/******************************************************************************************* key_disp.c 键盘与数码管扫描显示驱动程序 ******************************************************************************************/
#include <reg52.h> #include "shell.h" typedef unsigned char uchar; static unsigned int ihexs; //定义进制转换临时变量 unsigned char tempA; //定义闪烁时间 unsigned char tempB; //定义闪烁时间 unsigned char tempC; //P0数据备份 unsigned char bcdData[3];
unsigned char menu_Value=0; //定义菜单计数变量 unsigned char menu_data_Value=0; //定义菜单数据计数变量 bit enter_Value=1; //enter判断 bit esc_Value=1; //ESC判断
static unsigned char DispBuf[5]; //(静态变量)5位数码管显示的数字码(显示段码的偏移量) unsigned char led_shift_data=1,led_shift_enable=0; //(静态变量)键盘移动变量 code unsigned char com[] = {0x01,0x02,0x04,0x08,0x10}; code unsigned char disp_seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5f,0x79,0x71,0x40,0x00,0xff,0x73}; /* // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 全灭,全亮, P //定义显示缓冲区(由定时中断程序自动扫描) */
/* 函数:DispDotOn() 功能:显示指定位的小数点 参数:x为数码管坐标 */
void DispDotOn(unsigned char y1) { // DispClear(); DispBuf[4-y1] |= 0x80; }
/* 函数: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]; } */
/* 函数:delayms() 功能:延时函数 */ void delayms(uchar loop) // about delay time=loop*1ms (little small) { uchar i; while(loop--) // fosc=11.0592MHz for(i=0;i<210;i++); }
/* 函数:DispClear() 功能:清除数码管的所有显示 */ void DispClear() { unsigned char i; for ( i=0; i<8; i++ ) { DispBuf = 0x11; //0x00; } } /* 函数:DispInit() 功能:数码管扫描显示初始化 */ void DispInit() { P0 = 0x00; P2 = 0xff; P1 = 0xff; EA = 0; TMOD = 0x01; TH0 = 0xFC; TL0 = 0x17; IE = 0x82; TR0 = 1; EA = 1; }
/*************************** hex to bcd 转换程序 ***************************/ void hextobcd(unsigned int ihexs) { DispBuf[4] = ihexs / 10000; DispBuf[3] = ihexs % 10000 / 1000; DispBuf[2] = ihexs % 1000 / 100; DispBuf[1] = ihexs % 100 / 10; DispBuf[0] = ihexs % 10; }
/*************************** //数码管参数调整是闪烁函数 ***************************/ void led_shift() { P0=0x00; tempA++; if (tempA>40) { P0=tempC; tempB++; tempA=0x00; if (tempB>40) { P0=tempC; tempA=0x00; tempB=0x00; } } }
/* 函数功能主要是把DISPBUF的值显示出来 // 定时器0中断服务程序, 用于数码管的动态扫描 // P0 = disp_seg[DispBuf[y]]; 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量 // P2 = ~com[x]; --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时, //选通P2.0口数码管 */
void timer0() interrupt 1 { static uchar x = 0,y = 0; TR0 = 0; TH0 = 0xFC; TL0 = 0x17; //定时器 P2 = 0xFF; //暂停显示 DispDotOn(2); //功能:显示指定位的小数点 if ( (DispBuf[y]&0x80) == 0x80 ) //带小数点显示 { DispBuf[y] = DispBuf[y]&0x7f; P0 = (disp_seg[DispBuf[y]] | 0x80); //更新扫描数据 tempC = (disp_seg[DispBuf[y]] | 0x80);//扫描数据数据备份 } else P0 = disp_seg[DispBuf[y]]; //更新扫描数据 tempC = disp_seg[DispBuf[y]]; //更新扫描数据 备份 DispP(0); //功能:显示"P0 一定要放到P2后面不然显示不了点 P2 = ~com[x]; //重新显示 led_shift_data=1; if (x==led_shift_data) //数码管位选择 { led_shift(); } x++; y++; if (x>=5) { x=0; y=0; } TR0 = 1; }
/* 函数:DispP() 功能:选择高位 显示"P0 显示"P1 显示"P2 显示"P3 显示"P4 ",即最高为显示"Px",其余显示灭 */ void DispP(unsigned char led_bit) { switch (led_bit) { case 1: DispBuf[4] = 0x13; DispBuf[3] = 0x0; DispBuf[2] = 0x0; ////0xf3; 0x0; 显示 P00 break; case 2: DispBuf[4] = 0x13; DispBuf[3] = 0x0; DispBuf[2] = 0x0; ////0xf3; 0x0; 显示 P01 break; case 3: DispBuf[4] = 0x13; DispBuf[3] = 0x0; DispBuf[2] = 0x0; ////0xf3; 0x0; 显示 P02 break; case 4: DispBuf[4] = 0x13; DispBuf[3] = 0x0; DispBuf[2] = 0x0; ////0xf3; 0x0; 显示 P03 break; case 5: DispBuf[4] = 0x13; DispBuf[3] = 0x0; DispBuf[2] = 0x0; ////0xf3; 0x0; 显示 P04 break; default: break; } }
/* led显示主函数 */ void Printf_Led(unsigned int LedOut) { DispClear(); //清除LED缓冲区 ihexs = LedOut; hextobcd(ihexs); DispInit(); //数码管扫描显示//初始化中断 }
void main() {
idata unsigned char menu_data[159]; //创建参数存储区
code unsigned char menu[159]= //定义1到3位显示数据 用于查表 {
///////////////////////////P00组--//0-18 0, 1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18, ///////////////////////////P01组--//19-56 0, 1,2,3,4,5,6,7,8,19,10, 11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29,30, 31,32,33,34,35,36,37,
///////////////////////////P02组--//57-113 0, 1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29,30, 31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50, 51,52,53,54,55,56,
///////////////////////////P03组--//114-141 0, 1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,
///////////////////////////P04组--//142-159 0, 1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17 };///////////////////////////////()
//menu_data[160]; //menu[159];
Printf_Led(menu[menu_Value]); //显示LED的数值
delayms(1); while (1) {
if (P3==0xfe) //键盘UP//——————等待完善————————// { menu_Value++; //菜单偏移 menu_data_Value++; // 数据偏移 ihexs=menu[menu_Value]; //更新显示菜单 } if (P3==0xfd) //键盘DOWN//——————等待完善————————// { menu_Value--; //菜单偏移 menu_data_Value--; // 数据偏移 ihexs=menu[menu_Value]; //更新显示菜单 } if (P3==0xfb) //键盘enter//——————等待完善————————// { ihexs=menu[menu_data_Value]; //更新显示数据 enter_Value=0; //关闭 ENTER esc_Value=1; //打开 esc } if (P3==0xf7) //键盘esc//——————等待完善————————// { ihexs=menu[menu_Value]; //更新显示菜单 esc_Value=0; //关闭 esc enter_Value=1; //打开 ENTER
} // Key_Initial(); // KeyScan_Service(); // Key_Get(); }
}
|