按键操纵问题

2020-01-20 18:58发布

程序如下。请教给问题,按键操作。我原本想就是每次按加键数值+1,按减键数值-1,但是我把我写的程序下载到板子上却是从0一下子到30,按减键从30一下子变为0,请教这是为什么。

#include <stc12c5a.h>

#include "Config.h"
#include "intrins.h"


#define  NOP() _nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_() /* ????? */

#define Upkeytimer    80     //up键延迟消抖
#define Downkeytimer  80     //down键延迟消抖
#define Setkeytimer   80     //设置键延迟消抖

unsigned char i = 0;

unsigned char code LedChar[] = { //共阴字形码
                                ~0xC0, ~0xF9, ~0xA4, ~0xB0, ~0x99,
//                                 0      1      2     3       4   
                                ~0x92, ~0x82, ~0xF8, ~0x80, ~0x90,
//                                 5      6      7     8       9
                                 0x77,  0x7c,  0x39,  0x5e,  0x79, 0x71,0x3e
//                                 A      B      C     D       E     F   V
};

unsigned char ucKeySec = 0; //被触发的按键编号
unsigned char ucWd=1; //本程序的核心变量,窗口显示变量,类似一级菜单的变量,代表不太的显示窗口

unsigned char Sensor_Address = 15;   //传感器地址参数
unsigned char Sensor_Type    = 0;   //传感器类型参数
unsigned int  Sensor_Bias    = 0;   //传感器偏差参数
unsigned int  Sensor_Alarm   = 0;   //传感器报警值参数

unsigned char ucDigShow3;       //第3位数码管显示的内容
unsigned char ucDigShow2;       //第2位数码管显示的内容
unsigned char ucDigShow1;       //第1位数码管显示的内容

unsigned int ucTemp3 = 0;       //中间过度变量
unsigned int ucTemp2 = 0;       //中间过度变量
unsigned int ucTemp1 = 0;       //中间过度变量
   
unsigned int KeyUpTime  = 0;       //延迟去抖延迟计数器
unsigned char KeyUpLock = 0;       //"+"键触发后自锁的变量标志

unsigned int KeyDownTime  = 0;     //延迟去抖延迟计数器
unsigned char KeyDownLock = 0;     //"-"键触发后自锁的变量标志
   
unsigned int KeySetTime  = 0;      //延迟去抖延迟计数器
unsigned char KeySetLock = 0;      //"Set"键触发后自锁的变量标志

unsigned char ucDigDot;       //数码管第二位是否有小数点
   

unsigned char ucDisplayUpdata = 1;   //更新显示标志
unsigned int ucDigShowTemp = 0;     //临时中间变量


void Intial_myself();
void Delay_long(unsigned int ms);
void Intial_peripheral();
void Key_service();
void Display_service();
void KeyScan();
void display_drive();
void SMG_Display();
void Delay2ms();

void HC595SendData(unsigned char SendVal);


void main()
{
    Intial_myself();
    Delay_long(100);
    Intial_peripheral();
   
    while(1)
    {
        Key_service();            //按键服务的应用程序
        Display_service();          //显示窗口菜单服务程序
    }
   
}

/*初始化函数*/
void Intial_myself()
{
    ADDR0 = 1;   //第0位数码管   0:亮  1:灭
    ADDR1 = 1;   //第1位数码管
    ADDR2 = 1;   //第2位数码管
   
    LED_R = 1;   //D1--红灯   
    LED_G = 1;   //D2--绿灯
    LED_B = 1;   //D3--蓝灯
   
    KEY_UP   = 1;             //独立键盘扫描 “+” 输入引脚
    KEY_DOWN = 1;             //独立键盘扫描 “-” 输入引脚
    KEY_SET  = 1;             //独立键盘扫描 “设置”输入引脚
   
    HC595SendData(0X00);

    TMOD = 0x01;
    TH0 = 0xf8;
    TL0 = 0xcd;        
}

void Intial_peripheral()
{        
    EA=1;
   
    ET0=1;
   
    TR0=1;   
}

