×
单片机 > 单片机程序设计 > 详情

51单片机复习程序例举001

发布时间:2020-08-31 发布时间:
|

1、点亮闪烁的LED灯。


  1. #include  

  2.   

  3. sbit LED00=P0^0;  //位定义,定义单片机引脚  

  4.   

  5.   

  6. void delay(int t)  

  7. {  

  8.     int i , j ;  

  9.     for(i = 0 ; i 

  10.     {  

  11.         for(j = 0 ; j 

  12.         {  

  13.             ;  

  14.         }  

  15.     }  

  16. }  

  17.   

  18. void main(void)  

  19. {  

  20.   while(1)  

  21.   {  

  22.     

  23.     LED00 = 0 ;  //此开发板是低电平点亮  

  24.     delay(5) ;  

  25.     LED00 = 1 ;  //此开发板是高电平熄灭  

  26.     delay(5) ;  

  27.   

  28.   }  

  29.   

  30.   

  31. }  



2、流水灯。


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  P0、P1两个8位端口分别连接8个LED灯 

  4.  *  低电平点亮,高电平熄灭。 

  5.  ******************************************************************************/  

  6.   

  7. #include  

  8. #include //是循环左移、右移函数的头文件,参考网址如下  

  9.     //http://baike.baidu.com/view/1745068.htm?fromTaglist  

  10.     //http://wenku.baidu.com/view/06ba3d00b52acfc789ebc97b.html  

  11.   

  12. //sbit LED00=P0^0;  //位定义,定义单片机引脚  

  13.   

  14.   

  15. void delay(int t)  

  16. {  

  17.     int i , j ;  

  18.     for(i = 0 ; i 

  19.     {  

  20.         for(j = 0 ; j 

  21.         {  

  22.             ;  

  23.         }  

  24.     }  

  25. }  

  26.   

  27. void main(void)  

  28. {  

  29.   

  30.     P0 = 0xfe ; //0b11111110   

  31.     P1 = 0x7f ; //0b01111111   

  32.   

  33.   while(1)  

  34.   {  

  35.     P0 = _crol_(P0 , 1);  //循环左移,每次循环1位  

  36.     P1 = _cror_(P1 , 1);  //循环右移,每次循环1位  

  37.     delay(5) ;  

  38.   

  39.   }  

  40.   

  41.   

  42. }  


3、继电器的控制。


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板继电器的控制端口和单片机的P3^7引脚相连接 

  4.  *  因为继电器的工作电流比较大, 

  5.  *  所以P3^7连接的是一个三极管,通过三极管驱动继电器 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9.   

  10. sbit JDQ = P3^7 ; //位定义,定义单片机引脚  

  11.   

  12. void delay(int t)  

  13. {  

  14.     int i , j ;  

  15.     for(i = 0 ; i 

  16.     {  

  17.         for(j = 0 ; j 

  18.         {  

  19.             ;  

  20.         }  

  21.     }  

  22. }  

  23.   

  24. void main(void)  

  25. {  

  26.   

  27.   while(1)  

  28.   {  

  29.     JDQ = 0 ;  

  30.     delay(5) ;  //延时0.5s  

  31.     JDQ = 1 ;  

  32.     delay(5) ;  

  33.   

  34.   }  

  35.   

  36.   

  37. }  

4、控制无源蜂鸣器每隔1s响1s (有一个疑问)


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板蜂鸣器的控制端口和单片机的P3^6引脚相连接 

  4.  *  用三极管进行驱动   

  5.  *  无源蜂鸣器:需要写函数产生1KHz左右的声音频率(方波) 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9.   

  10. sbit FMQ = P3^6 ; //位定义,定义单片机引脚  

  11.   

  12. /****************************************************************************** 

  13.  *  名称:delay1ms() 

  14.  *  功能:延时1ms 

  15.  *  参数:int t 

  16.  *  返回:无 

  17.  ******************************************************************************/  

  18. void delay1ms(int t)  

  19. {  

  20.     unsigned char i ;  

  21.     while(t--)  

  22.     {  

  23.         for(i = 0 ; i 

  24.         {  

  25.             ;  

  26.         }  

  27.     }  

  28. }  

  29.   

  30.   

  31. /****************************************************************************** 

  32.  *  名称:delay500us() 

  33.  *  功能:延时500us 

  34.  *  参数:无 

  35.  *  返回:无 

  36.  ******************************************************************************/  

  37. void delay500us(void)  

  38. {  

  39.     int i ;  

  40.   

  41.     for(i = 0 ; i 

  42.     {  

  43.         ;  

  44.     }  

  45.   

  46. }  

  47.   

  48. /****************************************************************************** 

  49.  *  名称:beep_sound() 

  50.  *  功能:产生FMQ发声需要的1KHz的声音频率 

  51.  *  参数:无 

  52.  *  返回:无 

  53.  ******************************************************************************/  

  54. void beep_sound(void)  

  55. {  

  56.     FMQ = 0 ;  

  57.     delay500us();  

  58.     FMQ = 1 ;  

  59.     delay500us();  

  60.   

  61. }  

  62.   

  63.   

  64. void main(void)  

  65. {  

  66.   int i , t;  

  67.   

  68.   while(1)  

  69.   {  

  70.   

  71.     t = 1000 ; //蜂鸣器发声1000*1ms 1KHz频率的方波,一个周期是1ms  

  72.     for(i = 0 ; i 

  73.     {  

  74.         beep_sound();     

  75.     }  

  76.   

  77.     FMQ = 1 ;  //关掉FMQ 1s(延时)   

  78.     delay1ms(1000) ;  

  79.   

  80.   }  

  81.   

  82.   

  83. }  

注意:尽量使用定时器产生标准频率的方波,或用延时函数产生时,函数最好不要通过参数来改变延时效果。

疑问:把500us延时函数改成可以传参数t的形式,结果蜂鸣器发出的声音频率和发声的时长变得面目全非,很无解。有经验的朋友欢迎通过评论的方式讨论一下。

改过后的delay500ms()函数 和 beep_sound()函数内容如下:


  1. /****************************************************************************** 

  2.  *  名称:delay500us() 

  3.  *  功能:延时500us 

  4.  *  参数:int t 

  5.  *  返回:无 

  6.  ******************************************************************************/  

  7. void delay500us(int t)  

  8. {  

  9.     int i ;  

  10.   

  11.     for(i = 0 ; i 

  12.     {  

  13.         ;  

  14.     }  

  15.   

  16. }  

  17.   

  18. /****************************************************************************** 

  19.  *  名称:beep_sound() 

  20.  *  功能:产生FMQ发声需要的1KHz的声音频率 

  21.  *  参数:无 

  22.  *  返回:无 

  23.  ******************************************************************************/  

  24. void beep_sound(void)  

  25. {  

  26.     FMQ = 0 ;  

  27.     delay500us(1);  

  28.     FMQ = 1 ;  

  29.     delay500us(1);  

  30.   

  31. }  


5、点亮一位数码管,循环显示 0---F


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上 

  4.  *  数码管共阳  

  5.  *  本程序:在一个数码管上显示0-F 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9.   

  10. sbit SMG_1 = P2^7 ; //位定义,定义单片机引脚  

  11.   

  12. unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};  

  13. //数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。  

  14. //这样就节省了芯片内部宝贵的RAM资源。  

  15. //但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错  

  16.   

  17. /****************************************************************************** 

  18.  *  名称:delay1ms() 

  19.  *  功能:延时1ms 

  20.  *  参数:int t 

  21.  *  返回:无 

  22.  ******************************************************************************/  

  23. void delay1ms(int t)  

  24. {  

  25.     unsigned char i ;  

  26.     SMG_1 = 0 ;  

  27.     while(t--)  

  28.     {  

  29.         for(i = 0 ; i 

  30.         {  

  31.             ;  

  32.         }  

  33.     }  

  34. }  

  35.   

  36.   

  37.   

  38. void main(void)  

  39. {  

  40.   int i ;  

  41.   

  42.   while(1)  

  43.   {  

  44.   

  45.     for(i = 0 ; i 

  46.     {  

  47.         P0 = S8[i] ;  

  48.         delay1ms(500);  

  49.     }  

  50.   

  51.   

  52.   }  

  53.   

  54.   

  55. }  

6、在8位数码管上流水式循环显示0---F


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上 

  4.  *  数码管共阳  

  5.  *  本程序:在8位数码管上流水式循环显示0-F 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9. #include  

  10. #define SMG_NUM P2  

  11.   

  12.   

  13. unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};  

  14. //数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。  

  15. //这样就节省了芯片内部宝贵的RAM资源。  

  16. //但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错  

  17.   

  18. /****************************************************************************** 

  19.  *  名称:delay1ms() 

  20.  *  功能:延时1ms 

  21.  *  参数:int t 

  22.  *  返回:无 

  23.  ******************************************************************************/  

  24. void delay1ms(int t)  

  25. {  

  26.     unsigned char i ;  

  27.   

  28.     while(t--)  

  29.     {  

  30.         for(i = 0 ; i 

  31.         {  

  32.             ;  

  33.         }  

  34.     }  

  35. }  

  36.   

  37.   

  38.   

  39. void main(void)  

  40. {  

  41.   int i ;  

  42.   SMG_NUM = 0xfe ;  

  43.   

  44.   while(1)  

  45.   {  

  46.   

  47.     for(i = 0 ; i 

  48.     {     

  49.         P0 = S8[i] ;  

  50.         delay1ms(500);  

  51.         SMG_NUM = _crol_(SMG_NUM , 1);  

  52.     }  

  53.   

  54.   

  55.   }  

  56.   

  57.   

  58. }  


7、独立按键。按键使数码管上的数据增加。


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上 

  4.  *  数码管共阳  

  5.  *  本程序:独立按键,按键使数码管上的数字循环增加 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9. #include  

  10.   

  11. sbit SMG = P2^0 ;   //要选通的数码管  

  12. sbit K5 = P1^4 ;    //独立按键对应的单片机输入引脚  

  13.   

  14.   

  15. unsigned char code S8[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};  

  16. //数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。  

  17. //这样就节省了芯片内部宝贵的RAM资源。  

  18. //但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错  

  19.   

  20. /****************************************************************************** 

  21.  *  名称:delay1ms() 

  22.  *  功能:延时1ms 

  23.  *  参数:int t 

  24.  *  返回:无 

  25.  ******************************************************************************/  

  26. void delay1ms(int t)  

  27. {  

  28.     unsigned char i ;  

  29.   

  30.     while(t--)  

  31.     {  

  32.         for(i = 0 ; i 

  33.         {  

  34.             ;  

  35.         }  

  36.     }  

  37. }  

  38.   

  39.   

  40. void main(void)  

  41. {  

  42.     int num = 0 ;  

  43.     SMG = 0 ;   //选通数码管  

  44.     P0 = S8[num]; //数码管初始显示0  

  45.     while(1)  

  46.     {    

  47.     //1、判断K5键是否按下,按下,软件消抖  

  48.         if(K5 == 0)  

  49.         {  

  50.             delay1ms(15);  //软件消抖,延时大约15ms  

  51.             if(K5 == 0)  

  52.             {   //2、有键按下,数码管显示的数字+1  

  53.                 P0 = S8[++num];  

  54.                 //3、判断按键是否松开  

  55.                 while(!K5)  

  56.                 { ; }  

  57.             }  

  58.         }  

  59.     //4、数码管循环显示0--F  

  60.         if(num == 15)  

  61.         {  

  62.             num = 0 ;  

  63.         }     

  64.     }  

  65.       

  66. }  

8、矩阵键盘,逐行扫描法获取键值。

注意:AT89S52单片机,要进行读端口时,必须在读端口之前给端口写1(其实是写入到内部的锁存器中)

http://wenwen.soso.com/z/q184033008.htm


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上 

  4.  *  数码管共阳  

  5.  *  本程序:矩阵键盘,逐行扫描获取键值 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9. #include  

  10.   

  11. sbit SMG = P2^0 ;   //要选通的数码管  

  12. sbit K5 = P1^4 ;    //独立按键对应的单片机输入引脚  

  13.   

  14.   

  15. unsigned char code S8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF};  

  16. //数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。  

  17. //这样就节省了芯片内部宝贵的RAM资源。  

  18. //但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错  

  19.   

  20. /****************************************************************************** 

  21.  *  名称:delay1ms() 

  22.  *  功能:延时1ms 

  23.  *  参数:int t 

  24.  *  返回:无 

  25.  ******************************************************************************/  

  26. void delay1ms(int t)  

  27. {  

  28.     unsigned char i ;  

  29.   

  30.     while(t--)  

  31.     {  

  32.         for(i = 0 ; i 

  33.         {  

  34.             ;  

  35.         }  

  36.     }  

  37. }  

  38.   

  39.   

  40. /****************************************************************************** 

  41.  *  名称:display_num() 

  42.  *  功能:根据参数num在数码管上显示0--F 

  43.  *  参数:int num 

  44.  *  返回:无 

  45.  ******************************************************************************/  

  46. void display_num(int num)  

  47. {  

  48.     SMG = 0 ;   //选通数码管  

  49.     P0 = S8[num]; //数码管初始显示0  

  50. }  

  51.   

  52. void main(void)  

  53. {  

  54.     unsigned char temp ;  

  55.     display_num(16) ; //显示 -   

  56.     while(1)  

  57.     {  

  58.         P1 = 0xff ; //先向端口写1,使端口处于读的状态  

  59.         //判断是否有键按下  

  60.         P1 = 0xf0 ;  

  61.         temp = P1 ;  

  62.         if(temp != 0xf0)  

  63.         {  

  64.             delay1ms(15);  

  65.             if(temp != 0xf0)  

  66.             {  

  67.             //有键按下,扫描方式判断键值,并通过数码管显示  

  68.             /*-----------对你第一行扫描-----------------*/   

  69.                 P1 = 0xfe ; //写端口  

  70.                 temp = P1 ; //读端口  

  71.                 switch(temp)  

  72.                 {  

  73.                     case 0xee: display_num(0) ; break ;  

  74.                     case 0xde: display_num(1) ; break ;  

  75.                     case 0xbe: display_num(2) ; break ;  

  76.                     case 0x7e: display_num(3) ; break ;  

  77.                 }  

  78.       

  79.             /*-----------对你第二行扫描-----------------*/   

  80.                 P1 = 0xfd ; //写端口  

  81.                 temp = P1 ; //读端口  

  82.                 switch(temp)  

  83.                 {  

  84.                     case 0xed: display_num(4) ; break ;  

  85.                     case 0xdd: display_num(5) ; break ;  

  86.                     case 0xbd: display_num(6) ; break ;  

  87.                     case 0x7d: display_num(7) ; break ;  

  88.                 }  

  89.       

  90.             /*-----------对你第三行扫描-----------------*/   

  91.                 P1 = 0xfb ; //写端口  

  92.                 temp = P1 ; //读端口  

  93.                 switch(temp)  

  94.                 {  

  95.                     case 0xeb: display_num(8) ; break ;  

  96.                     case 0xdb: display_num(9) ; break ;  

  97.                     case 0xbb: display_num(10) ; break ;  

  98.                     case 0x7b: display_num(11) ; break ;  

  99.                 }  

  100.       

  101.             /*-----------对你第四行扫描-----------------*/   

  102.                 P1 = 0xf7 ; //写端口  

  103.                 temp = P1 ; //读端口  

  104.                 switch(temp)  

  105.                 {  

  106.                     case 0xe7: display_num(12) ; break ;  

  107.                     case 0xd7: display_num(13) ; break ;  

  108.                     case 0xb7: display_num(14) ; break ;  

  109.                     case 0x77: display_num(15) ; break ;  

  110.                 }  

  111.               

  112.             }  

  113.         }  

  114.       

  115.   

  116.     }  

  117.       

  118. }  


9、矩阵键盘,线反转法扫描按键


  1. /****************************************************************************** 

  2.  *  说明:AT89S52芯片,12M晶振 

  3.  *  此开发板数码管的片选信号连接在P2口上,每个数码管的8位段选信号连接在P0端口上 

  4.  *  数码管共阳  

  5.  *  本程序:矩阵键盘,线反转法扫描按键 , 数码管上显示按下了哪一个按键 

  6.  ******************************************************************************/  

  7.   

  8. #include  

  9. #include  

  10.   

  11. sbit SMG = P2^0 ;   //要选通的数码管  

  12. sbit K5 = P1^4 ;    //独立按键对应的单片机输入引脚  

  13.   

  14. unsigned char code key_code[]={0xee,0xde,0xbe,0x7e,  

  15.                                0xed,0xdd,0xbd,0x7d,  

  16.                                0xeb,0xdb,0xbb,0x7b,    

  17.                                0xe7,0xd7,0xb7,0x77};  

  18. unsigned char code S8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF};  

  19. //数组名前加 code 作用:将静态数组S8[16]存到AT89S52外部的8K的ROM中,而不是内部的256字节的RAM中。  

  20. //这样就节省了芯片内部宝贵的RAM资源。  

  21. //但是动态的(在程序运行过程中要发生变化的)变量或数组不能存放在外部的ROM中,变量名前面加code程序会出错  

  22.   

  23. /****************************************************************************** 

  24.  *  名称:delay1ms() 

  25.  *  功能:延时1ms 

  26.  *  参数:int t 

  27.  *  返回:无 

  28.  ******************************************************************************/  

  29. void delay1ms(int t)  

  30. {  

  31.     unsigned char i ;  

  32.   

  33.     while(t--)  

  34.     {  

  35.         for(i = 0 ; i 

  36.         {  

  37.             ;  

  38.         }  

  39.     }  

  40. }  

  41.   

  42.   

  43. /****************************************************************************** 

  44.  *  名称:display_num() 

  45.  *  功能:根据参数num在数码管上显示0--F 

  46.  *  参数:int num 

  47.  *  返回:无 

  48.  ******************************************************************************/  

  49. void display_num(unsigned char num)  

  50. {  

  51.     SMG = 0 ;   //选通数码管  

  52.     P0 = S8[num]; //数码管初始显示0  

  53. }  

  54.   

  55. /****************************************************************************** 

  56.  *  名称:key_scan() 

  57.  *  功能:线反转法扫描按键 

  58.  *  参数:无 

  59.  *  返回:key 

  60.  ******************************************************************************/  

  61. unsigned char key_scan(void)  

  62. {  

  63.     unsigned char  key_scan_line , key_scan_row , key_scan_temp ;  

  64.     unsigned char i , key ;  

  65.     //1、列扫描  

  66.     P1 = 0Xf0 ;  

  67.     key_scan_line = P1;  

  68.     if(key_scan_line != 0xf0)  

  69.     {  

  70.         delay1ms(8);  

  71.         if(key_scan_line != 0xf0)  

  72.         {  

  73.             delay1ms(8) ;  

  74.             if(key_scan_line != 0xf0)  

  75.             {  

  76.             //2、翻转,行扫描  

  77.                 P1 = 0X0f ;  

  78.                 key_scan_row = P1 ;  

  79.                 if(key_scan_row != 0x0f)  

  80.                 {  

  81.           

  82.                 //3、列、行扫描到键值后,将列与行的键值安位相或得到实际完整的键值  

  83.                     key_scan_temp = key_scan_line | key_scan_row ;  

  84.   

  85.                 //4、释放按键,否则等待  

  86.                     while(P1 != 0xf0)  //如果按键还没释放,读到的端口值和写入端口的值不同  

  87.                     {  

  88.                         P1 = 0xf0 ;   //给端口写一个值  

  89.                     }  

  90.                       

  91.       

  92.                 //5、通过键值 判断具体是键盘上的哪一个键按下 , 返回键值  

  93.                     for(i = 0 ; i 

  94.                     {  

  95.                         if(key_scan_temp == key_code[i])  

  96.                         {  

  97.                             key = i ;  

  98.                             return(key) ;  

  99.                         }     

  100.                     }  

  101.       

  102.       

  103.                 }             

  104.             }  

  105.   

  106.         }  

  107.     }  

  108.     else P1 = 0xff ;  

  109.     return 16 ;  

  110.   

  111. }  

  112.   

  113.   

  114.   

  115.   

  116. void main(void)  

  117. {  

  118.     unsigned char key ;  

  119.     //1、初始状态数码管显示 -   

  120.     display_num(16) ;   

  121.   

  122.     //2、向端口写1,使端口处于读的状态  

  123.     P1 = 0xff ;   

  124.     while(1)  

  125.     {  

  126.     //3、判断是否有键按下,然后进入按键扫描函数,(大大降低了干扰)  

  127.         P1 = 0xf0 ;  

  128.         if( (P1&0xf0) != 0xf0 )  

  129.         {  

  130.             key = key_scan() ;  

  131.             display_num(key) ;                

  132.         }  

  133.     //4、延时一段时间,按键是机械部件实现的,需要一定的反应时间  

  134.         delay1ms(100) ;  

  135.   

  136.     }  

  137.       

  138. }  



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式