[应用方案] 单片机跑马灯

[复制链接]
1228|2
 楼主| capturesthe 发表于 2016-4-21 22:29 | 显示全部楼层 |阅读模式
我用的板子是一个电机驱动版,上面有四个LED,接在P1.0,P1.1,P1.2,P1.3脚上,拉低就点亮。
用定时器1ms触发一次,1000次就是1秒,每个灯亮一秒,形成跑马灯。
  1. /*----------------------------------------------------
  2.         名称:用定时器控制led亮灭
  3.         单片机:stc12c2052
  4.         晶振:12M
  5.         说明:四个led,一个亮一秒,跑马灯。
  6. ------------------------------------------------------*/
  7. #include<reg52.h>                //头文件
  8. sbit LED1=P1^0;
  9. sbit LED2=P1^1;
  10. sbit LED3=P1^2;
  11. sbit LED4=P1^3;
  12. #define LED1_ON        {LED1 = 0;}
  13. #define LED2_ON        {LED2 = 0;}
  14. #define LED3_ON        {LED3 = 0;}
  15. #define LED4_ON        {LED4 = 0;}
  16. #define ALL_OFF {LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 1;}
  17. void Init_Timer0(void)        //初始化定时器0
  18. {
  19.         TMOD=0x01;                                //定时器0,使用模式1,16位定时器
  20.         TH0=(65536-1000)/256;        //给定初值
  21.         TL0=(65536-1000)%256;
  22.         EA=1;                //打开总中断
  23.         ET0=1;        //打开定时器中断
  24.         TR0=1;        //开定时器
  25. }
  26. void main()        //主函数
  27. {
  28.         Init_Timer0();
  29.         LED1 = 0;
  30.         while(1)
  31.         {
  32.         }
  33. }
  34. void Timer0_isr(void) interrupt 1
  35. {
  36.         static unsigned short int count = 0;
  37.         static char index = 0;
  38.         TH0=(65536-1000)/256;//重新赋值 1ms
  39.         TL0=(65536-1000)%256;
  40.         EA = 0;
  41.         ++count;
  42.         if(count == 1000)
  43.         {
  44.                 ++index;
  45.                 index &= 0x03;
  46.                 ALL_OFF;
  47.                 switch(index){
  48.                         case 0:
  49.                                 LED1_ON;
  50.                                 break;
  51.                         case 1:
  52.                                 LED2_ON;
  53.                                 break;
  54.                         case 2:
  55.                                 LED3_ON;
  56.                                 break;
  57.                         case 3:
  58.                                 LED4_ON;
  59.                                 break;
  60.                         default:
  61.                                 break;
  62.                 }
  63.                 count = 0;
  64.         }
  65.         EA = 1;
  66. }
  67. stc_01_1.c
  68. 觉得switch语句太丑了,想改成根据序号,点亮不同的灯,但点灯的变量是sbit ,C51不支持sbit数组。
  69. 想了想,把点灯动作写成函数,四个灯四个函数,函数指针数组,这个支持。

  70. /*----------------------------------------------------
  71.         名称:用定时器控制led亮灭
  72.         单片机:stc12c2052
  73.         晶振:12M
  74.         说明:四个led,一个亮一秒,跑马灯。
  75. ------------------------------------------------------*/
  76. #include<reg52.h>                //头文件
  77. typedef void (*pFun)(void);
  78. sbit LED1=P1^0;
  79. sbit LED2=P1^1;
  80. sbit LED3=P1^2;
  81. sbit LED4=P1^3;

  82. #define LED1_ON        {LED1 = 0;}
  83. #define LED2_ON        {LED2 = 0;}
  84. #define LED3_ON        {LED3 = 0;}
  85. #define LED4_ON        {LED4 = 0;}
  86. #define ALL_OFF {LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 1;}

  87. void set_led1_on(void)
  88. {
  89.         LED1_ON;
  90. }
  91. void set_led2_on(void)
  92. {
  93.         LED2_ON;
  94. }
  95. void set_led3_on(void)
  96. {
  97.         LED3_ON;
  98. }
  99. void set_led4_on(void)
  100. {
  101.         LED4_ON;
  102. }

  103. const pFun led_on[4] = {set_led1_on,set_led2_on,set_led3_on,set_led4_on};
  104. //const void (*led_on[4])(void) = {set_led1_on,set_led2_on,set_led3_on,set_led4_on};

  105. void Init_Timer0(void)        //初始化定时器0
  106. {
  107.         TMOD=0x01;                                //定时器0,使用模式1,16位定时器
  108.         TH0=(65536-1000)/256;        //给定初值
  109.         TL0=(65536-1000)%256;
  110.         EA=1;                //打开总中断
  111.         ET0=1;        //打开定时器中断
  112.         TR0=1;        //开定时器
  113. }

  114. void main()        //主函数
  115. {
  116.         Init_Timer0();//初始化定时器0
  117.         LED1 = 0;                //开第一个灯
  118.         while(1)
  119.         {
  120.         }
  121. }

  122. //定时器中断函数,1ms 定时。
  123. void Timer0_isr(void) interrupt 1
  124. {
  125.         static unsigned short int count = 0;
  126.         static char index = 0;
  127.         TH0=(65536-1000)/256;//重新赋值 1ms
  128.         TL0=(65536-1000)%256;
  129.         EA = 0;
  130.         ++count;
  131.         if(count == 1000)        //到 1 秒了
  132.         {
  133.                 ++index;                //点灯序号
  134.                 index &= 0x03;        //四个灯,序号0~3
  135.                 ALL_OFF;                //全关灯
  136.                 (*led_on[index])();                //打开序号对应灯
  137.                 count = 0;                                // 1秒计数开始。1s = 1000ms。
  138.         }
  139.         EA = 1;
  140. }
  141. stc_01_2.c
  142. 后来想到虽然sbit数组不支持,但是我可以不单个控制灯,而是四个灯一起控制,P1口可以用char赋值,char数组是支持的,改成下面这样:
  143. /*----------------------------------------------------
  144.         名称:用定时器控制led亮灭
  145.         单片机:stc12c2052
  146.         晶振:12M
  147.         说明:四个led,一个亮一秒,跑马灯。
  148. ------------------------------------------------------*/
  149. #include<reg52.h>                //头文件
  150. typedef void (*pFun)(void);
  151. const unsigned char led_port[4] = {0xFE,0xFD,0xFB,0xF7};
  152. void Init_Timer0(void)        //初始化定时器0
  153. {
  154.         TMOD=0x01;                                //定时器0,使用模式1,16位定时器
  155.         TH0=(65536-1000)/256;        //给定初值
  156.         TL0=(65536-1000)%256;
  157.         EA=1;                //打开总中断
  158.         ET0=1;        //打开定时器中断
  159.         TR0=1;        //开定时器
  160. }
  161. void main()        //主函数
  162. {
  163.         Init_Timer0();//初始化定时器0
  164.         P1 = 0xFE;                //开第一个灯
  165.         while(1)
  166.         {
  167.         }
  168. }
  169. //定时器中断函数,1ms 定时。
  170. void Timer0_isr(void) interrupt 1
  171. {
  172.         static unsigned short int count = 0;
  173.         static char index = 0;
  174.         TH0=(65536-1000)/256;//重新赋值 1ms
  175.         TL0=(65536-1000)%256;
  176.         EA = 0;
  177.         ++count;
  178.         if(count == 1000)        //到 1 秒了
  179.         {
  180.                 ++index;                //点灯序号
  181.                 index &= 0x03;        //四个灯,序号0~3
  182.                 P1 = led_port[index];
  183.                 count = 0;                                // 1秒计数开始。1s = 1000ms。
  184.         }
  185.         EA = 1;
  186. }


xuanhuanzi 发表于 2018-8-15 12:37 | 显示全部楼层
多谢分享
zhuotuzi 发表于 2018-8-15 20:55 | 显示全部楼层
这个用法新奇。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

136

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部