void Delay_long(unsigned int ms)
{
    unsigned int i;
    unsigned int j;
    for(i=0;i<ms;i++)
    {
        for(j=0;j<500;j++)
        {;}
    }
}
void KeyScan()
{
    if(KEY_UP == 1)  //高电平,没有按键按下,这时及时清标志位
    {
        KeyUpTime = 0;  //按键自锁标志清0
        KeyUpLock = 0;  //按键去抖动计数器清0        
    }
    else if(KEY_UP == 0) //说明有键按下,而且是第一次
    {
        KeyUpTime++;     //累加定时中断加1      
        if(KeyUpTime > Upkeytimer)
        {
            KeyUpTime = 0;
            KeyUpLock = 1;//自锁键置位,避免一直触发
            ucKeySec  = 1; //触发"+"号键
        }                    
    }
    if(KEY_DOWN == 1)  //高电平,没有按键按下,这时及时清标志位
    {
        KeyDownTime = 0;  //按键自锁标志清0
        KeyDownLock = 0;  //按键去抖动计数器清0        
    }
    else if(KEY_DOWN == 0) //说明有键按下,而且是第一次
    {
        KeyDownTime++;     //累加定时中断加1      
        if(KeyDownTime > Downkeytimer)
        {
            KeyDownTime = 0;
            KeyDownLock = 1;//自锁键置位,避免一直触发
            ucKeySec  = 2; //触发"-"号键
        }                    
    }
    if(KEY_SET == 1)  //高电平,没有按键按下,这时及时清标志位
    {
        KeySetTime = 0;  //按键自锁标志清0
        KeySetLock = 0;  //按键去抖动计数器清0        
    }
    else if(KEY_SET == 0) //说明有键按下,而且是第一次
    {
        KeySetTime++;     //累加定时中断加1      
        if(KeySetTime > Downkeytimer)
        {
            KeySetTime = 0;
            KeySetLock = 1;//自锁键置位,避免一直触发
            ucKeySec  = 3; //触发"设置"键
        }                    
    }   
}
//按键服务的应用程序
void Key_service()
{
    switch(ucKeySec)     //按键服务状态切换
    {
        case 1:          //"+"按键
             switch(ucWd)  //在不同的窗口下,设置不同的参数
             {
                 case 1: Sensor_Address++;if(Sensor_Address > 30);{Sensor_Address =0;}break;
                 case 2: Sensor_Type++;   if(Sensor_Type    > 4); {Sensor_Type    =0;}break;
                 case 3: Sensor_Bias++;   if(Sensor_Bias    > 60);{Sensor_Bias    =0;}break;
                 case 4: Sensor_Alarm++;  if(Sensor_Alarm   > 60);{Sensor_Alarm   =0;}break;
                 default:break;
             }

             ucDisplayUpdata = 1;  //显示更新内容
             ucKeySec = 0;         //相应按键服务程序后,按键编号清0,避免一次触发
             break;
            
        case 2:         //"-"按键
             switch(ucWd)  //在不同的窗口下,设置不同的参数
             {
                 case 1: Sensor_Address--;if(Sensor_Address <0);Sensor_Address =30;break;
                 case 2: Sensor_Type--;   if(Sensor_Type    <0);Sensor_Type    =4; break;
                 case 3: Sensor_Bias--;   if(Sensor_Bias    <0);Sensor_Bias    =60;break;
                 case 4: Sensor_Alarm--;  if(Sensor_Alarm   <0);Sensor_Alarm   =60;break;
                 default:break;
             }

             ucDisplayUpdata = 1;  //显示更新内容
             ucKeySec = 0;         //相应按键服务程序后,按键编号清0,避免一次触发
             break;
            
        case 3:      //切换窗口键
             ucWd++;
             if(ucWd>4)
             {
                ucWd = 1;
             }   
             ucDisplayUpdata = 1;  //显示更新内容
             ucKeySec = 0;         //相应按键服务程序后,按键编号清0,避免一次触发
             break;        
    }        
}

