51单片机利用定时器按键控制数码管的加减

这里就只是需要建立两个文件一个是main.c,Gobal.h  关于reg52.h已经放在Gobal.h里面了所以main.c文件调用Gobal.h就行不需要重复使用reg52.h
#include "Gobal.h"

bit sign;
bit sign1;
bit sign2;
bit sign3;
bit sign4;
unsigned int KEY1_Cnt = 0;
unsigned int KEY2_Cnt = 0;
unsigned int KEY3_Cnt = 0;
unsigned int KEY4_Cnt = 0;
unsigned int KEY5_Cnt = 0;
unsigned int Cnt;
unsigned char key1_Flag = 1;
unsigned char key2_Flag = 0;
unsigned char key3_Flag = 0;
unsigned char key4_Flag = 0;
unsigned char key5_Flag = 0;

//--定义全局变量--//
unsigned char code DIG_PLACE[8] = {
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选控制   查表的方法控制
unsigned char code DIG_CODE[17] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char DisplayData[4];
//用来存放要显示的4位数的值

//--声明全局函数--//
void DigDisplay(); //动态显示函数
void Timer0_init();
void Timer0();

/*******************************************************************************
* 函 数 名         : main
* 函数功能           : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
unsigned int Number;
unsigned int loosen;
void main(void)
{

//    GPIO_DIG = 0x3f;
    
    Timer0_init();
    //GPIO_DIG = 0x00;//消隐
    //GPIO_PLACE = 0xf0;
    while(1)
    {
        //DigDisplay();
        
        if(sign==1)
        {
            sign=0;
            Number++;
        }
        
        
        if(sign2==1)
        {
            sign2=0;
            Number--;
        }
        
        if(sign1==1)
        {
            sign1=0;
            Number++;
//            if(Number>20)
//                Number=0;
        }
        
        if(sign3==1)
        {
            sign3=0;
            Number--;
        }
        
        if(sign4==1)
        {
            sign4=0;
            Number = 0;
        }
        
        if(Cnt_100ms == 100)
        {
            Cnt_100ms = 0;
            Dis_Buff[0] = Number%10;
            Dis_Buff[1] = Number%100/10;
            Dis_Buff[2] = Number%1000/100;
            Dis_Buff[3] = Number%10000/1000;
                
        }    
   }        
}                


/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能           : 使用数码管显示
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

//void DigDisplay()
//{
//    unsigned char i = 0;
//    unsigned int j;

//    for(i=0; i<4; i++)
//    {
//        GPIO_PLACE = ~DIG_PLACE[i];     //发送位选     
//        GPIO_DIG = DisplayData[i];     //发送段码
//        j = 60000;                         //扫描间隔时间设定  
//        while(j--);       //加入这里后数码管显示的数字灯变明显
//        GPIO_DIG = 0x00;//消隐
//    }
//}


/*******************************************************************************
* 函 数 名         : Timer0_init
* 函数功能           : 定时器0初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0_init()  //定时器0初始化
{
    TMOD = 0x01;  //选择工作方式  这里高四位是0000,低四位0001 使用定时器模式  用TRx(定时器/计数器)控制  选择工作方式1
    //16位定时器/计数器
//    TH0 = 0xD8;  //设置初始值,定时10ms  这里是每加1时间是1us
//    TL0 = 0XF0;  //
    
    TH0 = 0xFC;  //设置初始值,定时1ms  这里是每加1时间是1us    65535-1000=64535(FC17);
    TL0 = 0x17;  //
    
    EA = 1;  //打开总中断
    ET0 = 1; //打开定时器0中断  
    TR0 = 1;  //启动定时器0   中断源

}


/*******************************************************************************
* 函 数 名         : Timer0
* 函数功能           : 定时器0配置   定时1ms
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
unsigned char Cnt_100ms;
void Timer0()  interrupt 1   // 配置定时器
{
    
    TH0 = 0xFC;  //设置初始值,定时1ms  这里是每加1时间是1us   3CAF  FC17
    TL0 = 0x17;  //
    
    Display();
        

    if(Cnt<30)      //30可以换成其他的数字
    {
        Cnt++;
        if(KEY1 == 1)
        {
            if(KEY1_Cnt<30)KEY1_Cnt++;
        }
        else 
        {
            //P20 = 1;
            //这里两需要清零是因为按键在按着的时候程序一直在以按着的形式执行,
            //当你松开按键的时候可能刚好执行满足Cnt=30,KEY1_Cnt>=20这个条件所以程序往下执行会返回一次sign=1的值
            //所以松手的时候数码管有时也会有反应  
            KEY1_Cnt = 0;
            
            key1_Flag = 0;
        }
        
        if(KEY2 == 0)
        {
            if(KEY2_Cnt<30) KEY2_Cnt++;
        }
        else 
        {
        //    Cnt = 0;   //一个按键控制的时候可以Cnt清零多个的时候当一个按键按下其他按键是松开这样在其他按键那里就会把第一个按键的到的Cnt给清零下面的if(Cnt==30)就不会执行
            KEY2_Cnt = 0;
            
            key2_Flag = 0;
        }
        
        if(KEY3 == 0)
        {
            if(KEY3_Cnt<30)KEY3_Cnt++;
        }
        else 
        {
            KEY3_Cnt = 0;    
            key3_Flag = 0;
        }
        if(KEY4 == 0)
        {
            if(KEY4_Cnt<30) KEY4_Cnt++;
        }
        else 
        {
            //Cnt = 0;   
            KEY4_Cnt = 0;
            
            key4_Flag = 0;
        }
        
        if(KEY5 == 0)
        {
            if(KEY5_Cnt<30) KEY5_Cnt++;
        }
        else 
        {
        //    Cnt = 0;   
            KEY5_Cnt = 0;
            
            key5_Flag = 0;
        }
    }
    else if(Cnt == 30)    //这里的Cnt可以共用
    {
        if(KEY1_Cnt >= 20)   //这里的数字可以共用但是KEY1_Cnt不可以不同的按键有不同的CNT
        {
            if(key1_Flag == 0)   //可以不用,但是sign = 1;要保留
            {
                key1_Flag = 1;
                //loosen=1;
                sign = 1;
            }        

        }
        
            
        
        if(KEY2_Cnt >= 20)   
        {
            if(key2_Flag == 0)  
            {
                key2_Flag = 0;       //长按数值一直增加
        
                sign1 = 1;
            }        
        }
        
        if(KEY3_Cnt >= 20)   
        {
            if(key3_Flag == 0)  
            {
                key3_Flag = 1;
        
                sign2 = 1;
            }        
        }
        
        if(KEY4_Cnt >= 20)   
        {
            if(key4_Flag == 0)  
            {
                key4_Flag = 0;      //长按数值一直减少
        
                sign3 = 1;
            }        
        }
        
        if(KEY5_Cnt >= 20)   
        {
            if(key5_Flag == 0)  
            {
                key5_Flag = 1;
        
                sign4 = 1;
            }        
        }
        Cnt = 0;
        KEY1_Cnt = 0;
        KEY2_Cnt = 0;
        KEY3_Cnt = 0;
        KEY4_Cnt = 0;
        KEY5_Cnt = 0;
    }
    
    
    if(Cnt_100ms<100)Cnt_100ms++;  //这里是定时器计数,在其他地方调用Cnt_100ms==100时表示隔100ms执行一次
    
  
}

unsigned char Dis_Scan_Num;
unsigned char Dis_Buff[4];
void Display()      //数码管的
{
    DisCom0    = 0;
    DisCom1    = 0;
    DisCom2    = 0;
    DisCom3    = 0;
    GPIO_DIG = 0;
    if(Dis_Scan_Num == 0)
    {
        GPIO_DIG = DIG_CODE[Dis_Buff[0]];
        DisCom0 = 1;   //第一个数码管亮
    }
    else if(Dis_Scan_Num == 1)
    {
        GPIO_DIG = DIG_CODE[Dis_Buff[1]];
        DisCom1    = 1;   //第二个数码管亮,当扫描速度足够快时会看到第一和第二个数码管一起亮
    }
    else if(Dis_Scan_Num == 2)
    {
        GPIO_DIG = DIG_CODE[Dis_Buff[2]];
        DisCom2    = 1; 
    }
    else if(Dis_Scan_Num == 3)
    {
        GPIO_DIG = DIG_CODE[Dis_Buff[3]];
        DisCom3    = 1; 
    }
    Dis_Scan_Num++;
    if(Dis_Scan_Num == 4)Dis_Scan_Num = 0;
}

2.Gobal.h源文件

#include

//--定义使用的IO口--//
#define GPIO_DIG   P0    //段选
#define GPIO_PLACE P1    //位选

sbit KEY1 = P1^4;
sbit KEY2 = P1^5;
sbit KEY3 = P1^6;
sbit KEY4 = P1^7;
sbit KEY5 = P3^5;


sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;

#define DisCom0 P10      //数码管位选
#define DisCom1    P11   
#define DisCom2    P12
#define DisCom3    P13

extern unsigned char Cnt_100ms;

//extern bit sign;
//extern unsigned int Cnt;
//extern unsigned char key1_Flag ;
//extern unsigned int KEY1_Cnt ;
extern unsigned char Dis_Buff[4];
extern unsigned char code DIG_PLACE[8];
unsigned char code DIG_CODE[17];
void Display();

你可能感兴趣的:(51单片机,单片机,嵌入式硬件)