来源:电子技术网 作者: 按键扫描数码管显示程序共定义了6个键的功能:K1、K2、K3、K4以及K5、K8组成的一对复合键,其中K2,K3为连击键,K5为上档键。在正常工作模式下按K1则切换至状态,在设定模式下按K1键循环选择4个数码管中的某个,被选中的数码管闪烁,此时单按K2键显示数值加1;常按K2显示数值以一定速度递增,同时数码管停止闪烁,当K2松开,数码管恢复闪烁,显示数值停留在K2松开前的值上。K3完成的功能和K2类似。其完成减操作。这2个键只有在设定状态才有效,可以有效防止误操作。K4为确认键,按下该键回到正常显示状态,所有指示灯熄灭,数码管显示刚刚设定的数值。K5+K8这对复合键执行复位操作,任何情况下同时按下K5和K8或先按下K5再按下K8,所有数码管的显示全为0,指示灯全灭,进入正常显示状态。同时程序还对如下几个异常操作进行了处理: 1. 2个或多个功能键同时按下 2. 一个功能键按下未释放,又按另一个功能键,然后再松开其中一个功能键 3. 先按下功能键再按下上档键 4. 多个上档键和一个功能键同时按下,此时不做处理。等到松开其他上档键,只剩下一个上 5. 档键和一个功能键时才执行这对复合键;或松开所有上档键,处理单一功能键。 *******************************************************************************/ #include <iom8v.h> #include <macros.h> #define uchar unsigned char #define uint unsigned int #define RCtrl 0x20 //定义上挡键 第5键 #define RConti 0xfe //定义连击键 第6键
#define N 2 //去抖年龄下限 #define MaxRate 50 //重复前的延迟值 600ms #define MinRate 20 //重复速度 240ms #define leddark 83 //闪烁时灭时间1s #define ledshow 83 //闪烁时亮时间1s #define decimal 0x80 //小数点的段数 #define KEY_DDR DDRC #define KEY_PORTO PORTC #define KEY_PORTI PINC #define OUT 0x3f #define IN 0xc0 #define KeyValue 0x3f
#define LEDD_DDR DDRB #define LEDD_PORTO PORTB #define LEDS_DDR DDRD #define LEDS_PORTO PORTD #define LEDS_MASK 0xfc #define LEDS_NUM 0x06 #define TRUE 1 #define FALSE 0 /*定义键盘扫描程序返回数据类型*/ typedef struct { uchar shiftcnt; //上档键的个数值 uchar funcnt; //功能键的个数值 uchar shiftval; //最后扫描到的上档键的值 uchar funval; //最后扫描到的功能键的值 } keyret;
/*定义显示字符段码*/ uchar const led_stroke[19] = { //0,1,2,3,4,5,6,7,8,9 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, //a,b,C,d,e,F,P, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x73, //all on all off 0xff, 0x00 }; /*定义位选码*/ uchar const led_cs[LEDS_NUM] = { 0xfb, //11111011 0xf7, //11110111 0xef, //11101111 0xdf, //11011111 0xbf, //10111111 0x7f //01111111 }; uchar led_buf[LEDS_NUM] = { 0x73, 0x81, 0x82, 0x83, 0x84,0x85 }; uchar *pb = &led_buf[1]; //定义指向数码管数据缓冲区的指针 /*定义全局变量*/ uchar task, state; //task:按键状态,0:去抖 1,重复的延迟 2,重复 //state:显示位置变量 uchar keydone, keyprocess; //keydone: 按键任务完成标志,为1表示已完成 //keyprocess: 按键有效标志,为1时表示对按键执行 uchar keypre[2] = { 0x00, 0x00 }; //存放上次功能键和上档键的键值 //keypre0存放功能键 uchar blink, ledtime; //blink:闪烁控制寄存器,某位为1时闪烁 //d7d6d5d4d3d2d1d0 //xxxx1111 //ledtime:累计闪烁时已点亮和已熄灭的时间 uchar ledtask; //ledtask: 当前的闪烁状态,0代表亮 uchar keymark; //keymark:只是当前工作状态,为1时处于设定状态,为0时正常工作 uchar enflash; //enflash:闪烁使能标志,1闪烁 #define shut_dis() LEDS_PORTO|=LEDS_MASK; //shut display |