//显示窗口菜单服务程序
void Display_service()         
{
    if(ucDisplayUpdata == 1)   //有数据要更新
    {
        ucDisplayUpdata = 0;
        switch(ucWd)
        {
            case 1:   //显示压力传感器地址参数设置页面 d x x
                   ucDigShow3 = 13;      //第1位显示d
            
                   ucTemp2 = Sensor_Address / 10;   //第二位显示十位数
                   ucTemp1 = Sensor_Address % 10;   //第三位显示个位数
            
                   ucDigShow2 = ucTemp2;            //十位数送到缓冲区
                   ucDigShow1 = ucTemp1;            //个位数送到缓冲区
                  
                    LED_R = 1;
                    LED_G = 1;
                    LED_B = 1;
            // SMG_Display();
                   break;                     
            case 2:   //显示压力传感器类型参数设置页面 A x x
                    ucDigShow3 = 10;            //第1位显示 A  
                    ucDigShow2 = 0;             //第二位显示0
                    
                    ucTemp1    = Sensor_Type % 10; //获得个位数
            
                    ucDigShow1 =ucTemp1;          //个位数送到缓冲区
                    
                    LED_R = 1;
                    LED_G = 1;
                    LED_B = 1;
                    //SMG_Display();
                    break;
            case 3:   //显示压力传感器偏差参数设置页面 xx.x
                    ucTemp3 = Sensor_Bias / 100;        //获得百位数
                    ucTemp2 = Sensor_Bias / 10%10;      //获得十位数
                    ucTemp1 = Sensor_Bias % 10;         //获得个位数
            
                    ucDigShow3 =ucTemp3;                //百位数送到缓冲区
                    ucDigShow2 =ucTemp2;                //十位数送到缓冲区
                    ucDigShow1 =ucTemp1;                //个位数送到缓冲区
            
                    LED_R = 0;
                    LED_G = 1;
                    LED_B = 1;
                    //SMG_Display();
                    break;
            case 4:   //显示压力传感器报警值参数设置页面 xx.x
                    ucTemp3 = Sensor_Alarm / 100;        //获得百位数
                    ucTemp2 = Sensor_Alarm / 10%10;      //获得十位数
                    ucTemp1 = Sensor_Alarm % 10;         //获得个位数
            
                    ucDigShow3 =ucTemp3;                 //百位数送到缓冲区
                    ucDigShow2 =ucTemp2;                 //十位数送到缓冲区
                    ucDigShow1 =ucTemp1;                 //个位数送到缓冲区
                    
                    LED_R = 1;
                    LED_G = 0;
                    LED_B = 1;
                    
                    break;
            default:break;
        }           
    }
}
void SMG_Display()
{   
    ADDR2 = 0; ADDR1 = 1; ADDR0 = 1;HC595SendData(LedChar[ucDigShow3]);Delay2ms();HC595SendData(0);
    ADDR2 = 1; ADDR1 = 0; ADDR0 = 1;HC595SendData(LedChar[ucDigShow2]);Delay2ms();HC595SendData(0);
    ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;HC595SendData(LedChar[ucDigShow1]);Delay2ms();HC595SendData(0);   
}


//void display_drive()
//{
//        
//    switch(i)
//    {
//        case 0: ucDigShowTemp = LedChar[9];
//                ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;  
//                HC595SendData(ucDigShowTemp);
//        
//        case 1: ucDigShowTemp = LedChar[12];
//                ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
//                if(ucDigDot == 1)
//                {
//                    ucDigShowTemp=ucDigShowTemp|0x80;
//                }
//               HC595SendData(ucDigShowTemp);
//               
//        case 2:ucDigShowTemp = LedChar[11];
//               ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
//               HC595SendData(ucDigShowTemp);
//        default:break;
//    }
//   
//}
/*********************************************************************************************************
** 函数名称: HC595SendData
** 功能描述: 向SPI总线发送数据
*********************************************************************************************************/
void HC595SendData(unsigned char SendVal)
{  
    unsigned char i;
               
    for(i=0;i<8;i++)
    {
        if((SendVal<<i)&0x80) MOSIO=1; //set dataline high  0X80  最高位与SendVal左移的最高位 进行逻辑运算
        else MOSIO=0;                                   // 如果为真 MOSIO = 1  

        S_CLK=0;  
        NOP();         //短暂延时产生一定宽度的脉冲信号
        NOP();         //短暂延时
        S_CLK=1;
    }
    R_CLK=0; //set dataline low
    NOP();  //短暂延时
    NOP();  //短暂延时
    R_CLK=1;         //
}
/*定时中断函数*/
void T0_Time() interrupt 1
{
    static unsigned char tmr10ms = 0;

    TH0 = 0xf8;
    TL0 = 0xcd;
   
    KeyScan();
    tmr10ms++;
    if (tmr10ms >= 5)
    {
        tmr10ms = 0;
        SMG_Display();  //调用秒表计数函数
    }
   
//   display_drive();
   
}

void Delay2ms()                //@11.0592MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 22;
        j = 128;
        do
        {
                while (--j);
        } while (--i);
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。