微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 数码管动态扫描-按键-流水灯(附仿真图)

数码管动态扫描-按键-流水灯(附仿真图)

时间:10-02 整理:3721RD 点击:
#include<reg52.h>
#define      uchar      unsigned char                                             //无符号char类型
#define      uint       unsigned int                                             //无符号int类型
/************************常用位抄作指令*****************************/
#define set_bit(x,y)              (x|=(1<<y))                                      //位置1
#define clr_bit(x,y)              (x&=~(1<<y))                                  //位清0
#define get_bit(x,y)            (x&(1<<y))                                      //位查询
#define    xor_bit(x,y)             (x^=(1<<y))                                      //位取反
#define    MAKEWORD(v1,v2)            (((uint)(v1)<<8) + (uint)(v2))                  //高低位字节组合为一个字v1高,v2低
#define    HIBYTE(v1)                ((uchar)((v1)>>8))                              //取高位字节
#define    LOBYTE(v1)                ((uchar)((v1)&0xff))                          //取低位字节
#define    nop()                    _nop_
/********************************************************************/
#define LongToBin(n) \
(                    \
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >>  9) & 0x08) | \
((n >>  6) & 0x04) | \
((n >>  3) & 0x02) | \
((n      ) & 0x01)   \
)
#define Bin(n) LongToBin(0x##n##l)                                            //write binary charactor set,exsample : Bin(11111111) = 0xff
//*******************************数码管com口定义**********************************//
#define display_location_1_set         set_bit(P3,0)//P3_3=1
#define display_location_1_clr         clr_bit(P3,0)//P3_3=0
#define display_location_2_set         set_bit(P3,1)//P3_2=1
#define display_location_2_clr         clr_bit(P3,1)//P3_2=0
#define display_location_3_set         set_bit(P3,2)//P3_1=1
#define display_location_3_clr         clr_bit(P3,2)//P3_1=0  
   
#define display_location_4_set         set_bit(P3,3)//P3_0=1
#define display_location_4_clr         clr_bit(P3,3)//P3_0=0
//*******************************数码管断码定义**********************************//
#define display_1_set                 set_bit(P2,0)//P1_4=0
#define display_1_clr                 clr_bit(P2,0)//P1_4=1
#define display_2_set                set_bit(P2,1)//P1_6=0
#define display_2_clr                 clr_bit(P2,1)//P1_6=1
#define display_3_set                set_bit(P2,2)//P2_5=0
#define display_3_clr                clr_bit(P2,2)//P2_5=1
#define display_4_set                 set_bit(P2,3)//P2_3=0
#define display_4_clr                 clr_bit(P2,3)//P2_3=1
#define display_5_set                 set_bit(P2,4)//P2_2=0
#define display_5_clr                 clr_bit(P2,4)//P2_2=1
#define display_6_set                 set_bit(P2,5)//P1_5=0
#define display_6_clr                 clr_bit(P2,5)//P1_5=1
#define display_7_set                 set_bit(P2,6)//P2_6=0
#define display_7_clr                 clr_bit(P2,6)//P2_6=1
#define display_8_set                 set_bit(P2,7)//P2_4=0
#define display_8_clr                 clr_bit(P2,7)//P2_4=1
uchar        bite=1;                                                                                  //数码管位转换数据   
//*****************************时间标记变量*************************************//
uchar      r_timer_2ms=0;                                                                                   //2ms计数累加器
bit           f_timer_2ms=0;                                                                                   //2ms标记   
uchar    r_timer_500ms=0;                                                                            //500ms计数累加器
bit        f_timer_500ms=0;                                                                             //500ms标记
uchar     key_data_old=0;                                                                                //按键编码上一状态保持寄存器
uint    show_data=1000;                                                                                //数码管显示数值保持寄存器
//**********************************稳定性处理函数***************************//
uint            key_keep_timer[8];                                                                    //稳定性计数次数初始化为0
uchar           key_station=0;                                                                      //稳定性状态标志信号反馈
//*****************************数码管BCD码值*************************************//
code unsigned char       LED_DATA[10] ={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,
//                                             0   1    2     3    4    5    6    7
                                              0x01,0x09,};//,0x3e,0x9c,0x7a,0x9e,0x8e};
