1、点亮闪烁的LED灯。
#include
sbit LED00=P0^0; //位定义,定义单片机引脚
void delay(int t)
{
int i , j ;
for(i = 0 ; i < 100*t ; i++)
{
for(j = 0 ; j < 125 ; j++)
{
;
}
}
}
void main(void)
{
while(1)
{
LED00 = 0 ; //此开发板是低电平点亮
delay(5) ;
LED00 = 1 ; //此开发板是高电平熄灭
delay(5) ;
}
}
2、流水灯。
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* P0、P1两个8位端口分别连接8个LED灯
* 低电平点亮,高电平熄灭。
******************************************************************************/
#include
#include
//是循环左移、右移函数的头文件,参考网址如下 //http://baike.baidu.com/view/1745068.htm?fromTaglist
//http://wenku.baidu.com/view/06ba3d00b52acfc789ebc97b.html
//sbit LED00=P0^0; //位定义,定义单片机引脚
void delay(int t)
{
int i , j ;
for(i = 0 ; i < 100*t ; i++)
{
for(j = 0 ; j < 125 ; j++)
{
;
}
}
}
void main(void)
{
P0 = 0xfe ; //0b11111110
P1 = 0x7f ; //0b01111111
while(1)
{
P0 = _crol_(P0 , 1); //循环左移,每次循环1位
P1 = _cror_(P1 , 1); //循环右移,每次循环1位
delay(5) ;
}
}
3、继电器的控制。
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板继电器的控制端口和单片机的P3^7引脚相连接
* 因为继电器的工作电流比较大,
* 所以P3^7连接的是一个三极管,通过三极管驱动继电器
******************************************************************************/
#include
sbit JDQ = P3^7 ; //位定义,定义单片机引脚
void delay(int t)
{
int i , j ;
for(i = 0 ; i < 100*t ; i++)
{
for(j = 0 ; j < 125 ; j++)
{
;
}
}
}
void main(void)
{
while(1)
{
JDQ = 0 ;
delay(5) ; //延时0.5s
JDQ = 1 ;
delay(5) ;
}
}
4、控制无源蜂鸣器每隔1s响1s (有一个疑问)
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板蜂鸣器的控制端口和单片机的P3^6引脚相连接
* 用三极管进行驱动
* 无源蜂鸣器:需要写函数产生1KHz左右的声音频率(方波)
******************************************************************************/
#include
sbit FMQ = P3^6 ; //位定义,定义单片机引脚
/******************************************************************************
* 名称:delay1ms()
* 功能:延时1ms
* 参数:int t
* 返回:无
******************************************************************************/
void delay1ms(int t)
{
unsigned char i ;
while(t--)
{
for(i = 0 ; i < 125 ; i++)
{
;
}
}
}
/******************************************************************************
* 名称:delay500us()
* 功能:延时500us
* 参数:无
* 返回:无
******************************************************************************/
void delay500us(void)
{
int i ;
for(i = 0 ; i < 63 ; i++)
{
;
}
}
/******************************************************************************
* 名称:beep_sound()
* 功能:产生FMQ发声需要的1KHz的声音频率
* 参数:无
* 返回:无
******************************************************************************/
void beep_sound(void)
{
FMQ = 0 ;
delay500us();
FMQ = 1 ;
delay500us();
}
void main(void)
{
int i , t;
while(1)
{
t = 1000 ; //蜂鸣器发声1000*1ms 1KHz频率的方波,一个周期是1ms
for(i = 0 ; i < t/3 ; i++) //for( ; ; )循环自身每循环一次占用3个指令周期
{
beep_sound();
}
FMQ = 1 ; //关掉FMQ 1s(延时)
delay1ms(1000) ;
}
}
注意:尽量使用定时器产生标准频率的方波,或用延时函数产生时,函数最好不要通过参数来改变延时效果。
疑问:把500us延时函数改成可以传参数t的形式,结果蜂鸣器发出的声音频率和发声的时长变得面目全非,很无解。有经验的朋友欢迎通过评论的方式讨论一下。
改过后的delay500ms()函数 和 beep_sound()函数内容如下:
/******************************************************************************
* 名称:delay500us()
* 功能:延时500us
* 参数:int t
* 返回:无
******************************************************************************/
void delay500us(int t)
{
int i ;
for(i = 0 ; i < 63*t ; i++)
{
;
}
}
/******************************************************************************
* 名称:beep_sound()
* 功能:产生FMQ发声需要的1KHz的声音频率
* 参数:无
* 返回:无
******************************************************************************/
void beep_sound(void)
{
FMQ = 0 ;
delay500us(1);
FMQ = 1 ;
delay500us(1);
}
5、点亮一位数码管,循环显示 0---F
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
* 数码管共阳
* 本程序:在一个数码管上显示0-F
******************************************************************************/
#include
sbit SMG_1 = P2^7 ; //位定义,定义单片机引脚
unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错
/******************************************************************************
* 名称:delay1ms()
* 功能:延时1ms
* 参数:int t
* 返回:无
******************************************************************************/
void delay1ms(int t)
{
unsigned char i ;
SMG_1 = 0 ;
while(t--)
{
for(i = 0 ; i < 125 ; i++)
{
;
}
}
}
void main(void)
{
int i ;
while(1)
{
for(i = 0 ; i < 16 ; i++)
{
P0 = S8[i] ;
delay1ms(500);
}
}
}
6、在8位数码管上流水式循环显示0---F
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
* 数码管共阳
* 本程序:在8位数码管上流水式循环显示0-F
******************************************************************************/
#include
#include
#define SMG_NUM P2
unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错
/******************************************************************************
* 名称:delay1ms()
* 功能:延时1ms
* 参数:int t
* 返回:无
******************************************************************************/
void delay1ms(int t)
{
unsigned char i ;
while(t--)
{
for(i = 0 ; i < 125 ; i++)
{
;
}
}
}
void main(void)
{
int i ;
SMG_NUM = 0xfe ;
while(1)
{
for(i = 0 ; i < 16 ; i++)
{
P0 = S8[i] ;
delay1ms(500);
SMG_NUM = _crol_(SMG_NUM , 1);
}
}
}
7、独立按键。按键使数码管上的数据增加。
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
* 数码管共阳
* 本程序:独立按键,按键使数码管上的数字循环增加
******************************************************************************/
#include
#include
sbit SMG = P2^0 ; //要选通的数码管
sbit K5 = P1^4 ; //独立按键对应的单片机输入引脚
unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错
/******************************************************************************
* 名称:delay1ms()
* 功能:延时1ms
* 参数:int t
* 返回:无
******************************************************************************/
void delay1ms(int t)
{
unsigned char i ;
while(t--)
{
for(i = 0 ; i < 125 ; i++)
{
;
}
}
}
void main(void)
{
int num = 0 ;
SMG = 0 ; //选通数码管
P0 = S8[num]; //数码管初始显示0
while(1)
{
//1、判断K5键是否按下,按下,软件消抖
if(K5 == 0)
{
delay1ms(15); //软件消抖,延时大约15ms
if(K5 == 0)
{ //2、有键按下,数码管显示的数字+1
P0 = S8[++num];
//3、判断按键是否松开
while(!K5)
{ ; }
}
}
//4、数码管循环显示0--F
if(num == 15)
{
num = 0 ;
}
}
}
8、矩阵键盘,逐行扫描法获取键值。
注意:AT89S52单片机,要进行读端口时,必须在读端口之前给端口写1(其实是写入到内部的锁存器中)
http://wenwen.soso.com/z/q184033008.htm
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
* 数码管共阳
* 本程序:矩阵键盘,逐行扫描获取键值
******************************************************************************/
#include
#include
sbit SMG = P2^0 ; //要选通的数码管
sbit K5 = P1^4 ; //独立按键对应的单片机输入引脚
unsigned char code S8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错
/******************************************************************************
* 名称:delay1ms()
* 功能:延时1ms
* 参数:int t
* 返回:无
******************************************************************************/
void delay1ms(int t)
{
unsigned char i ;
while(t--)
{
for(i = 0 ; i < 125 ; i++)
{
;
}
}
}
/******************************************************************************
* 名称:display_num()
* 功能:根据参数num在数码管上显示0--F
* 参数:int num
* 返回:无
******************************************************************************/
void display_num(int num)
{
SMG = 0 ; //选通数码管
P0 = S8[num]; //数码管初始显示0
}
void main(void)
{
unsigned char temp ;
display_num(16) ; //显示 -
while(1)
{
P1 = 0xff ; //先向端口写1,使端口处于读的状态
//判断是否有键按下
P1 = 0xf0 ;
temp = P1 ;
if(temp != 0xf0)
{
delay1ms(15);
if(temp != 0xf0)
{
//有键按下,扫描方式判断键值,并通过数码管显示
/*-----------对你第一行扫描-----------------*/
P1 = 0xfe ; //写端口
temp = P1 ; //读端口
switch(temp)
{
case 0xee: display_num(0) ; break ;
case 0xde: display_num(1) ; break ;
case 0xbe: display_num(2) ; break ;
case 0x7e: display_num(3) ; break ;
}
/*-----------对你第二行扫描-----------------*/
P1 = 0xfd ; //写端口
temp = P1 ; //读端口
switch(temp)
{
case 0xed: display_num(4) ; break ;
case 0xdd: display_num(5) ; break ;
case 0xbd: display_num(6) ; break ;
case 0x7d: display_num(7) ; break ;
}
/*-----------对你第三行扫描-----------------*/
P1 = 0xfb ; //写端口
temp = P1 ; //读端口
switch(temp)
{
case 0xeb: display_num(8) ; break ;
case 0xdb: display_num(9) ; break ;
case 0xbb: display_num(10) ; break ;
case 0x7b: display_num(11) ; break ;
}
/*-----------对你第四行扫描-----------------*/
P1 = 0xf7 ; //写端口
temp = P1 ; //读端口
switch(temp)
{
case 0xe7: display_num(12) ; break ;
case 0xd7: display_num(13) ; break ;
case 0xb7: display_num(14) ; break ;
case 0x77: display_num(15) ; break ;
}
}
}
}
}
9、矩阵键盘,线反转法扫描按键
/******************************************************************************
* 说明:AT89S52芯片,12M晶振
* 此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上
* 数码管共阳
* 本程序:矩阵键盘,线反转法扫描按键 , 数码管上显示按下了哪一个按键
******************************************************************************/
#include
#include
sbit SMG = P2^0 ; //要选通的数码管
sbit K5 = P1^4 ; //独立按键对应的单片机输入引脚
unsigned char code key_code[]={0xee,0xde,0xbe,0x7e,
0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};
unsigned char code S8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF};
//数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。
//这样就节省了芯片内部宝贵的RAM资源。
//但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错
/******************************************************************************
* 名称:delay1ms()
* 功能:延时1ms
* 参数:int t
* 返回:无
******************************************************************************/
void delay1ms(int t)
{
unsigned char i ;
while(t--)
{
for(i = 0 ; i < 125 ; i++)
{
;
}
}
}
/******************************************************************************
* 名称:display_num()
* 功能:根据参数num在数码管上显示0--F
* 参数:int num
* 返回:无
******************************************************************************/
void display_num(unsigned char num)
{
SMG = 0 ; //选通数码管
P0 = S8[num]; //数码管初始显示0
}
/******************************************************************************
* 名称:key_scan()
* 功能:线反转法扫描按键
* 参数:无
* 返回:key
******************************************************************************/
unsigned char key_scan(void)
{
unsigned char key_scan_line , key_scan_row , key_scan_temp ;
unsigned char i , key ;
//1、列扫描
P1 = 0Xf0 ;
key_scan_line = P1;
if(key_scan_line != 0xf0)
{
delay1ms(8);
if(key_scan_line != 0xf0)
{
delay1ms(8) ;
if(key_scan_line != 0xf0)
{
//2、翻转,行扫描
P1 = 0X0f ;
key_scan_row = P1 ;
if(key_scan_row != 0x0f)
{
//3、列、行扫描到键值后,将列与行的键值安位相或得到实际完整的键值
key_scan_temp = key_scan_line | key_scan_row ;
//4、释放按键,否则等待
while(P1 != 0xf0) //如果按键还没释放,读到的端口值和写入端口的值不同
{
P1 = 0xf0 ; //给端口写一个值
}
//5、通过键值 判断具体是键盘上的哪一个键按下 , 返回键值
for(i = 0 ; i < 16 ; i++)
{
if(key_scan_temp == key_code[i])
{
key = i ;
return(key) ;
}
}
}
}
}
}
else P1 = 0xff ;
return 16 ;
}
void main(void)
{
unsigned char key ;
//1、初始状态数码管显示 -
display_num(16) ;
//2、向端口写1,使端口处于读的状态
P1 = 0xff ;
while(1)
{
//3、判断是否有键按下,然后进入按键扫描函数,(大大降低了干扰)
P1 = 0xf0 ;
if( (P1&0xf0) != 0xf0 )
{
key = key_scan() ;
display_num(key) ;
}
//4、延时一段时间,按键是机械部件实现的,需要一定的反应时间
delay1ms(100) ;
}
}
上一篇:51单片机复习002
下一篇:51单片机复习001
推荐阅读最新更新时间:2024-03-16 15:37