zoukankan      html  css  js  c++  java
  • 依次逐个亮灯并且每次只能亮一个灯的跑马灯程序

    #include "REG52.H"
    #define const_time_level_01_08 200  //第1个至第8个LED跑马灯的速度延时时间
    void initial_myself();
    void initial_peripheral();
    void delay_short(unsigned int uiDelayShort);
    void delay_long(unsigned int uiDelayLong);
    void led_flicker_01_08(); //第1个至第8个LED跑马灯程序,逐个亮且每次只能亮一个
    void hc595_drive(unsigned char ucLedStatusTemp08_01);
    void led_updata(); //LED更新函数
    void T0_time(); //定时中断函数
    sbit hc595_sh_dr=P3^6;  //上升沿时,数据寄存器数据移位
    sbit hc595_st_dr=P3^5;  //上升沿时移位寄存器的数据进入数据寄存器,下降沿时数据不变。当移位结束后,会产生一个正脉冲,用于更新显示数据。 
    sbit hc595_ds_dr=P3^4;  //串行数据输入端,级联的话接上一级的Q7
    unsigned char ucLed_dr1=0; //代表8个灯的亮灭状态,0灭,1亮
    unsigned char ucLed_dr2=0;
    unsigned char ucLed_dr3=0;
    unsigned char ucLed_dr4=0;
    unsigned char ucLed_dr5=0;
    unsigned char ucLed_dr6=0;
    unsigned char ucLed_dr7=0;
    unsigned char ucLed_dr8=0;
    unsigned char ucLed_updata=0; //刷新变量。每次更改LED灯的状态都要更新一次
    unsigned char ucLedStep_01_08=0; //第1个至第8个LED跑马灯的步骤变量
    unsigned int uiTimeCnt_01_08=0;  //第1个至第8个LED跑马灯的统计定时中断次数的延时计数器
    unsigned char ucLedStatus08_01=0; //代表底层74HC595输出状态的中间变量
    void main()
    {
     initial_myself();
     delay_long(100);
     initial_peripheral();
     delay_long(100);
     while(1)
     {
      led_flicker_01_08(); //第1个至第8个LED跑马灯程序,逐个亮且每次只能亮一个
      led_updata(); //LED更新函数
     }
    }
    void led_updata() //LED更新函数
    {
     if(ucLed_updata==1)
     {
      ucLed_updata=0;  //及时清零,避免一直更新
      if(ucLed_dr1==1)
       ucLedStatus08_01=ucLedStatus08_01&0xfe;    //确保第1位为0  亮
      else
       ucLedStatus08_01=ucLedStatus08_01|0x01;  //确保第1位为1 灭
      
      if(ucLed_dr2==1)
       ucLedStatus08_01=ucLedStatus08_01&0xfd;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x02;  
      
      if(ucLed_dr3==1)
       ucLedStatus08_01=ucLedStatus08_01&0xfb;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x04;
      
      if(ucLed_dr4==1)
       ucLedStatus08_01=ucLedStatus08_01&0xf7;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x08;
      
      if(ucLed_dr5==1)
       ucLedStatus08_01=ucLedStatus08_01&0xef;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x10;
      
      if(ucLed_dr6==1)
       ucLedStatus08_01=ucLedStatus08_01&0xdf;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x20;
      
      if(ucLed_dr7==1)
       ucLedStatus08_01=ucLedStatus08_01&0xbf;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x40;
      
      if(ucLed_dr8==1)
       ucLedStatus08_01=ucLedStatus08_01&0x7f;    
      else
       ucLedStatus08_01=ucLedStatus08_01|0x80;
      
      hc595_drive(ucLedStatus08_01);  //74HC595底层驱动程序
     }
    }
    void hc595_drive(unsigned char ucLedStatusTemp08_01)//1-8位
    {
     unsigned char i;
     unsigned char ucTempData;
     hc595_sh_dr=0;
     hc595_st_dr=0;
     
     ucTempData=ucLedStatusTemp08_01; //送8位
     for(i=0;i<8;i++)
     {
      if(ucTempData>=0x80) //更新一次数据,移一次位
       hc595_ds_dr=1;//串行数据输入,如果是多片联级的话,更新一次,输入一次数据。(我的单片机只用了一个74HC595芯片)
      else
       hc595_ds_dr=0;
     
      hc595_sh_dr=0;
      delay_short(15);
      hc595_sh_dr=1;//SH引脚的上升沿把数据送入寄存器
      delay_short(15);
     
      ucTempData=ucTempData<<1;//左移一位
     }
     
     hc595_st_dr=0;
     delay_short(15);
     hc595_st_dr=1;  //ST引脚负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。上升沿时更新显示数据。
     delay_short(15);
     
     hc595_sh_dr=0; //拉低,抗干扰就增强
     hc595_st_dr=0;
     hc595_ds_dr=0;
    }
    /*switch状态机,进行程序切换*/
    void led_flicker_01_08() //第1个至第8个LED跑马灯程序,逐个亮,逐个灭
    {
     switch(ucLedStep_01_08)
     {
      case 0:
       if(uiTimeCnt_01_08>=const_time_level_01_08)  //时间到
       {
        uiTimeCnt_01_08=0;  //时间计数器清零
        ucLed_dr8=0;  //第8个灭
        ucLed_dr1=1;  //第1个灯亮
        ucLed_updata=1;  //更新显示
        ucLedStep_01_08=1; //切换到下一个步骤
       }
       break;
       
      case 1:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr1=0;  //第1个灭
        ucLed_dr2=1;  //第2个亮
        ucLed_updata=1;
        ucLedStep_01_08=2;
       }
       break;
       
      case 2:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr2=0;
        ucLed_dr3=1;
        ucLed_updata=1;
        ucLedStep_01_08=3;
       }
       break;
      case 3:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr3=0;
        ucLed_dr4=1;
        ucLed_updata=1;
        ucLedStep_01_08=4;
       }
       break;
      case 4:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr4=0;
        ucLed_dr5=1;
        ucLed_updata=1;
        ucLedStep_01_08=5;
       }
       break;
      case 5:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr5=0;
        ucLed_dr6=1;
        ucLed_updata=1;
        ucLedStep_01_08=6;
       }
       break;
      case 6:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr6=0;
        ucLed_dr7=1;
        ucLed_updata=1;
        ucLedStep_01_08=7;
       }
       break;
      case 7:
       if(uiTimeCnt_01_08>=const_time_level_01_08)
       {
        uiTimeCnt_01_08=0;
        ucLed_dr7=0;
        ucLed_dr8=1;
        ucLed_updata=1;
        ucLedStep_01_08=0;
       }
       break; 
     }
    }
    void T0_time() interrupt 1
    {
     TF0=0; //清除中断标志
     TR0=0; //关中断
     
     if(uiTimeCnt_01_08<0xffff) //设定这个条件,防止uiTimeCnt超范围
      uiTimeCnt_01_08++;
      
     TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
     TL0=0x2f;
     TR0=1; //开中断 
    }
    void delay_short(unsigned int uiDelayShort)
    {
     unsigned int i;
     for(i=0;i<uiDelayShort;i++)
      ;
    }
    void delay_long(unsigned int uiDelayLong)
    {
     unsigned int i;
     unsigned int j;
     for(i=0;i<uiDelayLong;i++)
      for(j=0;j<500;j++)
       ;
    }
    void initial_myself() //第一区  初始化单片机
    {
     TMOD=0x01;  //设置定时器0工作方式为1
     TH0=0xf8;
     TL0=0x2f;
    }
    void initial_peripheral()
    {
     EA=1; //开总中断
     ET0=1; //允许定时中断
     TR0=1; //启动定时中断
    }
     
  • 相关阅读:
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 133 克隆图
  • 原文地址:https://www.cnblogs.com/TheFly/p/12047751.html
Copyright © 2011-2022 走看看