按键操纵问题
程序如下。请教给问题,按键操作。我原本想就是每次按加键数值+1,按减键数值-1,但是我把我写的程序下载到板子上却是从0一下子到30,按减键从30一下子变为0,请教这是为什么。#include <stc12c5a.h>
#include "Config.h"
#include "intrins.h"
#defineNOP() _nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_() /* ????? */
#define Upkeytimer 80 //up键延迟消抖
#define Downkeytimer80 //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 intSensor_Bias = 0; //传感器偏差参数
unsigned intSensor_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);Delay2ms();HC595SendData(0);
ADDR2 = 1; ADDR1 = 0; ADDR0 = 1;HC595SendData(LedChar);Delay2ms();HC595SendData(0);
ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;HC595SendData(LedChar);Delay2ms();HC595SendData(0);
}
//void display_drive()
//{
//
// switch(i)
// {
// case 0: ucDigShowTemp = LedChar;
// ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
// HC595SendData(ucDigShowTemp);
//
// case 1: ucDigShowTemp = LedChar;
// ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
// if(ucDigDot == 1)
// {
// ucDigShowTemp=ucDigShowTemp|0x80;
// }
// HC595SendData(ucDigShowTemp);
//
// case 2:ucDigShowTemp = LedChar;
// 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 high0X80最高位与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);
} 看不懂c代码
想问下楼主:你的按键代码里有消抖动延时吗? 所有KEYLOCK没用上啊,有置有清,但没有判断的地方
不能只靠改ucKeySec为0来实现重复触发,没用的 没看程序。就问一句,程序跑一编就加减1,你按钮的速度要和程序跑的速度比了。除非设置了上下沿检测,确定是按了一次按钮。程序应该就设计单次按按钮。 具体没看,可以参考一下吴坚鸿的按键程序啊
页:
[1]