//                                             8   9     -    消   e         c    d    e    f   
void scan_io(uchar LED_TABLE)
{
              //*******************************************************************************//
              if(LED_TABLE & 0x80)      display_1_set;else display_1_clr;                            //a段码控制
              if(LED_TABLE & 0x40)      display_2_set;else display_2_clr;                            //b段码控制
              if(LED_TABLE & 0x20)      display_3_set;else display_3_clr;                            //c段码控制
              if(LED_TABLE & 0x10)      display_4_set;else display_4_clr;                            //d段码控制
              if(LED_TABLE & 0x08)      display_5_set;else display_5_clr;                            //e段码控制
              if(LED_TABLE & 0x04)      display_6_set;else display_6_clr;                            //f段码控制
              if(LED_TABLE & 0x02)      display_7_set;else display_7_clr;                            //g段码控制
              if(LED_TABLE & 0x01)      display_8_set;else display_8_set;                            //H段码控制     
              //*******************************************************************************//
}
void scan_lcd(uint Timer_Count_show)
{
    unsigned char temp_data1;unsigned char temp_data2;unsigned char temp_data3;unsigned char temp_data4;unsigned char      LED_TABLE;   
//********************数码管1-4全消隐,避免产生鬼影******************************//
      display_location_1_clr;                                                                       //数码管1消隐
      display_location_2_clr;                                                                       //数码管2消隐
      display_location_3_clr;                                                                       //数码管3消隐
      display_location_4_clr;                                                                       //数码管4消隐
      display_1_clr;display_2_clr;display_3_clr;                                                    //消隐数码屏
      display_4_clr;display_5_clr;display_6_clr;                                                    //消隐数码屏
      display_7_clr;display_8_clr;                                                                    //消隐数码屏
//*******************************获取个位*******************************//
      temp_data1=Timer_Count_show/1000;     
      temp_data2=Timer_Count_show%1000/100;
      temp_data3=Timer_Count_show%1000%100/10;
      temp_data4=Timer_Count_show%1000%100%10;
        switch(bite)                                                                                    
        {                                                                                                  
          case 1:                                                                                    //千位
          {
              bite=2;
         
              display_location_1_set;
              //******************************获取查表数值*************************************//
              LED_TABLE=LED_DATA[temp_data1];                                                          //获取查表数值     
              //******************************************************//
        
          break;
          }
          case 2:                                                                                     //百位
          {
              bite=3;
         
              display_location_2_set;
              //******************************获取查表数值*************************************//
              LED_TABLE=LED_DATA[temp_data2];                                                          //获取查表数值
              //*******************************************************************************//        
          break;
          }
          case 3:                                                                                   //十位
          {
              bite=4;  
              display_location_3_set;
              //******************************获取查表数值*************************************//
              LED_TABLE=LED_DATA[temp_data3];                                                          //获取查表数值
              //*******************************************************************************//        
          break;
          }
          case 4:
          {
              bite=1;                                                                               //个位
              display_location_4_set;
              //******************************获取查表数值*************************************//
              LED_TABLE=LED_DATA[temp_data4];                                                          //获取查表数值
              //*******************************************************************************//
              break;
          }
          default:break;   
        }
        scan_io(LED_TABLE);                                                                         //数码管扫描
}
/*===================定时器1初始化程序区=====================*/
/*16.6M12分频时钟,八位自动重装定时125us定时器*/
void timer0_init(void)
{
    clr_bit(TMOD,0);                //M01    0 0 : 13 位定时器/计数器           0 1 : 16 位定时器/计数器
    set_bit(TMOD,1);                //M11     1 0 : 8 位自动重载定时器             1 1 : 定时器0 此时作为双8 位定时器/计数器
    clr_bit(TMOD,2);                //C/T1     0:定时器,T0 计数来源于Fosc 分频     1:计数器,T0 计数来源于外部管脚T0/P1.2
    clr_bit(TMOD,3);                //GATE1     TMOD[3]控制定时器0,置0 且TR0 置1 时才打开T0   
                                     //1-T1FD T1 输入频率选择控制   0:T1 频率源自于Fosc/12      1:T1 频率源自于Fosc/4
                                    //0-T0FD T1 输入频率选择控制   0:T1 频率源自于Fosc/12      1:T1 频率源自于Fosc/4   
    TL0=0x83;                           //8位自动重载125us一次中断   
    TH0=0x83;        
    TR0=0;                            //定时器T1的运行控制位。打开timer1前,先清TRO
    ET0=1;                            //允许timer1中断
    TR0=1;                            //允许timer1开始计数
    EA=1;   
}
/***********************定时器1中断入口函数**************************/
void timer0()    interrupt 1        //125us中断一次
{   
    r_timer_2ms++;
    xor_bit(P3,5);
    if(r_timer_2ms>=16)             //125us*16=2ms
    {
        r_timer_2ms=0;
        f_timer_2ms=1;
    }
}
//**************************************************************************//        
void key_station_scan(uchar station,uint click_timer,uchar keep_way)                              //稳定性检测函数   station 为输入状态检测信号
{                                                                                               //click_timer为检测次数      keep_way为利用的函数信号通道
    if(station)                                                                                 //信号输入比较是否为1
    {
        if(key_keep_timer[keep_way]==click_timer)                                                 //计数对比是否达到稳定性次数要求
        set_bit(key_station,keep_way);                                                          //状态标记置位   
        if(key_keep_timer[keep_way]<65535)                                                         //防计数溢出
        key_keep_timer[keep_way]++;                                                             //计数未达到要求继续累加计数
    }
    else                                                                                        //稳定性信号不符合清楚计数和标记
    {
    key_keep_timer[keep_way]=0;                                                                 //计数器清零
    clr_bit(key_station,keep_way);                                                              //状态标记清零
    }
}
void    key_deal(void)                                                                            //按键功能处理
{
        uchar key_data=0;
        if(get_bit(P3,7))set_bit(key_data,0);
        if(get_bit(P3,6))set_bit(key_data,1);
        key_station_scan(key_data_old==key_data,10,0);                                            //检测是否有联系20次按键稳定值
        key_data_old=key_data;                                                                    //按键状态值更新
        if(get_bit(key_station,0))
        {clr_bit(key_station,0);                                                                //检测到稳定的按键值信号标记
            switch(key_data)                                                                    //检测到按键稳定性后进行按键解码处理
            {
                case    Bin(00000001):show_data++;break;                                        //+
                case    Bin(00000010):show_data--;break;                                        //-
            }
        }
}
void timer_count(void)                                                                          //时间标记计数函数
{        
        r_timer_500ms++;
        if(r_timer_500ms>=10)                                 
        {
            r_timer_500ms=0;
            f_timer_500ms=1;                                                                      //置位500ms时间基准标记              
        }            
}
uchar P1_data=Bin(00000001);
void    liushui_led(void)
{
        if(f_timer_500ms)
        {f_timer_500ms=0;
         P1_data=(P1_data<<1);
         if(!P1_data){P1_data=Bin(00000001);}
         P1=P1_data;
        }
}
void main()
{
    timer0_init();                                                                                //定时器0初始化
    P1=Bin(00000000);
    while(1)
    {   
        if(f_timer_2ms)                                                                            //2ms执行一次主程序
        {
            f_timer_2ms=0;                                                                        //时间标记清零
            key_deal();                                                                            //按键处理函数
            scan_lcd(show_data);                                                                //数码管显示函数
            timer_count();                                                                        //时间基准函数
            liushui_led();                                                                        //流水灯处理
            xor_bit(P3,4);
        }
        
    }
}


顶顶顶顶顶顶顶顶顶顶顶顶顶顶

先谢谢小编的分享精神, 稍后认真看看小编的代码, 对于按键这个地方, 一直是似懂非懂!

有不理解需要咨询可以问我,很乐意帮忙

好帖,做个记号!

好东西就应该给大家分享才行

好的!谢谢小编!

谢谢小编分享啊,好东西

都是实际应用开发中的精华提取,供大家学习和应用

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top