#include #include # define uchar unsigned char # define uint unsigned int unsigned char Func_Index=0; //存放当前的菜单索引 void (*Func_Ptr)(); //定义按键功能指针 ////////////////////////////////////////////定义状态 void State0(); void State1(); void State2(); void State3(); void State4(); void State5(); void State6(); void State7(); void State8(); void State9(); void State10(); //定义按键 sbit k1=P2^0; sbit k2=P2^3; sbit k3=P2^4; sbit k4=P2^5; sbit k5=P2^6; sbit k6=P2^7; sbit k7=P1^5; sbit k8=P1^6; unsigned char key; /************定义结构的类型**********/ typedef struct { uchar Index; //当前的状态索引号 存储以后用来查询 uchar Gore; //返回待机键状态索引号 uchar Right; //右键状态索引号 uchar Up; //向上键状态索引号 uchar Down; //向下键状态索引号 uchar Enter; //确定键状态索引号 uchar Left; //向左键状态索引号 uchar Goback1; //返回上一级键状态索引号 void (*Operate)(); //当前状态应执行的操作 } StateTab; /**********结构数组*************/ StateTab code Menu_Tab[11]= { { 0, 0, 0, 1, 2, 3, 0, 0,(*State0)}, // 待机 // { 1, 0, 1, 1, 1, 1, 1, 1,(*State1)}, // 查看温度及报警范围设置 // { 2, 0, 2, 2, 2, 2, 2, 2,(*State2)}, // 查看闹铃设置 // { 3, 0, 3, 6, 4, 7, 3, 3,(*State3)}, // 主菜单 时间 // { 4, 0, 4, 3, 5, 8, 4, 4,(*State4)}, // 主菜单 闹铃 // { 5, 0, 5, 4, 6, 9, 5, 5,(*State5)}, // 主菜单 温度 // { 6, 0, 6, 5, 3,10, 6, 6,(*State6)}, // 主菜单扩展 // { 7, 0, 7, 7, 7, 3, 7, 3,(*State7)}, // 时间调整 // { 8, 0, 8, 8, 8, 4, 8, 4,(*State8)}, // 闹铃设置 // { 9, 0, 9, 9, 9, 5, 9, 5,(*State9)}, // 温度报警设置 // {10, 0,10,10,10, 5,10, 5,(*State10)}, // 扩展设置 }; //////////////////////////////////////////////////////////////////// # define LCD_DB P0 sbit LCD_RS=P1^0; sbit LCD_RW=P1^1; sbit LCD_E=P1^2; /******定义函数****************/ void MenuOperate(uchar key); void keyscan(); void LCD_init(void);//初始化函数 void LCD_write_command(uchar command);//写指令函数 void LCD_write_data(uchar dat);//写数据函数 void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-16),y(1-2) void delay_n40us(uint n);//延时函数 void Printx(uchar x, uchar y,unsigned char *str); void GotoXY(unsigned char x, unsigned char y); //*******初始化函数*************** void LCD_init(void) { delay_n40us(10000); LCD_write_command(0x38);//设置8位格式,2行,5x7 LCD_write_command(0x38);//设置8位格式,2行,5x7 LCD_write_command(0x38);//设置8位格式,2行,5x7 LCD_write_command(0x02);//整体显示,关光标,不闪烁 LCD_write_command(0x0C);//清除屏幕显示 LCD_write_command(0x06);//设定输入方式,增量不移位 } //******************************** //********写指令函数************ void LCD_write_command(uchar dat) { LCD_E = 0; LCD_RS=0;//指令 LCD_RW=0;//写入 LCD_DB=dat; LCD_E=1;//允许 delay_n40us(10);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。 LCD_E = 0; } ////////////////////////////////////////// ///////////////////写数据函数///////////////////// void LCD_write_data(uchar dat) { LCD_E = 0; LCD_RS=1;//数据 LCD_RW=0;//写入 LCD_DB=dat; LCD_E=1;//允许 delay_n40us(10); LCD_E = 0; } /////////////////////////////////// //////////////////显示一个字符函数//////////// void LCD_disp_char(uchar x,uchar y,uchar dat) { uchar address; if(y==1) address=0x80+x; else address=0xc0+x; LCD_write_command(address); LCD_write_data(dat); } //////////////////////////////延时///////////////////// void delay_n40us(uint n) { uint i; uchar j; for(i=n;i>0;i--) for(j=0;j<15;j++) ; } ////////////////////////////////////// //////////////////////////坐标////////////////////////////// void GotoXY(unsigned char x, unsigned char y) { uchar address; if(y==0) address=0x80+x; else address=0xc0+x; LCD_write_command(address); } //将字符输出到液晶显示 void Printx(uchar x, uchar y,unsigned char *str) { GotoXY(x,y); while(*str!='\0') { LCD_write_data(*str); str++; } } /////////////////////////////////////////////////////////////////////////状态/////////////////////////////////////////////////////////////////////////////// void State0() { Printx(0,0,"time "); Printx(0,1," "); delay_n40us(1000); } void State1() { Printx(0,0,"tempalarm "); Printx(0,1," "); delay_n40us(1000); } void State2() { Printx(0,0,"timealarmrange "); Printx(0,1," "); delay_n40us(1000); } void State3() { Printx(0,0,"1:timeset in"); Printx(0,1,"2:timalarm "); delay_n40us(2000); } void State4() { Printx(0,0,"2:timalarm in"); Printx(0,1,"3:temalarm "); delay_n40us(2000); } void State5() { Printx(0,0,"3:temalarm in"); Printx(0,1,"4:kuozhan "); delay_n40us(2000); } void State6() { Printx(0,0,"4:kuozhan in"); Printx(0,1,"1:timeset "); delay_n40us(2000); } void State7() { Printx(0,0,"jiztime "); Printx(0,1," "); delay_n40us(2000); } void State8() { Printx(0,0,"alarmtime "); Printx(0,1," "); delay_n40us(1000); } void State9() { Printx(0,0,"jizkuo "); Printx(0,1," "); delay_n40us(1000); } void State10() { Printx(0,0,"kuozhan "); Printx(0,1," "); delay_n40us(1000); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /***********菜单操作函数*************/ void MenuOperate(uchar key) { switch(key) { case 1: //返回键 { Func_Index=Menu_Tab[Func_Index].Gore; break; } case 2: //右 { Func_Index=Menu_Tab[Func_Index].Right; break; } case 3: //Up键 { Func_Index=Menu_Tab[Func_Index].Up; break; } case 4: //下键 { Func_Index=Menu_Tab[Func_Index].Down; break; } case 5: //确定键 { Func_Index=Menu_Tab[Func_Index].Enter; break; } case 6: //左键 { Func_Index=Menu_Tab[Func_Index].Left; break; } case 7: //返回上一层键 { Func_Index=Menu_Tab[Func_Index].Goback1; break; } // case 8: //扩展键 // { // Func_Index1=Menu_Tab[Func_Index].Kuozhang; // break; // } } Func_Ptr=Menu_Tab[Func_Index].Operate; //执行当前操作 (*Func_Ptr)(); } //////////////////////////////////键盘扫描//////////////////// void keyscan() { if(k1==0) {delay_n40us(1000); if(k1==0) { key=1; } } if(k2==0) {delay_n40us(1000); if(k2==0) { key=2; } } if(k3==0) {delay_n40us(1000); if(k3==0) { key=3; } } if(k4==0) {delay_n40us(1000); if(k4==0) { key=4; } } if(k5==0) {delay_n40us(1000); if(k5==0) { key=5; } } if(k6==0) {delay_n40us(1000); if(k6==0) { key=6; } } if(k7==0) {delay_n40us(1000); if(k7==0) { key=7; } } if(k8==0) {delay_n40us(1000); if(k8==0) { key=8; } } } //////////////////////主函数//////////////////////// void main() { LCD_init(); Printx(0,0,"welcome to"); Printx(2,1,"jizzll'bolg"); delay_n40us(100000); MenuOperate(0); while(1) { keyscan(); MenuOperate(key); key=0; } }