数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 467|回复: 3

[C51] 小白学习单片机之跑马灯三境界

[复制链接]
发表于 2025-1-24 13:51:08 | 显示全部楼层 |阅读模式
道可道,非常道。名可名,非常名。无名,天地之始。有名,万物之母。
故常无,欲以观其妙。常有,欲以观其徼。此两者同出而异名。
同谓之玄,玄之又玄,众妙之门。——《道德经》第一章

点个灯也能点出三境界,是万万没有想到的。
第一境界:看山是山——移位阻塞式点灯

  1. #include "REG52.H"

  2. void T0_time();
  3. void SystemInitial(void) ;
  4. void Delay(unsigned long u32DelayTime) ;
  5. void PeripheralInitial(void) ;
  6. void LedTask(void);

  7. void main()
  8. {
  9.         SystemInitial();
  10.         Delay(10000);
  11.         PeripheralInitial();
  12.         while(1){
  13.                 LedTask();
  14.         }
  15. }
  16. void T0_time() interrupt 1
  17. {
  18.         TH0=0xfc;
  19.         TL0=0x66;
  20. }
  21. void SystemInitial(void)
  22. {
  23.         TMOD=0x01;
  24.         TH0=0xfc;
  25.         TL0=0x66;
  26.         EA=1;
  27.         ET0=1;
  28.         TR0=1;
  29. }
  30. void Delay(unsigned long u32DelayTime)
  31. {
  32.         for(;u32DelayTime>0;u32DelayTime--);
  33. }
  34. void PeripheralInitial(void)
  35. {
  36. }
  37. //????????
  38. void LedTask(void)
  39. {
  40.         static unsigned char Su8Data=0x01; //? static ???????,?????????????
  41.         static unsigned char Su8Cnt=0; //? static ???????,?????????????
  42.         P0=Su8Data; //Su8Data ? 8 ???? 8 ? LED ???,0 ???,1 ????
  43.         Delay(10000) ; //????
  44.         Su8Data=Su8Data<<1; //????
  45.         Su8Cnt++; //????? 1
  46.         if(Su8Cnt>=8){
  47.                 Su8Cnt=0;
  48.                 Su8Data=0x01; //?????,?????????
  49. }
  50. }
复制代码


第二境界:看山不是山——移位非阻塞式点灯

  1. #include "REG52.H"
  2. #define BLINK_TIME_1 1000

  3. void T0_time();
  4. void SystemInitial(void) ;
  5. void Delay(unsigned long u32DelayTime) ;
  6. void PeripheralInitial(void) ;
  7. void LedTask(void);

  8. volatile unsigned char vGu8TimeFlag_1=0;
  9. volatile unsigned int vGu16TimeCnt_1=0;

  10. void main()
  11. {
  12.         SystemInitial();
  13.         Delay(10000);
  14.         PeripheralInitial();
  15.         while(1){
  16.                 LedTask();
  17.         }
  18. }
  19. void T0_time() interrupt 1
  20. {
  21.         if(1==vGu8TimeFlag_1&&vGu16TimeCnt_1>0) {//软件定时器
  22.                 vGu16TimeCnt_1--;
  23.         }
  24.         TH0=0xfc;
  25.         TL0=0x66;
  26. }
  27. void SystemInitial(void)
  28. {
  29.         TMOD=0x01;
  30.         TH0=0xfc;
  31.         TL0=0x66;
  32.         EA=1;
  33.         ET0=1;
  34.         TR0=1;
  35. }
  36. void Delay(unsigned long u32DelayTime)
  37. {
  38.         for(;u32DelayTime>0;u32DelayTime--);
  39. }
  40. void PeripheralInitial(void)
  41. {
  42. }
  43. //跑马灯的任务程序
  44. void LedTask(void)
  45. {
  46.         static unsigned char Su8Data=0x01; //加 static 修饰的局部变量,每次进来都会保留上一次值。
  47.         static unsigned char Su8Cnt=0; //加 static 修饰的局部变量,每次进来都会保留上一次值。
  48.         if(0==vGu16TimeCnt_1) {//时间到       
  49.                 vGu8TimeFlag_1=0;
  50.                 vGu16TimeCnt_1=BLINK_TIME_1; //重装定时的时间
  51.                 vGu8TimeFlag_1=1;
  52.                 P0=Su8Data; //Su8Data 的 8 个位代表 8 个 LED 的状态,0 为点亮,1 为熄灭。
  53.                 Su8Data=Su8Data<<1; //左移一位
  54.                 Su8Cnt++; //计数器累加 1
  55.                 if(Su8Cnt>=8) {//移位大于等于 8 次后,重新赋初值               
  56.                         Su8Cnt=0;
  57.                         Su8Data=0x01; //重新赋初值,继续下一次循环移动
  58.                 }
  59.         }
  60. }
