/******************************************************************************************* key_disp.c 键盘与数码管扫描显示驱动程序 ******************************************************************************************/
#include <reg52.h> #include <absacc.h> #include <Adc_Temp.h>
code uchar disp_seg[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5f,0x79,0x71,0x40,0x00,0xff,0xf3}; // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 全灭, 全亮, P.
//定义显示缓冲区(由定时中断程序自动扫描) uchar DispBuf[8]; //8位数码管显示的数字码(显示段码的偏移量)
uchar bdata key_flag=0; //定义键盘状态标志位 sbit key_first_flag = key_flag^0; sbit key_delay_flag = key_flag^1; sbit key_valid_flag = key_flag^2;
uchar key_value; //key_value=0: no key, or key_value=1-8 stand for key1-key8
void DispInit(); //数码管扫描显示初始化 void DispClear(); //清除数码管的所有显示 void DispP(); //显示"P. "
//在数码管位置x(0~7)处显示字符c(仅限十进制数字和减号) //void DispChar(unsigned char x, unsigned char y);
//显示指定位置x(0~7)处的小数点 //void DispDotOn(unsigned char x);
/* 函数:T1INTSVC() 功能:定时器T0的中断服务函数 */ void T1INTSVC() interrupt 1 using 1 // interrupt 3 for T1 { code uchar com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; static uchar key_value_temp, n = 0; uchar key_in,i; TR0 = 0; TH0 = 0xf8; // 0xfc66:1ms for 11.0592MHz, oxf8cd:2ms, 0xB800:20ms, 0x4C00:50ms TL0 = 0xcd; P1 = 0xFF; //暂停显示 if ( (DispBuf[n]&0x80) == 0x80 ) //带小数点显示 { DispBuf[n] = DispBuf[n]&0x7f; LED_OUT = ~(disp_seg[DispBuf[n]] | 0x80);//更新扫描数据 } else LED_OUT = ~disp_seg[DispBuf[n]];//更新扫描数据 P1 = ~com[n]; //重新显示 if(key_first_flag==0) { key_in = KEY_IN; if(key_in!=0xff) //初次检测到有键按下 { for(i=0; i<n; i++) //n:当前扫描键 key_in = key_in>>1; if( (key_in&0x01)==0x00 )//若键按下,对应KEY_IN的输入口读入状态位为0 { key_first_flag = 1;//置标志 key_value_temp = i;//暂存 } } } else if(key_delay_flag==0 && n==key_value_temp) { key_in = KEY_IN; for(i=0; i<n; i++) key_in = key_in>>1; if( (key_in&0x01)==0x00 ) //经过一轮扫描后(8*2ms=16ms),第一次按下的键仍被按下 key_delay_flag = 1; } else if(key_delay_flag==1 && n==key_value_temp) { key_in = KEY_IN; for(i=0; i<n; i++) key_in = key_in>>1; if( (key_in&0x01)==0x01 ) //再经过一轮扫描后,按键已释放:则为有效键 { key_valid_flag = 1; key_value = key_value_temp+1; } } n++; n &= 0x07; -////////////////////////////-----------------------------------------------------------------------;
TR0 = 1; }
/* 函数:DispClear() 功能:清除数码管的所有显示 */ void DispClear() { unsigned char i; for ( i=0; i<8; i++ ) { DispBuf = 0x11; //0x00; } }
/* 函数:DispP() 功能:显示"P. ",即最高为显示"P.",其余显示灭 */ void DispP() { DispClear(); DispBuf[7] = 0x13; //0xf3; }
/* 函数:DispChar() 功能:在数码管上显示字符 参数: x:数码管的坐标位置(0~7,0为高位,7为低位) y:要显示的字符,c=0~19(仅限十进制数字和减号) */ /* void DispChar(unsigned char x, unsigned char y) { //0123456789,-,全灭,全亮的数码管字型数据 // code unsigned char Tab[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x00,0xff}; DispBuf[x] = disp_seg[y]; //Tab[x]; } */
/* 函数:DispDotOn() 功能:显示指定位的小数点 参数:x为数码管坐标 */ /* void DispDotOn(unsigned char x) { DispBuf[7-x] |= 0x80; } */
/* 函数:DispInit() 功能:数码管扫描显示初始化 */ void DispInit() { DispClear(); EA = 0; TMOD &= 0xf0; //0x0F; TMOD |= 0x01; //0x10; TH0 = 0xf8; // 0xfc66:1ms for 11.0592MHz, oxf8cd:2ms, 0xB800:20ms, 0x4C00:50ms TL0 = 0xcd; TR0 = 1; ET0 = 1; EA = 1; }
|