#include <reg51.h>//头文件
#define uint unsigned int
#define uchar unsigned char
#define Delay_MAX 1200
#define Delay_MIN 400
#define Delay_STEP 200
sbit L1 = P1^0; sbit L2 = P1^1; sbit L3 = P1^2; sbit L4 = P1^3;
sbit L5 = P1^4; sbit L6 = P1^5; sbit L7 = P1^6; sbit L8 = P1^7;//位定义8个LED
sbit MODE1 = P3^0;sbit MODE2 = P3^1;//位定义按键位置
uchar code SEG_TABLE[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 段码(演示模式显示)

// ---------- 全局变量 ----------
uchar mode = 1;//当前模式1
uint delay_time = 400;// 流转间隔(ms),默认400
uint timer_ms = 0;//定时器累计秒数
bit is_running = 0;// 起运状态(1运行,0暂停)
bit is_setting = 1;//时间设置状态


// ---------- 定时器初始化 ----------
void Timer0_Init(void)
{
    TMOD = 0x01;          // 定时器0,模式1(16位定时器
    TH0 = (65536 - 1000)/256; 
    TL0 = (65536 - 1000)%256;// 1ms定时(11.0592MHz晶振)
    ET0 = 1;EA = 1;       // 中断正常运行
    TR0 = 1;              // 启动定时器
}


// ---------- 定时器0中断函数(一秒一次) ----------
void zhongduan(void) interrupt 1  // 消抖
    {
        static uchar timer_10ms = 0;
        static uchar keep_mode1 = 0;//长按时长
        uchar current_mode1;
        uchar current_mode2;
      TH0 =(65536-1000)/256;
      TL0 =(65536-1000)%256;//重装初值
    timer_ms++;//累计通用延时毫秒数
            if(++timer_10ms >= 10)//消抖(10ms一次)
        {
                timer_10ms = 0;//重置
                current_mode1 = MODE1;//读取按键电平
                current_mode2 = MODE2;
            
//----------------------    
            if(current_mode1 == 0)
        {
            if(++current_mode1 == 1)//按键消抖
            {
                current_mode1 = 0;
                is_running = ~is_running;
            }
//----------------------------
                keep_mode1++;
            if(keep_mode1 >= 20 && is_setting)
                {
                keep_mode1 = 0;
                is_setting = 0;//退出设置
                }
        }        
            else{
                current_mode1 = 0;//释放时重新计数
                keep_mode1 = 0;//释放时重置长按时长
        }
                
//-----------------------
        
            if(current_mode2 == 0)
        {
            if(++current_mode2 == 1)//消抖
        {
                current_mode2 = 0;
                
            if(is_setting)//时间设置状态下
        {
                 delay_time += Delay_STEP;
                if(delay_time > Delay_MAX)
                    delay_time = Delay_MIN;
}
            else{
                is_setting = 1;
         }
        }
     }
          
            else{
                current_mode2 = 0;
       }
      }
     }
    
    

//------------------------------
void Delay_ms(uint ms)
{
    timer_ms = 0;//重置计时
    while(timer_ms < ms);//等待达到目的延时
}

//----------------------------
    void Run_Mode(void) 
    {
        uchar j,n;
        switch(mode)
        {
            case 1://模式1
        
            n = 0x01;
            P2 = 0xbf;//第1位显示,指向模式
            P0 = SEG_TABLE[1];
            Delay_ms(delay_time);
            P2 = 0x7f;//第2位显示,指向彩灯位置
            for(j=0;j<=8;j++)
            { 
                if(is_setting == 0)//退出设置状态时生效
                {
                while(timer_ms < delay_time);//精准延时
                timer_ms = 0;
                }
                P0 = SEG_TABLE[j+1];
                P1 = ~n;                
                n = n<<1;
            }
            break;
        
            case 2://模式2
        
            n = 0x80;
            P2 = 0xbf;//第1位显示,指向模式
            P0 = SEG_TABLE[2];
            Delay_ms(delay_time);
            P2 = 0x7f;//第2位显示,指向彩灯位置
            for(j = 0;j<=8;j++)
            { if(is_setting == 0)
                {
                while(timer_ms < delay_time);//精准延时
                timer_ms = 0;
                }
                P0 = SEG_TABLE[8-j];
                P1 = ~n;
                n = n>>1;
            }
            break;
        
            case 3://模式3
        
            P2 = 0xbf;
            P0 = SEG_TABLE[3];//第1位显示,指向模式
            
            P1 = 0xe7;
            {
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }
          P1 = 0xdb;
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }
            P1 = 0xbd;
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }
            P1 = 0x7e;
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }
        
      break;
    
            case 4://模式4
        
            P2 = 0xbf;
            P0 = SEG_TABLE[4];//第1位显示,指向模式
            
            P1 = 0x7e;
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }
          P1 = 0xbd;
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }
            P1 = 0xdb;
            if(is_setting == 0)
            {
            while(timer_ms < delay_time);
            timer_ms = 0;
            }                
            P1 = 0xe7;
            while(timer_ms < delay_time);
            timer_ms = 0;
         break;
        }
        if(++mode > 4)//循环
            mode =1;
    }

            


//---------- 主函数 ---------
void main(void)//217行
{
    Timer0_Init();  // 初始化定时器
    while(1) 
    {
            
        if(is_running)
            {
                        P2 = 0xff;//上电默认数码管清屏
            Run_Mode(); // 运行模式逻辑
             }
            else
            {
                P2 = 0xff;
                P0 = SEG_TABLE[0]; 
            }
  }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