复制代码



第三境界:看山还是山——状态切换非阻塞式点灯

  1. #include "REG52.H"
  2. #define BLINK_TIME_1 1000

  3. void T0_time();
  4. void SystemInitial(void) ;
  5. void Delay(unsigned long u32DelayTime) ;
  6. void PeripheralInitial(void) ;
  7. void LedTask(void);

  8. sbit P0_0=P0^0;
  9. sbit P0_1=P0^1;
  10. sbit P0_2=P0^2;
  11. sbit P0_3=P0^3;
  12. sbit P0_4=P0^4;
  13. sbit P0_5=P0^5;
  14. sbit P0_6=P0^6;
  15. sbit P0_7=P0^7;

  16. volatile unsigned char vGu8TimeFlag_1=0;
  17. volatile unsigned int vGu16TimeCnt_1=0;

  18. void main()
  19. {
  20.         SystemInitial();
  21.         Delay(10000);
  22.         PeripheralInitial();
  23.         while(1){
  24.                 LedTask();
  25.         }
  26. }
  27. void T0_time() interrupt 1
  28. {
  29.         if(1==vGu8TimeFlag_1&&vGu16TimeCnt_1>0) {
  30.                 vGu16TimeCnt_1--;
  31.         }
  32.         TH0=0xfc;
  33.         TL0=0x66;
  34. }

  35. void SystemInitial(void)
  36. {
  37.         TMOD=0x01;
  38.         TH0=0xfc;
  39.         TL0=0x66;
  40.         EA=1;
  41.         ET0=1;
  42.         TR0=1;
  43. }
  44. void Delay(unsigned long u32DelayTime)
  45. {
  46.         for(;u32DelayTime>0;u32DelayTime--);
  47. }
  48. void PeripheralInitial(void)
  49. {
  50. }
  51. //????????
  52. void LedTask(void)
  53. {
  54. static unsigned char Su8Step=0; //? static ???????,?????????????
  55. switch(Su8Step)
  56. {
  57.         case 0:
  58.                 if(0==vGu16TimeCnt_1){
  59.                         vGu8TimeFlag_1=0;
  60.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  61.                         vGu8TimeFlag_1=1;
  62.                         P0_0=1; //? 0 ????
  63.                         P0_1=0;
  64.                         P0_2=0;
  65.                         P0_3=0;
  66.                         P0_4=0;
  67.                         P0_5=0;
  68.                         P0_6=0;
  69.                         P0_7=0;
  70.                         Su8Step=1; //??
  71.                 }
  72.                 break;
  73.         case 1:
  74.                 if(0==vGu16TimeCnt_1){
  75.                         vGu8TimeFlag_1=0;
  76.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  77.                         vGu8TimeFlag_1=1;
  78.                         P0_0=0;
  79.                         P0_1=1; //? 1 ????
  80.                         P0_2=0;
  81.                         P0_3=0;
  82.                         P0_4=0;
  83.                         P0_5=0;
  84.                         P0_6=0;
  85.                         P0_7=0;
  86.                         Su8Step=2; //????????,????!
  87.                 }
  88.                 break;
  89.         case 2:
  90.                 if(0==vGu16TimeCnt_1) {
  91.                         vGu8TimeFlag_1=0;
  92.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  93.                         vGu8TimeFlag_1=1;
  94.                         P0_0=0;
  95.                         P0_1=0;
  96.                         P0_2=1; //? 2 ????
  97.                         P0_3=0;
  98.                         P0_4=0;
  99.                         P0_5=0;
  100.                         P0_6=0;
  101.                         P0_7=0;
  102.                         Su8Step=3; //????????,????!
  103.                 }
  104.                 break;
  105.         case 3:
  106.                 if(0==vGu16TimeCnt_1){
  107.                         vGu8TimeFlag_1=0;
  108.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  109.                         vGu8TimeFlag_1=1;
  110.                         P0_0=0;
  111.                         P0_1=0;
  112.                         P0_2=0;
  113.                         P0_3=1; //? 3 ????
  114.                         P0_4=0;
  115.                         P0_5=0;
  116.                         P0_6=0;
  117.                         P0_7=0;
  118.                         Su8Step=4; //??
  119.                 }
  120.                 break;
  121.         case 4:
  122.                 if(0==vGu16TimeCnt_1){
  123.                         vGu8TimeFlag_1=0;
  124.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  125.                         vGu8TimeFlag_1=1;
  126.                         P0_0=0;
  127.                         P0_1=0;
  128.                         P0_2=0;
  129.                         P0_3=0;
  130.                         P0_4=1; //? 4 ????
  131.                         P0_5=0;
  132.                         P0_6=0;
  133.                         P0_7=0;
  134.                         Su8Step=5; //????????,????!
  135.                 }
  136.                 break;
  137.         case 5:
  138.                 if(0==vGu16TimeCnt_1){
  139.                         vGu8TimeFlag_1=0;
  140.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  141.                         vGu8TimeFlag_1=1;
  142.                         P0_0=0;
  143.                         P0_1=0;
  144.                         P0_2=0;
  145.                         P0_3=0;
  146.                         P0_4=0;
  147.                         P0_5=1; //? 5 ????
  148.                         P0_6=0;
  149.                         P0_7=0;
  150.                         Su8Step=6; //????????,????!
  151.                 }
  152.                 break;
  153.         case 6:
  154.                 if(0==vGu16TimeCnt_1){
  155.                         vGu8TimeFlag_1=0;
  156.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  157.                         vGu8TimeFlag_1=1;
  158.                         P0_0=0;
  159.                         P0_1=0;
  160.                         P0_2=0;
  161.                         P0_3=0;
  162.                         P0_4=0;
  163.                         P0_5=0;
  164.                         P0_6=1; //? 6 ????
  165.                         P0_7=0;
  166.                         Su8Step=7; //????????,????!
  167.                 }
  168.                 break;
  169.         case 7:
  170.                 if(0==vGu16TimeCnt_1){
  171.                         vGu8TimeFlag_1=0;
  172.                         vGu16TimeCnt_1=BLINK_TIME_1; //???????
  173.                         vGu8TimeFlag_1=1;
  174.                         P0_0=0;
  175.                         P0_1=0;
  176.                         P0_2=0;
  177.                         P0_3=0;
  178.                         P0_4=0;
  179.                         P0_5=0;
  180.                         P0_6=0;
  181.                         P0_7=1; //? 7 ????
  182.                         Su8Step=0; //???? 0 ??????????,????!
  183.                 }
  184.                 break;
  185.         }
  186. }
复制代码
总结陈词:



作者在C51里面谈阻塞、锁也是我万万没想到的。
C++、C#里面面对多核CPU、超线程技术确实有线程阻塞、加锁的概念,
单片机里我觉得叫“调度”更合理吧,定时器中断和主循环互不影响,
实现这种“合理调度”的水平——谓之境界。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 1家元 +30 收起 理由
家睦 + 30

查看全部打赏

发表于 2025-1-24 23:26:38 | 显示全部楼层
【跑马灯】好像是从台湾图书中引入的,早期台湾出的图书,都这么叫。
回复 支持 反对

使用道具 举报

发表于 2025-1-24 15:40:39 | 显示全部楼层
点灯是最早也是最经典的代码操作,就算现在调试偶尔也会用点灯来确认状态.
回复 支持 反对

使用道具 举报

发表于 2025-1-24 14:58:02 来自手机浏览器 | 显示全部楼层
点灯挺有意思的,无论什么处理器。
我学arm也是点灯开始
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-22 06:19 , Processed in 0.218401 second(s), 17 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表