第二十节:依次逐个亮灯并且每次只能亮一个灯的跑马灯程序。(下)

  1. void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01)  
  2. {  
  3.    unsigned char i;  
  4.    unsigned char ucTempData;  
  5.    hc595_sh_dr=0;  
  6.    hc595_st_dr=0;  
  7.   
  8.    ucTempData=ucLedStatusTemp16_09;  //先送高8位  
  9.    for(i=0;i<8;i++)  
  10.    {   
  11.          if(ucTempData>=0x80)hc595_ds_dr=1;  
  12.          else hc595_ds_dr=0;  
  13.   
  14.          hc595_sh_dr=0;     //SH引脚的上升沿把数据送入寄存器  
  15.          delay_short(15);   
  16.          hc595_sh_dr=1;  
  17.          delay_short(15);   
  18.   
  19.          ucTempData=ucTempData<<1;  
  20.    }  
  21.   
  22.    ucTempData=ucLedStatusTemp08_01;  //再先送低8位  
  23.    for(i=0;i<8;i++)  
  24.    {   
  25.          if(ucTempData>=0x80)hc595_ds_dr=1;  
  26.          else hc595_ds_dr=0;  
  27.   
  28.          hc595_sh_dr=0;     //SH引脚的上升沿把数据送入寄存器  
  29.          delay_short(15);   
  30.          hc595_sh_dr=1;  
  31.          delay_short(15);   
  32.   
  33.          ucTempData=ucTempData<<1;  
  34.    }  
  35.   
  36.    hc595_st_dr=0;  //ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来  
  37.    delay_short(15);   
  38.    hc595_st_dr=1;  
  39.    delay_short(15);   
  40.   
  41.    hc595_sh_dr=0;    //拉低,抗干扰就增强  
  42.    hc595_st_dr=0;  
  43.    hc595_ds_dr=0;  
  44.   
  45. }  
  46.   
  47. /* 注释一: 
  48. * 以下程序,看似简单而且重复,其实蕴含着鸿哥的大智慧。 
  49. * 它是基于鸿哥的switch状态机思想,领略到了它的简单和精髓, 
  50. * 以后任何所谓复杂的工程项目,都不再复杂。 
  51. */  
  52. void led_flicker_09_16() //第9个至第16个LED的跑马灯程序,逐个亮并且每次只能亮一个.  
  53. {  
  54.   switch(ucLedStep_09_16)  
  55.   {  
  56.      case 0:  
  57.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  58.            {  
  59.                uiTimeCnt_09_16=0; //时间计数器清零  
  60.   
  61.                ucLed_dr16=0;  //第16个灭  
  62.                ucLed_dr9=1;  //第9个亮  
  63.   
  64.                ucLed_update=1;  //更新显示  
  65.                ucLedStep_09_16=1; //切换到下一个步骤  
  66.            }  
  67.            break;  
  68.      case 1:  
  69.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  70.            {  
  71.                uiTimeCnt_09_16=0; //时间计数器清零  
  72.   
  73.                ucLed_dr9=0;  //第9个灭  
  74.                ucLed_dr10=1;  //第10个亮  
  75.   
  76.                ucLed_update=1;  //更新显示  
  77.                ucLedStep_09_16=2; //切换到下一个步骤  
  78.            }  
  79.            break;  
  80.      case 2:  
  81.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  82.            {  
  83.                uiTimeCnt_09_16=0; //时间计数器清零  
  84.   
  85.                ucLed_dr10=0;  //第10个灭  
  86.                ucLed_dr11=1;  //第11个亮  
  87.   
  88.                ucLed_update=1;  //更新显示  
  89.                ucLedStep_09_16=3; //切换到下一个步骤  
  90.            }  
  91.            break;  
  92.      case 3:  
  93.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  94.            {  
  95.                uiTimeCnt_09_16=0; //时间计数器清零  
  96.   
  97.                ucLed_dr11=0;  //第11个灭  
  98.                ucLed_dr12=1;  //第12个亮  
  99.   
  100.                ucLed_update=1;  //更新显示  
  101.                ucLedStep_09_16=4; //切换到下一个步骤  
  102.            }  
  103.            break;  
  104.      case 4:  
  105.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  106.            {  
  107.                uiTimeCnt_09_16=0; //时间计数器清零  
  108.   
  109.                ucLed_dr12=0;  //第12个灭  
  110.                ucLed_dr13=1;  //第13个亮  
  111.   
  112.                ucLed_update=1;  //更新显示  
  113.                ucLedStep_09_16=5; //切换到下一个步骤  
  114.            }  
  115.            break;  
  116.      case 5:  
  117.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  118.            {  
  119.                uiTimeCnt_09_16=0; //时间计数器清零  
  120.   
  121.                ucLed_dr13=0;  //第13个灭  
  122.                ucLed_dr14=1;  //第14个亮  
  123.   
  124.                ucLed_update=1;  //更新显示  
  125.                ucLedStep_09_16=6; //切换到下一个步骤  
  126.            }  
  127.            break;  
  128.      case 6:  
  129.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  130.            {  
  131.                uiTimeCnt_09_16=0; //时间计数器清零  
  132.   
  133.                ucLed_dr14=0;  //第14个灭  
  134.                ucLed_dr15=1;  //第15个亮  
  135.   
  136.                ucLed_update=1;  //更新显示  
  137.                ucLedStep_09_16=7; //切换到下一个步骤  
  138.            }  
  139.            break;  
  140.      case 7:  
  141.            if(uiTimeCnt_09_16>=const_time_level_09_16) //时间到  
  142.            {  
  143.                uiTimeCnt_09_16=0; //时间计数器清零  
  144.   
  145.                ucLed_dr15=0;  //第15个灭  
  146.                ucLed_dr16=1;  //第16个亮  
  147.   
  148.                ucLed_update=1;  //更新显示  
  149.                ucLedStep_09_16=0; //返回到开始处,重新开始新的一次循环  
  150.            }  
  151.            break;  
  152.       
  153.    }  
  154.   
  155. }  
  156.   
  157.   
  158. void T0_time() interrupt 1  
  159. {  
  160.   TF0=0;  //清除中断标志  
  161.   TR0=0; //关中断  
  162.   
  163.   if(uiTimeCnt_09_16<0xffff)  //设定这个条件,防止uiTimeCnt超范围。  
  164.   {  
  165.       uiTimeCnt_09_16++;  //累加定时中断的次数,  
  166.   }  
  167.   
  168.   TH0=0xf8;   //重装初始值(65535-2000)=63535=0xf82f  
  169.   TL0=0x2f;  
  170.   TR0=1;  //开中断  
  171. }  
  172.   
  173. void delay_short(unsigned int uiDelayShort)   
  174. {  
  175.    unsigned int i;    
  176.    for(i=0;i<uiDelayShort;i++)  
  177.    {  
  178.      ;   //一个分号相当于执行一条空语句  
  179.    }  
  180. }  
  181.   
  182. void delay_long(unsigned int uiDelayLong)  
  183. {  
  184.    unsigned int i;  
  185.    unsigned int j;  
  186.    for(i=0;i<uiDelayLong;i++)  
  187.    {  
  188.       for(j=0;j<500;j++)  //内嵌循环的空指令数量  
  189.           {  
  190.              ; //一个分号相当于执行一条空语句  
  191.           }  
  192.    }  
  193. }  
  194.   
  195.   
  196. void initial_myself()  //第一区 初始化单片机  
  197. {  
  198.   
  199.   TMOD=0x01;  //设置定时器0为工作方式1  
  200.   
  201.   
  202.   TH0=0xf8;   //重装初始值(65535-2000)=63535=0xf82f  
  203.   TL0=0x2f;  
  204.   
  205.   
  206. }  
  207.   
  208. void initial_peripheral() //第二区 初始化外围  
  209. {  
  210.   EA=1;     //开总中断  
  211.   ET0=1;    //允许定时中断  
  212.   TR0=1;    //启动定时中断  
  213.   
  214. }   

总结陈词:
上一节和这一节讲了两种不同的跑马灯程序,如果要让这两种不同的跑马灯程序都能各自独立运行,就涉及到多任务并行处理的程序框架。没错,下一节就讲多任务并行处理这方面的知识,欲知详情,请听下回分解-----多任务并行处理两路跑马灯。

(上半部分http://www.eeskill.com/group/topic_scan/id/502

永不止步步 发表于11-20 15:20 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67417个|学分:363791个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号