12864液晶按键菜单程序
12864液晶屏幕使用说明及程序
12864使用说明一、串/并接口1.1 串口接口管脚信号*注释1:如在实际应用中仅使用并口通讯模式,可将PSB 接固定高电平。
*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。
*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK 用焊锡短接。
1.2 并行接口管脚信号*注释1:如在实际应用中仅使用并口通讯模式,可将PSB 接固定高电平。
*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。
*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK 用焊锡短接。
二、模块主要硬件构成说明控制器接口信号说明:2.1、RS,R/W的配合选择决定控制界面的4种模式:2.2、E信号●忙标志BFBF 标志提供内部工作情况.BF=1 表示模块在进行内部操作,此时模块不接受外部指令和数据.BF=0 时, 模块为准备状态,随时可接受外部指令和数据.利用STATUS RD 指令,可以将BF 读到DB7 总线,从而检验模块之工作状态.●字型产生ROM(CGROM)字型产生ROM(CGROM)提供8192 个此触发器是用于模块屏幕显示开和关的控制。
DFF=1 为开显示(DISPLAY ON),DDRAM 的内容就显示在屏幕上,DFF=0 为关显示(DISPLAY OFF)。
DFF 的状态是指令DISPLAY ON/OFF 和RST 信号控制的。
●显示数据RAM(DDRAM)模块内部显示数据 RAM 提供 64×2 个位元组的空间,最多可控制 4 行 16 字(64 个字)的中文字型显示,当写入显示数据 RAM 时,可分别显示 CGROM 与CGRAM 的字型;此模块可显示三种字型,分别是半角英、数字型(16*8)、CGRAM 字型及 CGROM 的中文字型。
三种字型的选择,由在 DDRAM 中写入的编码选择,在0000H—0006H 的编码中(其代码分别是0000、0002、0004、0006 共4 个)将选择 CGRAM 的自定义字型,02H—7FH 的编码中将选择半角英数字的字型,至于A1 以上的编码将自动的结合下一个位元组,组成两个位元组的编码形成中文字型的编码BIG5(A140—D75F),GB(A1A0-F7FFH)。
12864液晶电子钟具有按键可调闹钟温度显示
12864液晶电子钟具有按键可调闹钟温度显示理解才是最主要程序已全部通过硬件测试,请放心使用。
(没有使用到DS1302)/某某某某某某某某某某某某12864时钟显示函数某某某某某某某某某某某某某//某某某某某某实现时间走动、按键控制、蜂鸣器闹铃、温度显示某某某某某某/#include<reg52.h>#include<tdio.h>#defineucharunignedchar#defineuintunignedint/某某某某某某某某某某某某某某某某某某某某功能:定义液晶12864控制端接口某某某某某某某某某某某某某某某某某某某某某/bitr=P2^6;//注意:rw控制端始终为低电平,直接在硬件上接低电平biten=P2^7;bitwd=P2^0;//温度传感器信号线/某某某某某某某某某某某某某某某某某某某某功能:定义蜂鸣器、按键接口某某某某某某某某某某某某某某某某某某某某某/bitbeet=P2^2;//蜂鸣器定义bitkey1=P1^0;//功能选择bitkey2=P1^1;//至加bitkey3=P1^2;//至减bitkey4=P1^3;//北京时间与闹钟时间画面切换/某某某某某某某某某某某某某某某某某某某某功能:定义数据初始值某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某/charhour=23,minute=59,econd=58,count=0;charhi=0,fen=0,miao=0,hm;intyear=2022;charmonth=12,day=30,mm=0,cc=7;uinttemp;floatf_temp;/某某某某某某某某某某某某某某某某某某某某功能:定义数组字符串某某某某某某某某某某某某某某某某某某某某某/ucharcodetable1[]={"幸福牌电子钟"};ucharcodetable2[]={"温馨提示:00.0℃"};/某某某某某某某某某某某某某某某某某某某某功能:延时函数某某某某某某某某某某某某某某某某某某某某某某某某某某某/voiddelay(uintz){uint某,y;for(某=z;某>0;某--)for(y=110;y>0;y--);}/某某某某某某某某某某某某某某某某某某某功能:蜂鸣器响应某某某某某某某某某某某某某某某某某某某某某某某/voidfengmingqi(){beet=0;delay(1);beet=1;delay(1);}理解才是最主要/某某某某某某某某某某某某某某某某某某某某功能:液晶12864读写数据某某某某某某某某某某某某某某某某某某/void某ieling_hu(ucharaa,ucharbb){if(aa==1){r=0;}if(aa==0){r=1;}P0=bb;delay(1);en=1;delay(1);en=0;delay(1);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864写入地址某某某某某某某某某某某某某某某某某某/void某ieludizhi(uchar某,uchary){witch(某){cae1:某ieling_hu(1,0某80+y);return;//return返回的意思cae2:某ieling_hu(1,0某90+y);return;cae3:某ieling_hu(1,0某88+y);return;cae4:某ieling_hu(1,0某98+y);return;}}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864写入字符串某某某某某某某某某某某某某某某某某/void某iezifuchuan(uchar某dd){while(某dd!='\0'){某ieling_hu(0,某dd++);}}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864清屏函数某某某某某某某某某某某某某某某某某某某某某/voidqingping(){某ieling_hu(1,0某01);//清屏某ieling_hu(1,0某01);//清屏某ieling_hu(1,0某01);//清屏delay(20);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864初始化指令操作某某某某某某某某某某某某某某某某某某/voidinit_12864(){某ieling_hu(1,0某30);//基本指令操作某ieling_hu(1,0某30);//基本指令操作某ieling_hu(1,0某0C);//0某0c:无光标,O某OF:光标反白显示某ieling_hu(1,0某01);//清屏理解才是最主要某ieling_hu(1,0某06);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864初始化字串显示某某某某某某某某某某某某某某某某某某/voidinit_zifu(){某ieludizhi(1,0);某iezifuchuan("欢迎使用");delay(1);某ieludizhi(2,0);某iezifuchuan("幸福牌电子钟");delay(1);某ieludizhi(3,0);某iezifuchuan("订购热线");delay(1);某ieludizhi(4,0);某iezifuchuan("Phone:0777-66914");delay(9534);qingping();某ieludizhi(1,0);某iezifuchuan(table1);delay(1);某ieludizhi(4,0);某iezifuchuan(table2);delay(1);某ieludizhi(3,5);某iezifuchuan("星期");某ieludizhi(2,2);某iezifuchuan("年月日");}/某某某某某某某某某某某某某某某某某某某功能:时间、年月日显示函数某某某某某某某某某某某某某某某某某某某某/voiddiplay(){某ieludizhi(3,0);//显示时分秒某ieling_hu(0,0某30+hour/10);某ieling_hu(0,0某30+hour%10);某ieling_hu(0,':');某ieling_hu(0,0某30+minute/10);某ieling_hu(0,0某30+minute%10);某ieling_hu(0,':');某ieling_hu(0,0某30+econd/10);某ieling_hu(0,0某30+econd%10);某ieludizhi(2,0);//显示年某ieling_hu(0,0某30+year/1000);某ieling_hu(0,0某30+year%1000/100);某ieling_hu(0,0某30+year%100/10);某ieling_hu(0,0某30+year%10);某ieludizhi(2,3);//显示月某ieling_hu(0,0某30+month/10);某ieling_hu(0,0某30+month%10);某ieludizhi(2,5);//显示日某ieling_hu(0,0某30+day/10);某ieling_hu(0,0某30+day%10);}/某某某某某某某某某某某某某某某某某某某功能:闹钟(时间、年月日)显示函数某某某某某某某某某某某某某某某某某某某某/voiddiplay1(){理解才是最主要某ieludizhi(3,0);//显示时分秒某ieling_hu(0,0某30+hi/10);某ieling_hu(0,0某30+hi%10);某ieling_hu(0,':');某ieling_hu(0,0某30+fen/10);某ieling_hu(0,0某30+fen%10);某ieling_hu(0,':');某ieling_hu(0,0某30+miao/10);某ieling_hu(0,0某30+miao%10);某ieludizhi(2,0);//显示年某ieling_hu(0,0某30+year/1000);某ieling_hu(0,0某30+year%1000/100);某ieling_hu(0,0某30+year%100/10);某ieling_hu(0,0某30+year%10);某ieludizhi(2,3);//显示月某ieling_hu(0,0某30+month/10);某ieling_hu(0,0某30+month%10);某ieludizhi(2,5);//显示日某ieling_hu(0,0某30+day/10);某ieling_hu(0,0某30+day%10);}/某某某某某某某某某某某某某某某某某某某功能:星期函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某/ void某ingqi(){witch(cc){cae1:某ieludizhi(3,7);某iezifuchuan("一");return;cae2:某ieludizhi(3,7);某iezifuchuan("二");return;cae3:某ieludizhi(3,7);某iezifuchuan("叁");return;cae4:某ieludizhi(3,7);某iezifuchuan("四");return;cae5:某ieludizhi(3,7);某iezifuchuan("五");return;cae6:某ieludizhi(3,7);某iezifuchuan("六");return;cae7:某ieludizhi(3,7);某iezifuchuan("日");return;}}/某某某某某某某某某某某某某某某某某某某功能:按键程序某某某某某某某某某某某某某某某某某某某/voidanjian(){if(key4==0){delay(1);hm=~hm;while(key4==0);}/某某某某某某某某某某某某某某某某某某某功能:key1按键选择功能某某某某某某某某某某某某某某某某某某某/if(key1==0){delay(1);mm++;if(hm!=0){if(mm>=4)mm=0;}理解才是最主要if(mm==1){某ieludizhi(3,3);某ieling_hu(0,0某5f);}if(mm==2){TR0=1;某ieludizhi(3,2);某ieling_hu(0,0某5f);}if(mm==3){某ieludizhi(3,0);某ieling_hu(0,0某5f);}if(mm==4){某ieludizhi(2,5);某ieling_hu(0,0某5f);}if(mm==5){某ieludizhi(2,3);某ieling_hu(0,0某5f);}if(mm==6){某ieludizhi(2,1);某ieling_hu(0,0某5f);}if(mm==7){某ieludizhi(3,7);某ieling_hu(0,0某5f);}if(mm==8){某ieludizhi(2,7);某ieling_hu(0,0某02);}if(mm>=9){某ieludizhi(2,7);某ieling_hu(0,0某20);mm=0;}//mm=0;跳出调整时间while(key1==0);}/某某某某某某某某某某某某某某某某某某某功能:key2按键加减功能某某某某某某某某某某某某某某某某某某某/if(mm==1&&key2==0)//秒加1{if(hm==0){TR0=0;delay(1);if(key2==0){econd++;if(econd>=60){e cond=0;}}}if(hm!=0){delay(1);if(key2==0){miao++;if(miao>=60){miao=0;}}} while(key2==0);}if(mm==1&&key3==0)//秒减1{if(hm==0){TR0=0;delay(1);if(key3==0){econd--;if(econd<=-1){econd=59;}}}if(hm!=0){delay(1);if(key3==0){miao--;if(miao<=-1){miao=59;}}}while(key3==0);}if(mm==2&&key2==0)//分加1{if(hm==0){delay(1);if(key2==0){minute++;if(minute>=60){minut e=0;}}}if(hm!=0){delay(1);if(key2==0){fen++;if(fen>=60){fen=0;}}}while(key2==0);}if(mm==2&&key3==0)//分减1{if(hm==0){delay(1);if(key3==0){minute--;if(minute<=-1){minute=59;}}}if(hm!=0){delay(1);if(key3==0){fen--;if(fen<=-1){fen=59;}}} while(key3==0);}理解才是最主要if(mm==3&&key2==0)//时加1{if(hm==0){delay(1);if(key2==0){hour++;if(hour>=24){hour=0;}}} if(hm!=0){delay(1);if(key2==0){hi++;if(hi>=24){hi=0;}}}while(key2==0);}if(mm==3&&key3==0)//时减1{if(hm==0){delay(1);if(key3==0){hour--;if(hour<=-1){hour=23;}}}if(hm!=0){delay(1);if(key3==0){hi--;if(hi<=-1){hi=23;}}} while(key3==0);}if(mm==4&&key2==0)//日加1{delay(1);if(key2==0){day++;if(day>=31){day=1;}}while(key2==0);}if(mm==4&&key3==0)//日减1{delay(1);if(key3==0){day--;if(day<=0){day=31;}}while(key3==0);}if(mm==5&&key2==0)//月加1 {delay(1);if(key2==0){month++;if(month>=13){month=1;}}理解才是最主要while(key2==0);}if(mm==5&&key3==0)//月减1{delay(1);if(key3==0){month--;if(month<=0){month=12;}}while(key3==0);}if(mm==6&&key2==0)//年加1{delay(1);if(key2==0){year++;}//不设置年限while(key2==0);}if(mm==6&&key3==0)//年减1{delay(1);if(key3==0){year--;}while(key3==0);}if(mm==7&&key2==0)//星期加1 {delay(1);if(key2==0){cc++;if(cc>=8){cc=1;}}while(key2==0);}if(mm==7&&key3==0)//星期减1 {delay(1);if(key3==0){cc--;if(cc==0){cc=7;}理解才是最主要}while(key3==0);}}/某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某功能:18B20所有函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//某某某某某某某某某某某某某某某某某某某18B20复位,初始化函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voiddreet(void){uinti;wd=0;i=103;while(i>0)i--;wd=1;i=4;while(i>0)i--;}/某某某某某某某某某某某某某某某某某某某18B20读1位函数某某某某某某某某某某某某某某某某某某某某某某某某某某/bittempreadbit(void){uinti;bitdat;wd=0;i++;//i++起延时作用wd=1;i++;i++;dat=wd;i=8;while(i>0)i--;return(dat);}/某某某某某某某某某某某某某某某某某某某18B20读1个字节函数某某某某某某某某某某某某某某某某某某某某某某某某某某/uchartempread(void){uchari,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);理解才是最主要}/某某某某某某某某某某某某某某某某某某某18B20写一个字节数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voidtempwritebyte(uchardat){uinti;ucharj;bittetb;for(j=1;j<=8;j++){tetb=dat&0某01;dat=dat>>1;if(tetb)//写1{wd=0;i++;i++;wd=1;i=8;while(i>0)i--;}ele{wd=0;//写0i=8;while(i>0)i--;wd=1;i++;i++;}}}/某某某某某某某某某某某某某某某某某某某18B20开始获取温度并转换函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voidtempchange(void){dreet();delay(1);tempwritebyte(0某cc);//写跳过读ROM指令tempwritebyte(0某44);//写温度转换指令}/某某某某某某某某某某某某某某某某某某某18B20读取寄存器中存储的温度数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/uintget_temp(){uchara,b;dreet();delay(1);理解才是最主要tempwritebyte(0某cc);tempwritebyte(0某be);a=tempread();//读低8位b=tempread();//读高8位temp=b;temp<<=8;//两个字节组合为1个字temp=temp|a;f_temp=temp某0.0625;//温度在寄存器中为12位分辨率位0.0625°temp=f_temp某10+0.5;//乘以10表示小数点后面只取1位,加0.5是四舍五入f_temp=f_temp+0.05;returntemp;//temp是整型}/某某某某某某某某某某某某某某某某某某某18B20发送数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/{do{SBUF=某parr++;//发送数据while(!TI);//等待发送完成标志为1TI=0;//标志清零}while(某parr);//保持循环直到字符为'\0'}/某某某某某某某某某某某某某某某某某某某某某某某某功能:主函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某/ voidmain(){ucharbuff[4];TMOD=0某01;//设置T0为工作方式1EA=1;ET0=1;TR0=1;//开启T0中断TH0=-50000/256;TL0=-50000%256;init_12864();init_zifu();hm=0;while(1){if(count>5&&count<18){tempchange();//开始获取温度get_temp();//读取寄存温度printf(buff,"%f",f_temp);某ieludizhi(4,5);某ieling_hu(0,0某30+temp/100);某ieling_hu(0,0某30+temp%100/10);理解才是最主要某ieling_hu(0,0某2e);某ieling_hu(0,0某30+temp%100%10);}if(hm==0)diplay();//如果hm=0显示北京时间,否则显示闹钟时间elediplay1();anjian();//按键判断某ingqi();//显示星期if(minute==59&&econd==59){fengmingqi();}//整点报时if(hi==hour&&fen==minute&&miao>=econd&&miao<=econd+3){fengmi ngqi();}//闹钟}}/某某某某某某某某某某某某某某某某某某某某某某某某功能:中断函数某某某某某某某某某某某某某某某某某某某某某某某某某某/ {TH0=-50000/256;TL0=-50000%256;count++;if(count==20){count=0;econd++;if(econd==60){econd=0;minute++;if(minute==60) {minute=0;hour++;if(hour==24){hour=0;day++;cc++;if(cc==8)cc=1; if(day==31){day=1;month++;if(month==13)理解才是最主要{month=1;year++; }}} } } } }。
12864并行多级菜单程序
#include "includes.h"u8 key=0,hua;extern u32 Second;extern u32 minite,hour,day,k,month,year,shan;u8 xingqi[]={"一二三四五六日"};u8 ModeFlag=0,wei=0;//液晶界面选择int main(void){u8 PasswordIndex=0;//密码数组索引u8 Password[4]={" "};//存储密码数组BSP_Init();//初始化外部资源ModeFlag=0;while(1){//////////////////////////////////////// 界面一//////////////////////////////////if(ModeFlag==0){ LCD12864_Waddr(1,3);LCD12864_WPoss(0,"WELCOME!");LCD12864_Waddr(2,2);LCD12864_WPoss(0,"--欢迎使用--");Delay_1ms(8000);LCD12864_Clear();}//////////////////////////////////////// 界面二//////////////////////////////////// ModeFlag=0; ///// 改while(ModeFlag==0) //进入登录界面{LCD12864_Waddr(1,1);LCD12864_WPoss(0,"请输入登陆密码:");LCD12864_Waddr(2,3);//LCD12864_WPoss(0," ");LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码为四位数字");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"删除*");LCD12864_Waddr(4,6);LCD12864_WPoss(0,"确定#");key=Key_Scan();//键盘扫描if(key_check==1)//检测是否有按键按下{if(key<='9'&&key>='0')//密码只能是数字{Password[PasswordIndex]=key;//存储输入的密码// LCD12864_WPoss(0," ");//////////////// 改动过++PasswordIndex; //记录输入密码的次数if(PasswordIndex>4) //如果次数超过4次返回重新输入{PasswordIndex=0;//清空索引Password[0]=0;//清空数组Password[1]=0;Password[2]=0;Password[3]=0;LCD12864_Clear();LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码只能为四位");Delay_1ms(4000);//延时两秒显示LCD12864_Clear(); //延时清空break;}if(PasswordIndex<=4){LCD12864_Waddr(2,3);LCD12864_WPoss(0,Password);//显示输入的密码LCD12864_WPoss(0," ");/// 改}//ModeFlag=10;//进入while(1) 重新开始///// 改}if(key=='#') //确认密码{if(PasswordIndex<4)//密码位数少于4位则返回重新输入{PasswordIndex=0;Password[0]=0;Password[1]=0;Password[2]=0;Password[3]=0;LCD12864_Clear();LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码只能为四位");Delay_1ms(4000);LCD12864_Clear();break;}if(Password[0]=='1'&&Password[1]=='2'&&Password[2]=='3'&&Password[3]=='4'){//如果输入密码正确则进入计数界面//ModeFlag=2;LCD12864_Clear();//// LCD12864_Waddr(1,5);//// LCD12864_WPoss(0,"00:00");// LCD12864_Waddr(2,4);//// LCD12864_WPoss(0,"2013/01/01");// LCD12864_Waddr(3,4);// LCD12864_WPoss(0,"星期一");//// LCD12864_Waddr(4,6);//// LCD12864_WPoss(0,"返回*");////// Second=0;//计数器清零// minite=0;//计数器清零// hour=0;// day=1;// month=1;}else //如果密码错误重新输入{//ModeFlag=10;//进入while(1) 重新开始LCD12864_Clear();LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码错误");Delay_1ms(4000);LCD12864_Clear();PasswordIndex=0;Password[0]=0;Password[1]=0;Password[2]=0;Password[3]=0;break;}}if(key=='*')//删除按键{Password[--PasswordIndex]=' ';//删除一位密码LCD12864_Waddr(2,3);LCD12864_WPoss(0,Password);//显示输入的密码LCD12864_WPoss(0," ");if(PasswordIndex<=0){PasswordIndex=0;break;}}key_check=0;LCD12864_Waddr(2,8);LCD12864_WPoss(0," ");}}//////////////////////////////////界面三///////////////////////////////////////////////////while(ModeFlag==2){LCD12864_Waddr(1,1);LCD12864_WPoss(0,"查看时钟");LCD12864_Waddr(1,6);LCD12864_WPoss(0," B向上");LCD12864_Waddr(2,1);LCD12864_WPoss(0,"查看图片");LCD12864_Waddr(2,6);LCD12864_WPoss(0," C向下");LCD12864_Waddr(3,1);LCD12864_WPoss(0,"空文件");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"返回*");LCD12864_Waddr(4,6);LCD12864_WPoss(0,"确定#");key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='B'){if(hua>0)hua--;}if(key=='C'){if(hua<2)hua++;}if(hua>2)hua=0;switch(hua){case 0:{convertChar(1,1,10);break;}case 1:{ convertChar(2,1,10);break;}case 2:{convertChar(3,1,10);break;}}if(key=='#'){if(hua==0)ModeFlag=3;if(hua==1)ModeFlag=4;if(hua==2)ModeFlag=5;LCD12864_W (LCD12864_COM,0x30);break;}if(key=='*'){LCD12864_Clear();Delay_1ms(1000);ModeFlag=0;LCD12864_Clear();}}}/////////////////////////////////////////// 界面四//////////////////////////if(ModeFlag==3)//计数界面{///////// Password[ ]=" ";// LCD12864_Waddr(1,1);// LCD12864_WPoss(0," ");LCD12864_Clear();//LCD12864_Waddr(1,5);//LCD12864_WPoss(0,"00:00");LCD12864_Waddr(2,4);//LCD12864_WPoss(0,"2013/01/01");LCD12864_Waddr(3,4);LCD12864_WPoss(0,"星期一");//LCD12864_Waddr(4,6);//LCD12864_WPoss(0,"返回*");//Second=0;//计数器清零minite=0;//计数器清零hour=0;day=1;month=1;while(ModeFlag==3){ if(shan==0) // :以秒为单位进行闪烁{LCD12864_Waddr(1,6);LCD12864_WPoss(0," ");}if(shan!=0){LCD12864_Waddr(1,6);LCD12864_WPoss(0,":");}if(minite<10){LCD12864_Wnum(0,0);LCD12864_Wnum(minite,0);LCD12864_WPoss(0," ");}else{LCD12864_Wnum(minite,0);LCD12864_WPoss(0," ");}LCD12864_Waddr(1,5);if(hour<10){LCD12864_Wnum(0,0);LCD12864_Wnum(hour,0);}if(hour>=10){LCD12864_Waddr(1,5);LCD12864_Wnum(hour,0);}LCD12864_Waddr(2,8);if(day<10){LCD12864_Wnum(0,0);LCD12864_Wnum(day,0);}if(day>=10)LCD12864_Wnum(day,0); LCD12864_Waddr(2,6);if(month<10){LCD12864_WPoss(0,"/");LCD12864_Wnum(0,0);LCD12864_Wnum(month,0);LCD12864_WPoss(0,"/");}if(month>=10){LCD12864_WPoss(0,"/");LCD12864_Wnum(month,0);LCD12864_WPoss(0,"/");}LCD12864_Waddr(3,6);LCD12864_W(LCD12864_DAT,xingqi[k]);LCD12864_W(LCD12864_DAT,xingqi[k+1]);if(day>365)year++;LCD12864_Waddr(2,4);LCD12864_Wnum(year,0);key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='A'){ wei++;if(wei==7)wei=1;}switch(wei){case 1:{if(key=='B')hour++;if(hour>0){ if(key=='C')hour--;}convertChar(1,5,2);//写入字节break;}case 2:{if(key=='B')minite++;if(minite>0){ if(key=='C')minite--;}convertChar(1,6,3);break;}case 3:{if(key=='B')year++;if(year>0){ if(key=='C')year--;}convertChar(2,4,4);break;}case 4:{if(key=='B')month++;if(month>1){ if(key=='C')month--;}convertChar(2,6,3);break;}case 5:{if(key=='B')day++;if(day>1){ if(key=='C')day--;}convertChar(2,8,2);break;}case 6:{if(key=='B')k=k+2;convertChar(3,6,2);break;}}if(key=='*'){ModeFlag=2;Delay_1ms(40);LCD12864_Clear();}}}}////////////////////////////////// 界面五////////////////////////////// while(ModeFlag==4){LCD12864_Clear();LCD12864_Waddr(2,3);LCD12864_WPoss(0,"No pictures");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"返回*");key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='*'){LCD12864_Clear();Delay_1ms(1000);ModeFlag=2;LCD12864_Clear();}}}///////////////////////////////// 界面六///////////////////////////////// while(ModeFlag==5){LCD12864_Clear();LCD12864_Waddr(2,3);LCD12864_WPoss(0,"啥也没有");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"返回*");key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='*'){Delay_1ms(100);ModeFlag=2;LCD12864_Clear();}}}}}。
12864菜单程序修改版
12864多级菜单设计作者董新凯#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#include "init.h"#define UINT8 unsigned char#define UINT16 unsigned int#define D_RS PTCD_PTCD4#define D_RW PTFD_PTFD4#define D_E PTCD_PTCD0#define D_L PTCD_PTCD1 //左右半屏选择#define D_R PTCD_PTCD2#define D_REST PTFD_PTFD5 //复位选择#define LED1 PTCD_PTCD5#define LED2 PTCD_PTCD6#define LED3 PTCD_PTCD7#define LED4 PTFD_PTFD6#define LED5 PTFD_PTFD3/******************菜单填充**************/# define FillType_Fill 0x01 //填充黑色# define FillType_Clear 0x00 //填充白色const UINT8 zimo[][32]={/*-- 文字: 菜0 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x04,0x04,0x44,0xC4,0x4F,0x44,0x44,0xC4,0x24,0x24,0x2F,0xB4,0x24,0x04,0x04,0x00, 0x40,0x44,0x24,0x24,0x15,0x0C,0x04,0xFE,0x04,0x0C,0x15,0x24,0x24,0x44,0x40,0x00, },/*-- 文字: 单 1 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x00,0x00,0xF8,0x49,0x4A,0x4C,0x48,0xF8,0x48,0x4C,0x4A,0x49,0xF8,0x00,0x00,0x00, 0x10,0x10,0x13,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x13,0x10,0x10,0x00, },/*-- 文字: 一2--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },/*-- 文字: 二3--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, },/*-- 文字: 三4--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, },/*-- 文字: 四5--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00, 0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x7F,0x00,0x00, },/*-- 文字: 是6--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x00,0x00,0x00,0x7F,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x7F,0x00,0x00,0x00,0x00, 0x81,0x41,0x21,0x1D,0x21,0x41,0x81,0xFF,0x89,0x89,0x89,0x89,0x89,0x81,0x81,0x00, },/*-- 文字: 否7--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/{0x00,0x02,0x82,0x82,0x42,0x22,0x12,0xFA,0x06,0x22,0x22,0x42,0x42,0x82,0x00,0x00, 0x01,0x01,0x00,0xFC,0x44,0x44,0x44,0x45,0x44,0x44,0x44,0xFC,0x00,0x00,0x01,0x00, }};UINT8 Menu_word[][4]={{0,1,2},{0,1,3},{0,1,4},{0,1,5}} ;struct MenuItem{ //菜单结构UINT8 MenuCount;//菜单项所在层的菜单项数目UINT8 *DisplayString;//显示的名称void (*subs)(void);//所指向的功能函数UINT8 Local_x;UINT8 Local_y;//菜单的横纵起始坐标struct MenuItem *ChildrenMenu;//所指向的子菜单struct MenuItem *ParentMenu;//所指向的父菜单struct MenuItem *This;//Thi s指针指向本项菜单1行地址};/*****************************************/struct MenuItem MainMenu[4];struct MenuItem ChildMenu1[3];struct MenuItem ChildMenu2[3];struct MenuItem ChildMenu3[3];struct MenuItem ChildMenu4[3];struct MenuItem SubChildMenu1;struct MenuItem SubChildMenu2;struct MenuItem SubChildMenu3;/*****************菜单状态储存数组*************************/ struct Menu_stat{UINT8 current_stat; //当前状态位UINT8 down_stat; //下状态位UINT8 up_stat; //上状态位UINT8 esc_stat; //返回状态位UINT8 enter_stat; //确定状态位struct MenuItem *Menu_pointer;//指向菜单结构的指针};const struct Menu_stat Menu_table[]=/************************************///1~4主菜单//5,8,11,14次级菜单//17~28三级菜单{{0,1,4,1,0,&MainMenu[0]},{1,2,4,1,5,&MainMenu[0] //0 },{2,3,1,2,8,&MainMenu[1] //1 },{3,4,2,3,11,&MainMenu[2] //2 },{4,1,3,4,14,&MainMenu[3] //3 },{5,6,7,1,17,&ChildMenu1[0]//4 },{6,7,5,1,18,&ChildMenu1[1]//5 },{7,5,6,1,19,&ChildMenu1[2]//6 },{8,9,10,2,20,&ChildMenu2[0] },{9,10,8,2,21,&ChildMenu2[1] },{10,8,9,2,22,&ChildMenu2[2] },{11,12,13,3,23,&ChildMenu3[0] },{12,13,11,3,24,&ChildMenu3[1] },{13,11,12,3,25,&ChildMenu3[2] },14,15,16,4,26,&ChildMenu4[0] },{15,16,14,4,27,&ChildMenu4[1] },{16,14,15,4,28,&ChildMenu4[2] },{17,17,17,5,17,&SubChildMenu1 },{18,18,18,6,18,&SubChildMenu2 },{19,19,19,7,19,&SubChildMenu3 },{20,20,20,8,20,&SubChildMenu1 },{21,21,21,9,21,&SubChildMenu2 },{22,22,22,10,22,&SubChildMenu3 },{23,23,23,11,23,&SubChildMenu1 },{24,24,24,12,24,&SubChildMenu2 },{25,25,25,13,25,&SubChildMenu3 },{26,26,26,14,26,&SubChildMenu1 },{27,27,27,15,27,&SubChildMenu2 },{28,28,28,16,28,&SubChildMenu3};/**********************************************************/ struct MenuItem *Menu_point=NULL;UINT8 key_number=0;UINT8 key_number_store=0;/**********************************************************/ void _12864_busycheck(void);void _12864_wr_cmd(UINT8 cmd);void _12864_clear_dot(UINT8 x,UINT8 y);void delay(UINT16 time){UINT16 i;for(i=0;i<time;i++);}/****************菜单初始化******************/void MainMenu_init(void){MainMenu[0].MenuCount=4;MainMenu[0].DisplayString=&Menu_word[0][0];MainMenu[0].subs=NULL;MainMenu[0].Local_x=5;MainMenu[0].Local_y=0;MainMenu[0].ChildrenMenu=ChildMenu1;MainMenu[0].ParentMenu=NULL;MainMenu[0].This=MainMenu;MainMenu[1].MenuCount=4;MainMenu[1].DisplayString=&Menu_word[1][0];MainMenu[1].subs=NULL;MainMenu[1].Local_x=5;MainMenu[1].Local_y=0;MainMenu[1].ChildrenMenu=ChildMenu2;MainMenu[1].ParentMenu=NULL;MainMenu[1].This=MainMenu;MainMenu[2].MenuCount=4;MainMenu[2].DisplayString=&Menu_word[2][0];MainMenu[2].subs=NULL;MainMenu[2].Local_x=5;MainMenu[2].Local_y=0;MainMenu[2].ChildrenMenu=ChildMenu3;MainMenu[2].ParentMenu=NULL;MainMenu[2].This=MainMenu;MainMenu[3].MenuCount=4;MainMenu[3].DisplayString=&Menu_word[3][0];MainMenu[3].subs=NULL;MainMenu[3].Local_x=5;MainMenu[3].Local_y=0;MainMenu[3].ChildrenMenu=ChildMenu4;MainMenu[3].ParentMenu=NULL;MainMenu[3].This=MainMenu;}void ChildMenu1_init(void){ChildMenu1[0].MenuCount=3;ChildMenu1[0].DisplayString=&Menu_word[0][0];ChildMenu1[0].subs=NULL;ChildMenu1[0].Local_x=43;ChildMenu1[0].Local_y=0;ChildMenu1[0].ChildrenMenu=&SubChildMenu1;ChildMenu1[0].ParentMenu=MainMenu;ChildMenu1[0].This=ChildMenu1;ChildMenu1[1].MenuCount=3;ChildMenu1[1].DisplayString=&Menu_word[1][0];ChildMenu1[1].subs=NULL;ChildMenu1[1].Local_x=43;ChildMenu1[1].Local_y=0;ChildMenu1[1].ChildrenMenu=&SubChildMenu2;ChildMenu1[1].ParentMenu=MainMenu;ChildMenu1[1].This=ChildMenu1;ChildMenu1[2].MenuCount=3;ChildMenu1[2].DisplayString=&Menu_word[2][0];ChildMenu1[2].subs=NULL;ChildMenu1[2].Local_x=43;ChildMenu1[2].Local_y=0;ChildMenu1[2].ChildrenMenu=&SubChildMenu3;ChildMenu1[2].ParentMenu=MainMenu;ChildMenu1[2].This=ChildMenu1;}void ChildMenu2_init(void){ChildMenu2[0].MenuCount=3;ChildMenu2[0].DisplayString=&Menu_word[0][0];ChildMenu2[0].subs=NULL;ChildMenu2[0].Local_x=43;ChildMenu2[0].Local_y=16;ChildMenu2[0].ChildrenMenu=&SubChildMenu1;ChildMenu2[0].ParentMenu=MainMenu;ChildMenu2[0].This=ChildMenu2;ChildMenu2[1].MenuCount=3;ChildMenu2[1].DisplayString=&Menu_word[1][0];ChildMenu2[1].subs=NULL;ChildMenu2[1].Local_x=43;ChildMenu2[1].Local_y=16;ChildMenu2[1].ChildrenMenu=&SubChildMenu2;ChildMenu2[1].ParentMenu=MainMenu;ChildMenu2[1].This=ChildMenu2;ChildMenu2[2].MenuCount=3;ChildMenu2[2].DisplayString=&Menu_word[2][0];ChildMenu2[2].subs=NULL;ChildMenu2[2].Local_x=43;ChildMenu2[2].Local_y=16;ChildMenu2[2].ChildrenMenu=&SubChildMenu3;ChildMenu2[2].ParentMenu=MainMenu;ChildMenu2[2].This=ChildMenu2;}void ChildMenu3_init(void){ChildMenu3[0].MenuCount=3;ChildMenu3[0].DisplayString=&Menu_word[0][0];ChildMenu3[0].subs=NULL;ChildMenu3[0].Local_x=43;ChildMenu3[0].Local_y=0;ChildMenu3[0].ChildrenMenu=&SubChildMenu1;ChildMenu3[0].ParentMenu=MainMenu;ChildMenu3[0].This=ChildMenu3;ChildMenu3[1].MenuCount=3;ChildMenu3[1].DisplayString=&Menu_word[1][0];ChildMenu3[1].subs=NULL;ChildMenu3[1].Local_x=43;ChildMenu3[1].Local_y=0;ChildMenu3[1].ChildrenMenu=&SubChildMenu2;ChildMenu3[1].ParentMenu=MainMenu;ChildMenu3[1].This=ChildMenu3;ChildMenu3[2].MenuCount=3;ChildMenu3[2].DisplayString=&Menu_word[2][0];ChildMenu3[2].subs=NULL;ChildMenu3[2].Local_x=43;ChildMenu3[2].Local_y=0;ChildMenu3[2].ChildrenMenu=&SubChildMenu3;ChildMenu3[2].ParentMenu=MainMenu;ChildMenu3[2].This=ChildMenu3;}void ChildMenu4_init(void){ChildMenu4[0].MenuCount=3;ChildMenu4[0].DisplayString=&Menu_word[0][0];ChildMenu4[0].subs=NULL;ChildMenu4[0].Local_x=43;ChildMenu4[0].Local_y=16;ChildMenu4[0].ChildrenMenu=&SubChildMenu1;ChildMenu4[0].ParentMenu=MainMenu;ChildMenu4[0].This=ChildMenu4;ChildMenu4[1].MenuCount=3;ChildMenu4[1].DisplayString=&Menu_word[1][0];ChildMenu4[1].subs=NULL;ChildMenu4[1].Local_x=43;ChildMenu4[1].Local_y=16;ChildMenu4[1].ChildrenMenu=&SubChildMenu2;ChildMenu4[1].ParentMenu=MainMenu;ChildMenu4[1].This=ChildMenu4;ChildMenu4[2].MenuCount=3;ChildMenu4[2].DisplayString=&Menu_word[2][0];ChildMenu4[2].subs=NULL;ChildMenu4[2].Local_x=43;ChildMenu4[2].Local_y=16;ChildMenu4[2].ChildrenMenu=&SubChildMenu3;ChildMenu4[2].ParentMenu=MainMenu;ChildMenu4[2].This=ChildMenu4;}void SubChildMenu1_init(void){SubChildMenu1.MenuCount=1;SubChildMenu1.DisplayString=&Menu_word[0][0];SubChildMenu1.subs=NULL;SubChildMenu1.Local_x=79;SubChildMenu1.Local_y=0;SubChildMenu1.ChildrenMenu=NULL;SubChildMenu1.ParentMenu=ChildMenu1;SubChildMenu1.This=&SubChildMenu1;SubChildMenu2.MenuCount=1;SubChildMenu2.DisplayString=&Menu_word[0][0];SubChildMenu2.subs=NULL;SubChildMenu2.Local_x=79;SubChildMenu2.Local_y=16;SubChildMenu2.ChildrenMenu=NULL;SubChildMenu2.ParentMenu=ChildMenu1;SubChildMenu2.This=&SubChildMenu2;SubChildMenu3.MenuCount=1;SubChildMenu3.DisplayString=&Menu_word[0][0];SubChildMenu3.subs=NULL;SubChildMenu3.Local_x=79;SubChildMenu3.Local_y=32;SubChildMenu3.ChildrenMenu=NULL;SubChildMenu3.ParentMenu=ChildMenu1;SubChildMenu3.This=&SubChildMenu3;}/*****************键盘*******************/ UINT8 keyscan(void){UINT8 i,j,temp;PTFD|=0x07; //PTF xxxx x111for(i=0;i<3;i++){PTFD &= ~(1<<i);temp=0x04;for(j=0;j<3;j++){if(!(PTGD&temp)){delay(10);if(!(PTGD&temp)){return (i*3+j+1);}}temp <<= 1;}PTFD|=0x07;}return 0;}/****************读状态*******************/UINT8 _12864_rd_stat(void){UINT8 volatile temp;PTBDD=0X00;D_RS=0;D_RW=1;D_E=1;delay(1);temp=PTBD;delay(1);D_E=0;return temp;}/*******************读数据******************/UINT8 _12864_rd_data(UINT8 page,UINT8 colum,UINT8 D_LorR) {UINT8 volatile data;_12864_busycheck();if(D_LorR){D_L=0;D_R=1;}else{D_L=1;D_R=0;}_12864_wr_cmd(0xb8+page);_12864_wr_cmd(0x40+colum);PTBDD=0X00;D_RS=1;D_RW=1;D_E=1;delay(5);data=PTBD;delay(10);D_E=0;return data;}/*******************忙检测**********************/void _12864_busycheck(void){PTBDD=0x00;D_RS=0;D_RW=1;D_E=1;while(_12864_rd_stat()==0x80);D_E=0;}/****************写指令********************/void _12864_wr_cmd(UINT8 cmd){_12864_busycheck();PTBDD=0XFF;D_RS=0;D_RW=0;D_E=1;delay(10);PTBD=cmd;delay(10);D_E=0;}/*****************写数据*****************/void _12864_wr_data(UINT8 page,UINT8 colum,UINT8 D_LorR,UINT8 data) {_12864_busycheck();if(D_LorR){D_L=0;D_R=1;}else{D_L=1;D_R=0;}_12864_wr_cmd(0xb8+page);_12864_wr_cmd(0x40+colum);PTBDD=0XFF;D_RS=1;D_RW=0;D_E=1;delay(5);PTBD=data;delay(10);D_E=0;}void _12864_wr_data_notclear(UINT8 page,UINT8 colum,UINT8 D_LorR,UINT8 data) {UINT8 temp;_12864_busycheck();if(D_LorR){D_L=0;D_R=1;}else{D_L=1;D_R=0;}(void)_12864_rd_data(page,colum,D_LorR);temp=_12864_rd_data(page,colum,D_LorR);data=data|temp;_12864_wr_cmd(0xb8+page);_12864_wr_cmd(0x40+colum);PTBDD=0XFF;D_RS=1;D_RW=0;D_E=1;delay(5);PTBD=data;delay(10);D_E=0;}/*****************清屏********************/void _12864_clear_lcdall(void){UINT8 i,j;for(i=0;i<8;i++){for(j=0;j<64;j++){_12864_wr_data(i,j,0,0x00);_12864_wr_data(i,j,1,0x00);}}}void _12864_clear_lcd(UINT8 xbegin,UINT8 ybegin,UINT8 xend,UINT8 yend) {UINT8 x,y,pages,pagee,D_LorR,temp;if(xbegin>=xend){temp=xbegin;xbegin=xend;xend=temp;}if(ybegin>=yend){temp=ybegin;ybegin=yend;yend=temp;}if(xend>127)xend=127;if(yend>63)yend=63;pages=ybegin>>3;pagee=yend>>3;for(x=pages;x<=pagee;x++){for(y=xbegin;y<=xend;y++){if(y>63){D_LorR=1;_12864_wr_data(x,y-64,D_LorR,0x00);}else{D_LorR=0;_12864_wr_data(x,y,D_LorR,0x00);}}}}/*****************清除一个点******************/void _12864_clear_dot(UINT8 x,UINT8 y){UINT8 page,row;UINT8 data;if(x<=63){page=y/8;row=y%8;(void)_12864_rd_data(page,x,0);data=_12864_rd_data(page,x,0);data=data&(~(0x01<<row));_12864_wr_data(page,x,0,data);}else{page=y/8;row=y%8;(void)_12864_rd_data(page,x-64,1);data=_12864_rd_data(page,x-64,1);data=data&(~(0x01<<row));_12864_wr_data(page,x-64,1,data);}}/**********************画一个点*********************/ void _12864_write_dot(UINT8 x,UINT8 y){UINT8 page,row;volatile UINT8 data;if(x<=63){page=y/8;row=y%8;delay(5);(void)_12864_rd_data(page,x,0);data=_12864_rd_data(page,x,0);data=data|(0x01<<row);_12864_wr_data(page,x,0,data);}else{page=y/8;row=y%8;delay(5);(void)_12864_rd_data(page,x-64,1);data=_12864_rd_data(page,x-64,1);data=data|(0x01<<row);_12864_wr_data(page,x-64,1,data);}}/*****************初始化*********************/void _12864_init(void){D_REST=1;D_L=1;D_R=1;_12864_wr_cmd(0xc0);_12864_wr_cmd(0x3f);}/******************io封装*****************/void io_keyscan(void){PTGPE=0x1c;PTFDD=0xff;}void io_12864(void){PTBDD=0XFF;PTCDD_PTCDD0=1;PTCDD_PTCDD1=1;PTCDD_PTCDD2=1;PTCDD_PTCDD4=1;PTFDD_PTFDD4=1;PTFDD_PTFDD5=1;}/******************画线函数****************/void _12864_glibline(UINT8 x1,UINT8 y1,UINT8 x2,UINT8 y2){int dx,dy,sub;dx=x2-x1;dy=y2-y1;if(dx>=0){if(dy>=0){if(dx>=dy)//1/8{sub=2*dy-dx;while(x1<x2){_12864_write_dot(x1,y1);if(sub>0){y1+=1;sub+=(dy-dx)*2;}else{sub+=2*dy;}x1+=1;}}else //2/8{sub=2*dx-dy;while(y1<y2){_12864_write_dot(x1,y1);if(sub>0){x1+=1;sub+=(dx-dy)*2;}else{sub+=2*dx;}y1+=1;}}}else{dy=-dy;if(dx>=dy){sub=2*dy-dx;while(x1<x2){_12864_write_dot(x1,y1);if(sub>0){y1-=1;sub+=(dy-dx)*2;}else{sub+=2*dy;}x1+=1;}}else{sub=2*dx-dy;while(y1>y2){_12864_write_dot(x1,y1);if(sub>0){x1+=1;sub+=(dx-dy)*2;}else{sub+=dx*2;}y1-=1;}}}}else{dx=-dx;if(dy>0){if(dx>dy){sub=2*dy-dx;while(x1>x2){_12864_write_dot(x1,y1);if(sub>0){y1+=1;sub+=(dy-dx)*2;}else{sub+=2*dy;}x1-=1;}}else{sub=2*dx-dy;while(y1<y2){_12864_write_dot(x1,y1);if(sub>0){x1-=1;sub+=(dx-dy)*2;}else{sub+=dx*2;}y1+=1;}}}else{dy=-dy;if(dx>dy){sub=2*dy-dx;while(x1>x2){_12864_write_dot(x1,y1);if(sub>0){y1-=1;sub+=(dy-dx)*2;}else{sub+=dy*2;}}}else{sub=2*dx-dy;while(y1>y2){_12864_write_dot(x1,y1);if(sub>0){x1-=1;sub+=(dx-dy)*2;}else{sub+=2*dx;}y1-=1;}}}}}/********************写16*16点阵的汉字函数*********************///参数page汉字开始的页数,colum汉字开始的列数//字符代码编号//CorN是否是带擦除的写入方式1为不擦除,0为擦除void write_word_16_16(UINT8 page,UINT8 colum,UINT8 word_num,UINT8 CorN,UINT8 filltype){UINT8 i,D_LorR,colum_temp;if(filltype==FillType_Fill){if(CorN==1){for(i=0;i<8;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data_notclear(page,colum_temp,D_LorR,zimo[word_num][i]);}for(i=16;i<24;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data_notclear(page+1,colum_temp,D_LorR,zimo[word_num][i]);}for(i=8;i<16;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data_notclear(page,colum_temp,D_LorR,zimo[word_num][i]);}for(i=24;i<32;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data_notclear(page+1,colum_temp,D_LorR,zimo[word_num][i]);}}else{for(i=0;i<8;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data(page,colum_temp,D_LorR,zimo[word_num][i]);}for(i=16;i<24;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data(page+1,colum_temp,D_LorR,zimo[word_num][i]);}for(i=8;i<16;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data(page,colum_temp,D_LorR,zimo[word_num][i]);}for(i=24;i<32;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data(page+1,colum_temp,D_LorR,zimo[word_num][i]);}}}else{if(CorN==1){for(i=0;i<8;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data_notclear(page,colum_temp,D_LorR,~zimo[word_num][i]);}for(i=16;i<24;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data_notclear(page+1,colum_temp,D_LorR,~zimo[word_num][i]);}for(i=8;i<16;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data_notclear(page,colum_temp,D_LorR,~zimo[word_num][i]);}for(i=24;i<32;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data_notclear(page+1,colum_temp,D_LorR,~zimo[word_num][i]);}}else{for(i=0;i<8;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data(page,colum_temp,D_LorR,~zimo[word_num][i]);}for(i=16;i<24;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data(page+1,colum_temp,D_LorR,~zimo[word_num][i]);}for(i=8;i<16;i++){D_LorR=0;colum_temp=colum+i;if((colum+i)>63){colum_temp=colum-64+i;D_LorR=1;}_12864_wr_data(page,colum_temp,D_LorR,~zimo[word_num][i]);}for(i=24;i<32;i++){D_LorR=0;colum_temp=colum+i-16;if((colum+i-16)>63){colum_temp=colum-64+i-16;D_LorR=1;}_12864_wr_data(page+1,colum_temp,D_LorR,~zimo[word_num][i]);}}}}/********************编写16*16点阵字符串显示函数******************************/ //参数string是字符编号数组的首地址void write_string_16_16(UINT8 page,UINT8 colum,UINT8 *string,UINT8 number,UINT8 CorN,UINT8 filltype){UINT8 i;for(i=0;i<number;i++){write_word_16_16(page,colum+(i<<4),*(string+i),CorN,filltype);}}/****************************************************************************** ******//*************************填充函数****************************/void fill_rectangle(UINT8 xbegin,UINT8 ybegin,UINT8 xend,UINT8 yend){UINT8 x;for(x=xbegin;x<=xend;x++){_12864_glibline(x,ybegin,x,yend);}}/*******************菜单函数*******************///功能:编译出一个菜单可视化图形界面//具有填充,反相功能//struct MenuItem//{ //菜单结构// UINT8 MenuCount;//菜单项所在层的菜单项数目// UINT8 *DisplayString;//显示的名称// void (*subs)(void);//所指向的功能函数// struct MenuItem *ChildrenMenu;//所指向的子菜单// struct MenuItem *ParentMenu;//所指向的父菜单//};void MenuBox(UINT8 xbegin,UINT8 ybegin)/*Xbegin 方框左上角横坐标Ybegin 方框左上角纵坐标Xend 方框右下角横坐标Y end 方框右下角纵坐标*/{UINT8 page,num,xend,yend,count_temp;struct MenuItem *Menu_point_temp;Menu_point_temp=Menu_point;xend=xbegin+16*3;yend=ybegin+Menu_point->MenuCount*16-1;if(yend>63)yend=63;Menu_point=Menu_point->This;//指向本项菜单的首位地址page=ybegin>>3;_12864_clear_lcd(xbegin,ybegin,xend,yend);_12864_glibline(xbegin,ybegin,xend,ybegin);_12864_glibline(xbegin,ybegin,xbegin,yend);_12864_glibline(xbegin,yend,xend,yend);_12864_glibline(xend,ybegin,xend,yend);count_temp=Menu_point->MenuCount;for(num=0;num<count_temp;num++){if(page>7)continue;if(Menu_point==Menu_point_temp){if(key_number!=0){write_string_16_16(page,xbegin,Menu_point->DisplayString,3,1,0);}else{write_string_16_16(page,xbegin,Menu_point->DisplayString,3,1,1);}}else{write_string_16_16(page,xbegin,Menu_point->DisplayString,3,1,1);}Menu_point++;page+=2;}Menu_point=Menu_point_temp;}/******************主函数*******************/void main(void){PLL_init(16);io_12864();io_keyscan();_12864_init();_12864_clear_lcdall();MainMenu_init();ChildMenu1_init();ChildMenu2_init();ChildMenu3_init();ChildMenu4_init();SubChildMenu1_init();/* _12864_glibline(0,0,0,63);_12864_glibline(0,0,63,0);_12864_glibline(63,0,63,63);_12864_glibline(0,63,63,63);write_word_16_16(1,60,1,0,0); */Menu_point=Menu_table[key_number].Menu_pointer;MenuBox(Menu_point->Local_x,Menu_point->Local_y);// MenuBox(65,16);// write_string_16_16(0,40,Menu_point->DisplayString,3,0,0);// write_string_16_16(2,40,&Menu_word[0][0],3,0,0);for(;;){switch(keyscan()){case 1: //DOWM下翻页key_number=Menu_table[key_number].down_stat;Menu_point=Menu_table[key_number].Menu_pointer;MenuBox(Menu_point->Local_x,Menu_point->Local_y);break;case 6: //UPkey_number=Menu_table[key_number].up_stat;Menu_point=Menu_table[key_number].Menu_pointer;MenuBox(Menu_point->Local_x,Menu_point->Local_y);break;case 5://enterif(Menu_point->ChildrenMenu!=NULL){key_number=Menu_table[key_number].enter_stat;Menu_point=Menu_table[key_number].Menu_pointer;MenuBox(Menu_point->Local_x,Menu_point->Local_y);}else if(Menu_point->subs!=NULL){(*Menu_point->subs)();}break;case 9://escif(Menu_point->ParentMenu!=NULL){_12864_clear_lcd(Menu_point->Local_x,Menu_point->Local_y,(Menu_point->Local_x+16*3),(Menu_point->Local_y+16*Menu_point->MenuCount-1));key_number=Menu_table[key_number].esc_stat;Menu_point=Menu_table[key_number].Menu_pointer;MenuBox(Menu_point->Local_x,Menu_point->Local_y);}break;}}}。
stm32-12864液晶-菜单设计
/*************menu.h*******************/#ifndef __MENU_H#define __MENU_H#include "stm32f10x.h"#include "SysTick.h"#include <stdlib.h>#include "12864.h"#include "AdcDisplay.h"#include "key.h"#include "spi_tm7705.h"#include "eeprom.h"typedef struct menu//定义一个菜单{u8 range_from,range_to; //当前显示的项开始及结束序号u8 itemCount;//项目总数u8 selected;//当前选择项u8 *menuItems[17];//菜单项目struct menu **subMenus;//子菜单struct menu *parent;//上级菜单,如果是顶级则为null void (**func)();//选择相应项按确定键后执行的函数}Menu;void MainDisplay(void);void DisplayMenu(u8 line);void func(void);void Unitch1(void);void Unitch2(void);void Unitch3(void);void Unitch4(void);void DiaChange(void);void MlChange(void);u16 NumLoop(u16 num,u8 pm);u8 Change(u8 Sval,uint8_t* title);void MenuInit(void);#endif /* __MENU_H *//*************menu.h*******************//************menu.c*******************//******************** ********************* 文件名:menu.c* 描述:液晶菜单函数库* 实验平台:* 硬件连接----------------------------**** ----------------------------* 库版本:ST3.0.0******************************************************************************** ***/#include "menu.h"//菜单与AD结果显示变量,0为AD,1为菜单extern u8 MenuDis=0;//typedef struct menu//定义一个菜单//{// u8 range_from,range_to; //当前显示的项开始及结束序号// u8 itemCount;//项目总数// u8 selected;//当前选择项// u8 *menuItems[17];//菜单项目// struct menu **subMenus;//子菜单// struct menu *parent;//上级菜单,如果是顶级则为null// void (**func)();//选择相应项按确定键后执行的函数////}Menu;Menu MainMenu = { //定义主菜单0,3,4,0,//默认显示0-3项,总共4项,当前选择第0项{"单位设置\x10","直径设置\x10","模量设置\x10","关于"}};Menu UnitMenu = {//单位设置菜单0,3,4,0,{"应变量ε","锁模力KN ","锁模力Ton","取消"}};u8 UnitCh;//单位选择,0为变形量ε,1为应变量σ,2为锁模力FMenu DiaMenu = {//单位设置菜单0,0,1,0,{"主999 mm"}};Menu MlMenu = {//模量设置菜单0,0,1,0,{"主999 KN/mm2"}};u8 DiaVal;//直径数值u8 MlVal;//模量数值//菜单与AD结果显示变量,0为AD,1为菜单u8 MenuDis;//复位前指数u16 BaseAD[4];//横截面积u16 mianji;//横截直径u16 zhijing;//模量u16 moliang;//按键返回值u8 keyval;uint8_t* title1="单位:MM";uint8_t* title2="单位:KN/MM2";extern u16 ADResult[4];//存储AD结果的数组extern uint16_t VirtAddVarTab[NumbOfVar];//eepromMenu *currentMenu;//当前的菜单void MainDisplay(void){if (MenuDis==0)AdUi();keyval=KeyScan();switch(keyval){case 0://什么都不干{Delay_ms(50);break;}case 1://向上{if(MenuDis==1){if(currentMenu->selected == 0)//到了第一项break;else{currentMenu->selected--;DisplayMenu(currentMenu->selected);}}break;}case 2://向下{if(MenuDis==1){if(currentMenu->selected == currentMenu->itemCount-1)break;else{currentMenu->selected++;DisplayMenu(currentMenu->selected);}}break;}case 3://确认{if(MenuDis==0){MenuDis=1;LCD_Init();DisplayMenu(currentMenu->selected);}else{if(currentMenu->subMenus[currentMenu->selected] !=NULL){LCD_Init();currentMenu = currentMenu->subMenus[currentMenu->selected];DisplayMenu(currentMenu->selected);}else{if(currentMenu->func[currentMenu->selected] != NULL){LCD_Init();currentMenu->func[currentMenu->selected]();//执行相应的函数currentMenu->selected=0;DisplayMenu(currentMenu->selected);//返回后恢复原来的菜单状态}}}break;}case 4://取消{if(MenuDis==1){if(currentMenu->parent!=NULL)//父菜单不为空,将显示父菜单{LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected);}else{MenuDis=0;//currentMenu = MainMenu;currentMenu->selected=0;LCD_Init();AdUi();Delay_ms(100);}}else{Clr_Scr();Delay_ms(50);Write_Char(0,0x30);//关闭扩展指令//复位归零BaseAD[0]=ADResult[0];BaseAD[1]=ADResult[1];BaseAD[2]=ADResult[2];BaseAD[3]=ADResult[3];AdUi();}break;}default:break;}}//用于显示菜单项void DisplayMenu(u8 line) //显示菜单项并设置选中的项反白{int i;line = 3-(currentMenu->range_to-line);for(i = 0;i<4;i++){LCD_Write_String(i,0,currentMenu->menuItems[i+currentMenu->range_from]); }WhiteLineInit();White_Line(line,0,8);//反白显示指定行}void func(void){uint8_t* s="为人民服务";LCD_Write_String(1,0,s);Delay_ms(3000);}void Unitch1(void){UnitCh=0;LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void Unitch2(void){UnitCh=1;LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void Unitch3(void){UnitCh=2;LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void Unitch4(void){LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void DiaChange(void){uint8_t* s="单位:MM";//测试代码u16 a=0;int i=0;//u16 tmp1;LCD_Init();LCD_Write_String(0,0,s);zhijing=Change(zhijing,title1);mianji=3.14*((zhijing/2)*(zhijing/2));EE_WriteVariable(VirtAddVarTab[0], zhijing);//测试代码//for(i=0;i<99;i++)//{//a=a+1;//LCD_Write_Tri_Value(2,3,a);//Delay_ms(50);//}}void MlChange(void){uint8_t* s="单位:KN/MM2";LCD_Init();LCD_Write_String(0,0,s);moliang=Change(moliang,title2);EE_WriteVariable(VirtAddVarTab[1], moliang);}//数字按键循环,升到9后变0,降到0后变9,参数pm为加减,1为+,0为减u16 NumLoop(u16 num,u8 pm){if (pm==1){if (num>=9)num=0;elsenum=num+1;}else{if (num<=0)num=9;elsenum=num-1;}return num;}//Sval代表直径或模量的默认值,返回修改后直径或模量的值u8 Change(u8 Sval,uint8_t* title){u16 baiwei,shiwei,gewei,Dval;//数字ascii码//char tmpval;//按键返回值u8 keyval=0;//光标位置3为百位、4为十位,5为个位u8 loc=3;//是否选中其中一位u8 clicked=0;//光标闪烁位,是否闪烁u8 flicker=0;baiwei=(u16)(Sval/100);shiwei=(u16)((Sval%100)/10);gewei=(u16)((Sval%100)%10);//tmpval=(char)baiwei + 0x30;//LCD_Write_Char(2,3,tmpval);//tmpval=(char)shiwei + 0x30;//LCD_Write_Char(2,4,tmpval);//tmpval=(char)gewei + 0x30;//LCD_Write_Char(2,5,tmpval);//LCD_Write_Single_Num(2,3,baiwei);//LCD_Write_Single_Num(2,4,shiwei);//LCD_Write_Single_Num(2,5,gewei);LCD_Write_Tri_Value(2,3,Sval);WhiteLineInit();White_Line(2,3,1);//反白显示指定行while(1){keyval=KeyScan();switch(keyval){case 0://什么都不干{if (clicked){if (flicker==0){White_Line(2,loc,1);flicker=1;}else{Shut_White_Line(2,loc,1);flicker=0;}}//else//White_Line(2,loc,1);Delay_ms(300);break;}case 1://向上{if (clicked==0){if (loc>3)loc=loc-1;elseloc=3;WhiteLineInit();White_Line(2,loc,1);}else{switch (loc){case 3:{baiwei=NumLoop(baiwei,1);LCD_Init();break;}case 4:{shiwei=NumLoop(shiwei,1);LCD_Init();break;}case 5:{gewei=NumLoop(gewei,1);LCD_Init();break;}default:break;}}break;}case 2://向下{if (clicked==0){if (loc<5)loc=loc+1;elseloc=5;WhiteLineInit();White_Line(2,loc,1);}else{switch (loc){case 3:{baiwei=NumLoop(baiwei,0);LCD_Init();break;}case 4:{shiwei=NumLoop(shiwei,0);LCD_Init();break;}case 5:{gewei=NumLoop(gewei,0);LCD_Init();break;}default:break;}}break;}case 3://确认{if (clicked)clicked=0;elseclicked=1;break;}case 4://取消{if (clicked)clicked=0;else //返回主菜单{LCD_Init();currentMenu = &MainMenu;currentMenu->selected=0;DisplayMenu(currentMenu->selected);//返回新的数值Dval=baiwei*100+shiwei*10+gewei;return Dval;}break;}default:break;}//LCD_Init();LCD_Write_String(0,0,title);Dval=baiwei*100+shiwei*10+gewei;LCD_Write_Tri_Value(2,3,Dval);Delay_ms(20);}}//初始化菜单:void MenuInit(void){MainMenu.subMenus = malloc(sizeof(&MainMenu)*4);MainMenu.subMenus[0] = &UnitMenu;//第1项没有子菜单置null,选择后程序会调用func中相应项中的函数MainMenu.subMenus[1] = NULL;//&DiaMenu;直接执行设置函数MainMenu.subMenus[2] = NULL;//&MlMenu;直接执行设置函数MainMenu.subMenus[3] = NULL;MainMenu.func = malloc(sizeof(&func)*4);MainMenu.func[0] = &func;MainMenu.func[1] = &DiaChange;MainMenu.func[2] = &MlChange;//当选择了并按了确定,会执行func函数MainMenu.func[3] = NULL;MainMenu.parent = NULL;//表示是顶级菜单UnitMenu.subMenus = malloc(sizeof(&UnitMenu)*4);UnitMenu.subMenus[0] = NULL;UnitMenu.subMenus[1] = NULL;UnitMenu.subMenus[2]= NULL;UnitMenu.subMenus[3]= NULL;UnitMenu.func = malloc(sizeof(&Unitch1)*4);UnitMenu.func[0] = &Unitch1;UnitMenu.func[1] = &Unitch2;UnitMenu.func[2] = &Unitch3;UnitMenu.func[3] = &Unitch4;UnitMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单项// DiaMenu.subMenus = malloc(sizeof(&DiaMenu)*1);// DiaMenu.subMenus[0] = NULL;// DiaMenu.func = malloc(sizeof(&func)*1);// DiaMenu.func[0] = &func;// DiaMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单项//// MlMenu.subMenus = malloc(sizeof(&MlMenu)*1);// MlMenu.subMenus[0] = NULL;// MlMenu.func = malloc(sizeof(&func)*1);// MlMenu.func[0] = &func;// MlMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单项currentMenu = &MainMenu;}/************menu.c*******************/。
12864汉字液晶显示--按键电子时钟程序(具有闪烁,移位,加一,减一功能)
//12864汉字液晶显示--按键电子时钟程序(具有闪烁,移位,加一,减一功能)#include <reg52.h>#include <intrins.h>#define uchar unsigned charvoid lcd_ini();void ascii_change(void);void delay();void wri_add(uchar com);void wri_dat(uchar com1);void shan(void);void disp();void tkey(void);sbit cs=P1^7;sbit sid=P1^6;sbit sclk=P1^5;bit flag=1;uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态uchar data clock[3]={23,45,12};uchar code clockname[10]={"北京时间:"};uchar data num[6];/*******主程序*************/void main(){lcd_ini();count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒TMOD=0x01;TL0=0XB0;TH0=0X3C;EA=1;ET0=1;IT0=1;EX0=1;TR0=1;while(1){back:ascii_change();disp();delay();if(flag==1)goto back;tkey();shan();delay();}}/****lcd初始化*******/void lcd_ini(){wri_add(0x30);delay();wri_add(0x0c);delay();wri_add(0x01);delay();wri_add(0x06);delay();}/********定时程序*************/ void timer1() interrupt 1 using 2 {TL0=0XB0;TH0=0X3C;count--;if(count==0){count=10;clock[2]++;//秒//}elsegoto out;if(clock[2]==60){clock[2]=0;clock[1]++;//分//}if(clock[1]==60){clock[1]=0;clock[0]++;}if(clock[0]==24)//时//clock[0]=0;out:_nop_();}/*******十位个位转换成ASCII码************/ void ascii_change(void){num[5]=clock[2]-(clock[2]/10)*10+0x30;num[4]=clock[2]/10+0x30;num[3]=clock[1]-(clock[1]/10)*10+0x30;num[2]=clock[1]/10+0x30;num[1]=clock[0]-(clock[0]/10)*10+0x30;num[0]=clock[0]/10+0x30;}/********廷时程序*************/void delay(){uchar i,j;for (i=250;i>0;i--)for (j=250;j>0;j--);}/*****Write address*********/void wri_add(uchar com){uchar i,j,k;cs=0;cs=1;dat=0xf8;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/*********Write data*************/ void wri_dat(uchar com1){uchar i,j,k;cs=0;cs=1;dat=0xfa;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/******display program***********/ void disp(){uchar i,k=0;wri_add(0x80);for (i=1;i<=9;i++)wri_dat(clockname[i-1]);wri_add(0x90);for (i=1;i<=6;i++) {k++;if(k==3||k==5)wri_dat(clockname[8]);//时间之间的冒号。
12864+键盘按键控制
LCD12864_data=dat; DelayMs(5); LCD12864_E=1; DelayMs(5); LCD12864_E=0; } //------设定显示位置-----------void set_LCD12864_pos(uchar x,uchar y) { uchar pos; if(x==0) x=0x80; if(x==1) x=0x90; if(x==2) x=0x88; if(x==3) x=0x98; pos=x+y; write_12864cmd(pos); //地址 } //------------写字符串---------------void write_12864str(uchar *s) { while(*s) {
#endif
Lcd12864.h #ifndef __LCD12864_H__ #define __LCD12864_H__ #include"keyboard.h" #define uchar unsigned char #define uint unsigned int //-----端口定义-----------#define LCD12864_data P0 sbit LCD12864_RS =P2^4; sbit LCD12864_RW =P2^5; sbit LCD12864_E = P2^6; sbit LCD12864_PSB=P2^1; sbit LCD12864_RES=P2^3; //------------------------//extern void delay_1ms(uint x); extern void set_LCD12864_pos(uchar x,uchar y);//x 确定行,y 确定起始位置 extern void LCD12864_init(); extern void write_12864cmd(uchar cmd);
12864点阵液晶显示器指令
10、写显示数据
CODE:R/WD/IDB7 DB6 DB5DB4DB3 DB2 DB1DB0
L
H
D7
D6
D5
D4
D3
D2
D1
D0
功能:写数据到DD RAM,DD RAM是存储图形显示数据的,写指令执行后Y地址计数器自动加1。D7-D0位数据为1表示显示,数据为0表示不显示。写数据到DD RAM前,要先执行“设置页地址”及“设置列地址”命令。
备注:ST7920控制器的128×64点阵液晶其实原理上等同256×32点阵,第三行对应的DDRAM地址紧接第一行;第四行对应的DDRAM地址紧接第二行。用户在使用行反白功能时,如果第一行反白,第三行必然反白。第二行反白,第四行必然反白。这是正常现象。
9、状态检测忙标志位(StatusBusy 1<<7)
基本指令
1、清除显示(DispClear0x01)
CODE:RSR/WDB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
L
L
L
L
L
L
L
L
L
H
功能:将DDRAM填满“20H”(空格)代码,并且设定DDRAM的地址计数器(AC)为
00H;更新设置进入设定点将I/D设为1,游标右移AC加1。
2、地址归0(HOME0x20)
绘图RAM(GDRAM)
绘图显示RAM提供64×32个位元组的记忆空间,最多可以控制256×64点的二维绘图缓冲空间,在更改绘图RAM时,先连续写入水平与垂直的坐标值,再写入两个8位元的资料到绘图RAM,
而地址计数器(AC)会自动加一;在写入绘图RAM的期间,绘图显示必须关闭,整个写入绘图RAM
12864液晶多级菜单设计
12864液晶打点程序
#include "reg52.h"#include "intrins.h"sbit io_LCD12864_RS = P2^5 ;sbit io_LCD12864_RW = P2^6 ;sbit io_LCD12864_EN = P2^7 ;sbit A=P3^7;#define io_LCD12864_DATAPORT P0#define SET_DATA io_LCD12864_RS = 1 ;#define SET_INC io_LCD12864_RS = 0 ;#define SET_READ io_LCD12864_RW = 1 ;#define SET_WRITE io_LCD12864_RW = 0 ;#define SET_EN io_LCD12864_EN = 1 ;#define CLR_EN io_LCD12864_EN = 0 ;void v_Lcd12864CheckBusy_f( void ) //忙检测函数{unsigned int nTimeOut = 0 ;SET_INCSET_READCLR_ENSET_ENwhile( ( io_LCD12864_DATAPORT & 0x80 ) && ( ++nTimeOut != 0 ) ) ;CLR_ENSET_INCSET_READ}void v_Lcd12864SendCmd_f( unsigned char byCmd ) //发送命令{v_Lcd12864CheckBusy_f() ;SET_INCSET_WRITECLR_ENio_LCD12864_DA TAPORT = byCmd ;_nop_();_nop_();SET_EN_nop_();_nop_();CLR_ENSET_READSET_INC}void v_Lcd12864SendData_f( unsigned char byData ) //发送数据{v_Lcd12864CheckBusy_f() ;SET_DATASET_WRITECLR_ENio_LCD12864_DA TAPORT = byData ;_nop_();_nop_();SET_EN_nop_();_nop_();CLR_ENSET_READSET_INC}void v_DelayMs_f( unsigned int nDelay )//延时{unsigned int i ;for( ; nDelay > 0 ; nDelay-- ){for( i = 125 ; i > 0 ; i-- ) ;}}void v_Lcd12864Init_f( void )//初始化{v_Lcd12864SendCmd_f( 0x30 ) ;//基本指令集v_DelayMs_f( 50 ) ;v_Lcd12864SendCmd_f( 0x01 ) ;//清屏v_DelayMs_f( 50 ) ;v_Lcd12864SendCmd_f( 0x06 ) ;//光标右移v_DelayMs_f( 50 ) ;v_Lcd12864SendCmd_f( 0x0c ) ;//开显示}unsigned char u8_Lcd12864ReadByte_f( void ) {unsigned char byReturnValue ;v_Lcd12864CheckBusy_f() ;io_LCD12864_DA TAPORT = 0xff ;SET_DATASET_READCLR_ENSET_ENbyReturnValue = io_LCD12864_DATAPORT ;CLR_ENreturn byReturnValue ;}void v_Lcd12864DrawPoint_f( unsigned char X, unsigned char Y, unsigned char Color ) {unsigned char Row , Tier , Tier_bit ;unsigned char ReadOldH, ReadOldL ;v_Lcd12864SendCmd_f( 0x34 ) ;v_Lcd12864SendCmd_f( 0x36 ) ;Tier = X >> 4 ;Tier_bit = X & 0x0f ;if( Y < 32 ){Row = Y ;}else{Row = Y - 32 ;Tier += 8 ;}v_Lcd12864SendCmd_f( Row + 0x80 ) ;v_Lcd12864SendCmd_f( Tier + 0x80 ) ;u8_Lcd12864ReadByte_f() ;ReadOldH = u8_Lcd12864ReadByte_f() ;ReadOldL = u8_Lcd12864ReadByte_f() ;v_Lcd12864SendCmd_f( Row + 0x80 ) ;v_Lcd12864SendCmd_f( Tier + 0x80 ) ;if( Tier_bit < 8 ){switch( Color){case 0 : ReadOldH &=( ~( 0x01 << ( 7 - Tier_bit ))) ; break ;case 1 : ReadOldH |= ( 0x01 << ( 7 - Tier_bit )) ; break ;case 2 : ReadOldH ^= ( 0x01 << ( 7 - Tier_bit )) ; break ;default : break ;}v_Lcd12864SendData_f( ReadOldH ) ;v_Lcd12864SendData_f( ReadOldL ) ;}else{switch(Color){case 0 : ReadOldL &= (~( 0x01 << ( 15 - Tier_bit ))) ; break ;case 1 : ReadOldL |= ( 0x01 << ( 15 - Tier_bit )) ; break ;case 2 : ReadOldL ^= ( 0x01 << ( 15 - Tier_bit )) ; break ;default : break ;}v_Lcd12864SendData_f( ReadOldH ) ;v_Lcd12864SendData_f( ReadOldL ) ;}v_Lcd12864SendCmd_f( 0x30 ) ;}void v_Lcd12864DrawLineX_f( unsigned char X0, unsigned char X1, unsigned char Y, unsigned char Color ){unsigned char Temp ;if( X0 > X1 ){Temp = X1 ;X1 = X0 ;X0 = Temp ;}for( ; X0 <= X1 ; X0++ )v_Lcd12864DrawPoint_f( X0, Y, Color ) ;}//画垂直线:void v_Lcd12864DrawLineY_f( unsigned char X, unsigned char Y0, unsigned char Y1, unsigned char Color ){unsigned char Temp ;if( Y0 > Y1 ){Temp = Y1 ;Y1 = Y0 ;Y0 = Temp ;}for(; Y0 <= Y1 ; Y0++)v_Lcd12864DrawPoint_f( X, Y0, Color);}void gui_clear(){unsigned char i , j , k;v_Lcd12864SendCmd_f(0x34);//扩展指令集,8位数据传输v_Lcd12864SendCmd_f(0x34);//绘图显示关闭for(i = 0; i < 2; i ++)//分上下两屏写{for(j = 0; j < 32; j ++){v_Lcd12864SendCmd_f(0x80 + j);//写y坐标v_DelayMs_f( 1 ) ;if(i == 0) //写x坐标{v_Lcd12864SendCmd_f(0x80);v_DelayMs_f( 1 ) ;}else //写下半屏{v_Lcd12864SendCmd_f(0x88);v_DelayMs_f( 1) ;}for(k = 0; k < 16; k ++)//写一整行数据{v_Lcd12864SendData_f(0x00);//写高字节v_Lcd12864SendData_f(0x00);//写低字节v_DelayMs_f( 1 ) ;}}}v_Lcd12864SendCmd_f(0x36);//打开绘图显示v_Lcd12864SendCmd_f(0x30);//打开基本指令集}void main(){v_Lcd12864Init_f();gui_clear();v_DelayMs_f( 2 ) ;v_Lcd12864DrawPoint_f(15,18,1);// v_Lcd12864DrawPoint_f(16,18,1);// v_Lcd12864DrawPoint_f(17,18,1);// v_Lcd12864DrawPoint_f(18,18,1);// v_Lcd12864DrawLineX_f( 0, 127 , 0, 1 ) ;// v_Lcd12864DrawLineX_f( 0, 127 , 7, 1 ) ;// v_Lcd12864DrawLineX_f( 0, 127 , 15, 1 ) ;// v_Lcd12864DrawLineX_f( 0, 127 , 23, 1 ) ;// v_Lcd12864DrawLineX_f( 0, 127 , 31, 1 ) ;// v_Lcd12864DrawLineX_f( 0, 127 , 39, 1 ) ;// v_Lcd12864DrawLineX_f( 0, 127 , 47, 1 ) ;}。
12864液晶模块程序
#include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define lcddat P0sbit RS=P2^0; //数据/命令选择端:RS=H时,选择数据,RS=L,时,选择命令sbit RW=P2^1; //液晶读写选择端:RW=H时,读,RW=L,时,写sbit EN=P2^2; //液晶使能控制//sbir PSB=P2^3 //串并口方式控制,并口不需要操作,液晶默认的方式是并口,若要使用串口则应在程序中队PSB=0;uchar dis1[]={"2015年06月19日"};void lcd_clear(void);void delayms(uint sj);void write_cmd(uchar cmd);void write_dat(uchar dat);void lcd_pos(uchar x, uchar y);void lcd_init();void print(uchar *str);void show();//********************************//液晶检测忙状态//在写入之前必须执行//********************************void lcd_busy(void){ uchar busy;lcddat=0xff;RS=0;RW=1;EN=1;Delayms(5);busy=lcddat&0x80;while(busy==0x80);EN=0;}//***********************************//填充液晶DDRAM全为空格//**********************************void lcd_clear(void){write_cmd(0x30);write_cmd(0x01);}//*******************************//延时子程序模块//*******************************void delayms(uint sj){ uint i,j;for(j=0;j<sj;j++)for(i=0;i<110;i++);//1ms延时.}//*******************************//写指令条件:RS=0,RW=0,E=高脉冲,D0~D7=指令码//*******************************void write_cmd(uchar cmd){lcd_busy();RS=0;RW=0;EN=0;lcddat=cmd;delayms(5);EN=1;delayms(5);EN=0;}//*******************************//写数据条件:RS=1,RW=0,E=高脉冲,D0~D7=数据//*******************************void write_dat(uchar dat){lcd_busy();RS=1;RW=0;EN=0;lcddat=dat;delayms(5);EN=1;delayms(5);EN=0;}//********************************//指定要显示字符的坐标x:行y:列//*******************************void lcd_pos(uchar x, uchar y){ y=y--;if(x==1)write_cmd(0x80|y);if(x==2)write_cmd(0x90|y);if(x==3)write_cmd((0x80|y)+8);if(x==4)write_cmd((0x90|y)+8);}//*******************************//LCD初始化程序//*******************************void lcd_init(){//PSB=1; //并口方式write_cmd(0x30); //基本功能设定delayms(5);write_cmd(0x0c); //显示开,关光标delayms(5);write_cmd(0x01); //清除LCD的显示内容delayms(5);}//**********************************//液晶显示字符串程序//**********************************void print(uchar *str){while(*str!='\0'){write_dat(*str);str++;}}//*************************************** //液晶显示主程序模块//*************************************** void show(){lcd_pos(1,1);print("液晶显示模块^__^");delayms(1000);lcd_pos(2,5);print("by郭功晓");delayms(1000);lcd_pos(3,2);print(dis1);delayms(1000);}#include <12864bx.h>main(){lcd_init();lcd_clear();show(); //液晶显示数据while(1);}。
12864液晶按键显示
#include<msp430x14x.h>#include "Keypad.h" //键盘扫描#include "Keypad.c"#include "HB12864.h"#include "Uart.H"#define uchar unsigned char#define uint unsigned int#define ulong unsigned longulong temp; //矩阵键盘中间变量//**************************引用外部变量的声明************************** extern unsigned char key_val;extern unsigned char key_Flag;//***************************主函数**************************************void main( void ){WDTCTL = WDTPW + WDTHOLD;//关闭看门狗Uart_Init();//液晶初始化_EINT();Screen_Con(LIGHT_SET);//开背光m1: Screen_Con(SCREEN_CLA);//清屏uchar yi=1; //检测输入的状态//Screen_Cont(CUR_SET,0X00);//关光标Display_StrChar(STR_CHAR,0,4,"液晶键盘测试");//第一排的显示部分Display_StrChar(STR_CHAR,2,0,"键盘输入:");//第三排的显示部分Screen_Cont(CUR_SET,0X0A);//设置光标长度Display_Dot(CUR_LOC_SET,47,72);//设置光标位子Init_Keypad();while(1){Key_Event();if(key_Flag==1){ key_Flag=0;if(yi==1){temp= key_val;//QSPL=temp*10000;Display_shuzi(STR_NUM_6_12,36,72,0x30+temp); //第一位的输入值}if(yi==2){temp = key_val;if (temp==67) //OK键break;if(temp==79) //清除键{yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{Display_shuzi(STR_NUM_6_12,36,78,0x30+temp);}}if(yi==3){temp = key_val;if (temp==67) //okbreak;if(temp==79) //清除键{ yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{//QSPL=QSPL+temp*100;Display_shuzi(STR_NUM_6_12,36,84,0x30+temp);}}if(yi==4){temp = key_val;if (temp==67)break;if(temp==79) //清除键{yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{Display_shuzi(STR_NUM_6_12,36,90,0x30+temp);}}if(yi==5){temp = key_val;if (temp==67)break;if(temp==79) //清除键{yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{Display_shuzi(STR_NUM_6_12,36,96,0x30+temp);}}if(yi==6){temp = key_val;if (temp==67)break;if(temp==79) //清除键{yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{Display_shuzi(STR_NUM_6_12,36,102,0x30+temp);}}if(yi==7){temp = key_val;if (temp==67)break;if(temp==79) //清除键{yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{Display_shuzi(STR_NUM_6_12,36,108,0x30+temp);}}if(yi==8){temp = key_val;if (temp==67)break;if(temp==79) //清除键{yi=0; //归位Display_StrChar(STR_CHAR,2,9," "); //清零Display_Dot(CUR_LOC_SET,47,72);//设置光标位子}else{Display_shuzi(STR_NUM_6_12,36,114,0x30+temp);yi++;break;}}yi++;//P2IFG = 0;}}while(1){Key_Event();if(key_Flag==1){ key_Flag=0;temp=key_val;if(temp==25)goto m1;}}}。
矩阵键盘控制12864显示最经典程序
矩阵键盘控制12864显示最经典程序#include //这个程序的功能:用4*4的矩阵键盘(接P3口)按键盘k1——k16中的任何一个键ki#include //12864液晶上显示数字i-1 (液晶数据口接P0)#define uint unsigned int//键盘扫描的思想是将行设置为低,列设置为高,来读取P3口的值,就能知道是哪个按键按下了#define uchar unsigned char#define LCDdata P0sbit E = P2^7;sbit RW = P2^6;sbit RS = P2^5;void init();void delayms(uint x);void displaykey();void write_com(uchar com);//写命令void write_data(uchar date);//写数据uchar temp;//--------------主函数-----------------void main(){init();// P3=0xfe;//P3=0xfd;//P3=0xfb;//P3=0xf7;while(1){displaykey();}}//-------------液晶初始化----------------void init(){write_com(0x01);write_com(0x02);write_com(0x06);write_com(0x0e);}//------------毫秒延时--------------- void delayms(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//------------写命令----------------- void write_com(uchar com){RS = 0;RW = 0;E = 0;LCDdata = com;E = 1;delayms(5);E = 0;}//-------------写数据------------------ void write_data(uchar date){RS = 1;RW = 0;E = 0;LCDdata = date;E = 1;delayms(5);E = 0;}//----void displaykey(){ //****************************判断第一行的键盘P3=0xfe; temp=P3; temp=temp&0xf0;while(temp!=0xf0)//判断是否有键盘按下为真有键盘按下{ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0)//再次判断是否有键盘按下为真有键盘按下{ temp=P3;switch(temp){case0xee:write_com(0x80);write_data('0');write_com(0x81);write_data (' ');break;case0xde:write_com(0x80);write_data('1');write_com(0x81);write_data (' ');break;case0xbe:write_com(0x80);write_data('2');write_com(0x81);write_data (' ');break;case0x7e:write_com(0x80);write_data('3');write_com(0x81);write_data (' ');break;}break;//这个break很重要不能丢下,若丢下会这这个中退步出来}}//******************************判断第二行的键盘P3=0xfd; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xed:write_com(0x80);write_data('4');write_com(0x81);write_data (' ');break;case0xdd:write_com(0x80);write_data('5');write_com(0x81);write_data (' ');break;case0xbd:write_com(0x80);write_data('6');write_com(0x81);write_data (' ');break;case0x7d:write_com(0x80);write_data('7');write_com(0x81);write_data (' ');break;} break;}}//******************************判断第三行的键盘P3=0xfb; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xeb:write_com(0x80);write_data('8');write_com(0x81);write_data (' ');break;case0xdb:write_com(0x80);write_data('9');write_com(0x81);write_data (' ');break;case0xbb:write_com(0x80);write_data('1');write_com(0x81);write_ data('0');break;case0x7b:write_com(0x80);write_data('1');write_com(0x81);write_ data('1');break;}break;}}//******************************判断第四行的键盘P3=0xf7; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xe7:write_com(0x80);write_data('1');write_com(0x81);write_ data('2');break;case0xd7:write_com(0x80);write_data('1');write_com(0x81);write_ data('3');break;case0xb7:write_com(0x80);write_data('1');write_com(0x81);write_ data('4');break;case0x77:write_com(0x80);write_data('1');write_com(0x81);write_ data('5');break;}break;}}}。
12864菜单程序
MENUTAB_4:
JMP HOST_41 ;
JMP HOST_42 ;
JMP HOST_43 ;
DIS1_RAM EQU 50H
DIS2_RAM EQU 70H
DIS3_RAM EQU 60H
DIS4_RAM EQU 80H
RR1 EQU 26H
RR3 EQU 21H
RR4 EQU 22H
;-----自检程序
CALL DL1S
MOV MENU_RAM,#00H
MOV DPTR,#TAB_H
CALL START_LCD
LCDDAT EQU P2
RS EQU P3.5
RW EQU P3.6
E EQU P3.7
REDLED EQU P3.4
BACKLED EQU P3.1
PLAY EQU P1.7
HH_H2:
CJNE A,#03H,HH_H3
MOV DPTR,#TAB_3
MOV MENU_RAM,#03H
JMP MENUNEXT
HH_H3:
CJNE A,#04H,HH_H4
MOV DPTR,#TAB_4
MENUTAB_1:
JMP HOST_11 ;
JMP HOST_12 ;
JMP HOST_13 ;
MENUTAB_2:
JMP HOST_21 ;
ONOFFLCD EQU 28H
;-------------------------------------程序入口
ORG 0000H
JMP LCD_START
ORG 0003H
12864的液晶显示程序(无字库)
12864的液晶显示程序(无字库)12864.h#ifndef __12864_H__#define __12864_H__#include#include/***************************************利用I/O口模拟点阵液晶所需时序点阵液晶控制端口定义,需根据硬件适当改变****************************************/sbit LCD_RS = P2^0;//控制端口定义sbit LCD_RW = P2^1;sbit LCD_E = P2^2;sbit LCD_CSA = P2^3;//H选通,即高电平有效sbit LCD_CSB = P2^4;#define LCD_Data P0//LCD数据端口8位#define R 1#define L 2/*****************************************函数声明*****************************************/void ReadStatusLCD(unsigned char select);//从LCD读出忙标志位unsigned char ReadDataLCD(unsigned char select);//从LCD 读出数据void WriteDataLCD(unsigned char WDLCD,unsigned char select);//向LED写入数据void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select);//向LCD写入命令void LcdReset(void) ;//初始化函数,完成液晶模块的初始设置void clear_LCD(unsigned char select);//清屏函数void Clr_All_Lcd(void);//全清屏函数void set_XY(unsigned char Column,unsigned char Page);//设置数据写入或读出的地址,通过页号和列数可以唯一确定一个地址void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW);//向指定行列写数据void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte );//显示点void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] );//显示16×16点阵的编码void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num,unsigned char V_num, unsigned char * puts );//通用的显示函数void Drawing_dot(unsigned char x,unsigned char y);void Drawing_line_vertical(unsigned x);#endif12864.c/****************************************************LCD12864点阵液晶屏,通过I/O口直接控制,采用模拟时序控制****************************************************/#include"12864.h"#include/*********************************************************** 功能:从LCD读取状态位变量:select用于选择LCD屏的左右,1选择左屏,2选择右屏***********************************************************/ void ReadStatusLCD(unsigned char select){switch(select){case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右default: break;}LCD_Data = 0xff;//置位输入口,已实现输入LCD_RS=0;LCD_RW=1;LCD_E=1;//高电平读取数据//_nop_(); //若晶振速度高,可在此作延时处理while(LCD_Data&0x80);//最高位为忙标志,检测忙信号状态LCD_E=0;//_nop_(); //若晶振速度高,可在此作延时处理}/*********************************************************** 功能:从LCD读取数据变量:select用于选择LCD屏的左右,1选择左屏,2选择右屏***********************************************************/ unsigned char ReadDataLCD(unsigned char select){unsigned char dataR;LCD_Data = 0xff;//置位输入口,已实现输入switch(select){case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右default: break;}LCD_RW=1;LCD_RS=1;LCD_E = 1;// 操作允许脉冲信号,高电平读出//_nop_(); //若晶振速度高,可在此作延时处理dataR = LCD_Data;LCD_E= 0;return dataR;}/***********************************************************功能:向LCD写入数据参数:WDLCD待写入的字符数据select用于选择LCD屏的左右,1选择左屏,2选择右屏***********************************************************/void WriteDataLCD(unsigned char WDLCD,unsigned char select){switch(select){case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右default: break;}ReadStatusLCD(select);//检测忙标志LCD_RS = 1;LCD_RW = 0;LCD_Data = WDLCD;LCD_E = 1;//_nop_(); //若晶振速度高,可在此作延时处理LCD_E = 0; //下降沿写入数据//_nop_(); //若晶振速度高,可在此作延时处理}/***********************************************************功能:向LCD写入命令参数:WDLCD待写入的字符数据BusyC是否要检查忙标志位选择标志,1为进行,0为不检测select用于选择LCD屏的左右,1选择左屏,2选择右屏***********************************************************/void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select) {if(BusyC) ReadStatusLCD(select);//根据需要检测忙switch(select){case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右default: break;}LCD_Data = WCLCD;LCD_RS = 0;LCD_RW = 0;LCD_E = 1;//_nop_(); //若晶振速度高,可在此作延时处理LCD_E = 0;}/************************************************************** **************** 功能:清显示RAM区(清屏)参数:select为驱动控制器选择1为左2为右*************************************************************** **************** */void clear_LCD(unsigned char select){unsigned char i,j;for(i=0;i<8;i++){ //8页,换页清零WriteCommandLCD( 0xb8|i,1 ,select);//页面地址设置,并分别写入左右模块中WriteCommandLCD( 0x40,1 ,select);//列地址设置,设置为0列,并分别写入左右三个模块中for(j=0;j<64;j++){ //页内清零WriteDataLCD( 0 ,select);}}}/************************************************************** *************** 功能:清LCD左右屏*************************************************************** **************/ void Clr_All_Lcd(void){clear_LCD(1);clear_LCD(2);}/************************************************************** **************** 功能:LCD初始化,分为左,右模块初始化参数:select为驱动控制器选择1为左2为右*************************************************************** **************** */void LcdReset(void){unsigned char i;for(i=0;i<5;i++){WriteCommandLCD( 0xc0,0 ,R);//设置显示起始行为第一行,并分别写入左右模块中,不检测忙标志WriteCommandLCD( 0xc0,0 ,L);//_nop_(); //若晶振速度高,可在此作延时处理}WriteCommandLCD( 0xc0,1 ,R);//设置显示起始行为第一行,并分别写入左右模块中,检测忙标志WriteCommandLCD( 0xc0,1 ,L);WriteCommandLCD( 0x3f,1 ,R);//开显示设置,并分别写入左右模块中WriteCommandLCD( 0x3f,1 ,L);clear_LCD(R);//清左屏clear_LCD(L);//清右屏}/************************************************************** **************** 功能:设置数据写入或读出的地址,通过页号和列数可以唯一确定一个地址参数:Column表示列号,Page表示页号*************************************************************** **************** */void set_XY(unsigned char Column,unsigned char Page){unsigned char x,y;unsigned char select;switch (Column&0x40) //完成左右屏的判断,根据列号完成区分,<64为左屏,>=64为右屏{case 0x00: {select = 1;ReadStatusLCD(select);break;}/*为左区*/case 0x40: {select = 2;ReadStatusLCD(select);break;}/*为右区*/}x = Column&0x3F|0x40; /* col.and.0x3f.or.Set Y Address*/ y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */WriteCommandLCD( y,1 ,select);//设置页面地址WriteCommandLCD( x,1 ,select);//设置列地址}/************************************************************** **************** 功能:根据地址值(页数和列号),写入数据,即写入显示缓冲区,便可以显示在LCD屏上参数:Column表示列号,Page表示页号,dataW表示待写入的数据*************************************************************** **************** */void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW){set_XY(Column,Page);LCD_RW=0;LCD_RS=1;_nop_();//若晶振速度高,可在此作延时处理LCD_Data = dataW;// 送数据_nop_(); //若晶振速度高,可在此作延时处理LCD_E = 1;_nop_(); //若晶振速度高,可在此作延时处理LCD_E= 0; // 操作允许脉冲信号,下降沿写入}/************************************************************** **************** 功能:用于显示点阵参数:Column表示列号,Page表示页号,*************************************************************** **************** */void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte ){unsigned char i;i=Column;for(;Page<8;Page++){for(;Column<128;Column++){xy_Write(Column,Page,DotByte);//DotByte = ~DotByte;}Column=i;}}/************************************************************** **************** 功能:在指定列,指定页显示待显示的点阵编码,用于显示16*16点阵码参数:Column表示列号,Page表示页号,puts待显示的点阵编码首指针*************************************************************** **************** */void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] ){unsigned char i,j;for(i=0;i<2;i++)//此处的2为控制点阵行数,实际点阵行数为2*8=16行,此处的16(对应的点行数)应为8的倍数{for(j=0;j<16;j++)//此处控制每行显示的列数{xy_Write(Column+j,Page+i,puts[i][j]);}}}/****************************************************************************** 功能:在指定列,指定页显示待显示指定点阵的编码参数:Column表示列号,Page表示页号,C_num为显示点阵的行数(物理行8的倍数),V_num 为列(物理列)puts待显示的点阵编码首指针*************************************************************** **************** */void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num,unsigned char V_num, unsigned char * puts){unsigned char i,j;for(i=0;i<(C_num/8);i++)//此处的2为控制点阵行数,实际点阵行数为2*8=16行,此处的16(对应的点行数)应为8的倍数{for(j=0;j<="">{xy_Write(Column+j,Page+i,*(puts+i*V_num+j));//注意地址的变化规律}}}/************************************************************** **************** 功能:绘点参数:Column表示列号,Page表示页号,C_num为显示点阵的行数(物理行8的倍数),V_num 为列(物理列)puts待显示的点阵编码首指针*************************************************************** **************** */void Drawing_dot(unsigned char x,unsigned char y){unsigned char y_byte,x_bit,y_bit,reverse_y;//此处y_byte为page,y_bit为具体行号,x_bit 为行号unsigned char dot;reverse_y=63-y;x_bit=x;y_byte=reverse_y/8;y_bit=y%8;// for(;x_bit<128;x_bit++)if(y_bit==0) dot=0x80;if(y_bit==1) dot=0x40;if(y_bit==2) dot=0x20;if(y_bit==3) dot=0x10;if(y_bit==4) dot=0x08;if(y_bit==5) dot=0x04;if(y_bit==6) dot=0x02;if(y_bit==7) dot=0x01;xy_Write(x_bit,y_byte,dot);/* reverse_y=64-y;if(y_bit==7) y_byte=y_byte-1;y_bit=y%8;if(y_byte==(-1)) break;*/}/************************************************************** **************** 功能:绘垂直直线参数:x表示列号*************************************************************** **************** */void Drawing_line_vertical(unsigned char x){xy_Write(x,0,0xff);xy_Write(x,1,0xff);xy_Write(x,2,0xff);xy_Write(x,3,0xff);xy_Write(x,4,0xff);xy_Write(x,5,0xff);xy_Write(x,6,0xff);xy_Write(x,7,0xff);}主程序.c/************************************************************** **************** ****************12864液晶屏上显示"南京绝妙科技发展有限公司,025-******** 开发板欢迎使用","0~9",刷新后重显。
12864液晶屏幕使用说明及程序
12864使用说明一、串/并接口1.1 串口接口管脚信号*注释1:如在实际应用中仅使用并口通讯模式,可将PSB 接固定高电平。
*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。
*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK 用焊锡短接。
1.2 并行接口管脚信号*注释1:如在实际应用中仅使用并口通讯模式,可将PSB 接固定高电平。
*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。
*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK 用焊锡短接。
二、模块主要硬件构成说明控制器接口信号说明:2.1、RS,R/W的配合选择决定控制界面的4种模式:2.2、E信号●忙标志BFBF 标志提供内部工作情况.BF=1 表示模块在进行内部操作,此时模块不接受外部指令和数据.BF=0 时, 模块为准备状态,随时可接受外部指令和数据.利用STATUS RD 指令,可以将BF 读到DB7 总线,从而检验模块之工作状态.●字型产生ROM(CGROM)字型产生ROM(CGROM)提供8192 个此触发器是用于模块屏幕显示开和关的控制。
DFF=1 为开显示(DISPLAY ON),DDRAM 的内容就显示在屏幕上,DFF=0 为关显示(DISPLAY OFF)。
DFF 的状态是指令DISPLAY ON/OFF 和RST 信号控制的。
●显示数据RAM(DDRAM)模块内部显示数据 RAM 提供 64×2 个位元组的空间,最多可控制 4 行 16 字(64 个字)的中文字型显示,当写入显示数据 RAM 时,可分别显示 CGROM 与CGRAM 的字型;此模块可显示三种字型,分别是半角英、数字型(16*8)、CGRAM 字型及 CGROM 的中文字型。
三种字型的选择,由在 DDRAM 中写入的编码选择,在0000H—0006H 的编码中(其代码分别是 0000、0002、0004、0006 共 4 个)将选择 CGRAM 的自定义字型,02H—7FH 的编码中将选择半角英数字的字型,至于A1 以上的编码将自动的结合下一个位元组,组成两个位元组的编码形成中文字型的编码BIG5(A140—D75F),GB(A1A0-F7FFH)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
write_dat(dis3[i]);
}
write_cmd(0x98);
for(i=0;i<16;i++)
{
write_dat(dis4[i]);
}
}
if(count1==2) //按下选择按钮2次
uchar code dis1_[] = {"系统初始化. "};
uchar code dis2_[] = {"系统初始化.. "};
uchar code dis3_[] = {"系统初始化.. "};
uchar code dis4_[] = {"按选择键开始! "};
uchar code dis1_6[] = {" 摄像头 "};
uchar code dis2_6[] = {" "};
uchar code dis3_6[] = {" "};
uchar code dis4_6[] = {"保存拍照——返回 "};
write_cmd(0x90);
for(i=0;i<16;i++)
{
write_dat(dis3_[i]);
}
delay_1ms(500);
write_cmd(0x90);
for(i=0;i<16;i++)
{
write_dat(dis4_[i]);
}
write_cmd(0x30); //基本指令操作
delay_1ms(2);
write_cmd(0x0C); //显示开,关光标
delay_1ms(2);
write_cmd(0x01); //清除LCD的显示内容
delay_1ms(2);
write_cmd(0x90); // 显示第一页,开机显示初始化。
uchar code dis1_4[] = {" 系统文件 "};
uchar code dis2_4[] = {"《小车使用手册》"};
uchar code dis3_4[] = {"《单片机基础》 "};
uchar code dis4_4[] = {" 翻页————返回 "};
LCD_RW = 0;
LCD_EN = 0;
P0 = cmd;
delay_1ms(1);
LCD_EN = 1;
delay_1ms(1);
LCD_EN = 0;
}
void write_dat(uchar dat)//写显示数据到LCD :RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
}
void main()
{
delay_1ms(10);
bianliang_init();
Time_init();
lcd_init();
while(1)
{
xuanzekey();
quedingkey();
fanhuikey();
if(flag==5){ LED_(1); }
uchar code dis5[] = {"系 5:轻松一刻!"};
uchar code dis6[] = {"统 6:摄像头 "};
uchar code dis7[] = {"菜 7:Word阅读器"};
uchar code dis8[] = {"单 8:万年历 "};
for(i=0;i<16;i++)
{
write_dat(dis1_[i]);
}
delay_1ms(500);
write_cmd(0x90);
for(i=0;i<16;i++)
{
write_dat(dis2_[i]);
}
delay_1ms(500);
}
write_cmd(0x88);
for(i=0;i<16;i++)
{
write_dat(dis3[i]);
}
write_cmd(0x98);
void delay_1ms(uint x)
{
uint i,j;
for(j=0;j<x;j++)
for(i=0;i<113;i++);
}
void write_cmd(uchar cmd)//写指令数据到LCD :RS=L,RW=L,E=高脉冲,D0-D7=指令码
{
LCD_RS = 0;
flag=0;
flag1=0;
}
void Time_init()
{
TMOD=0x01;
TH0=-(50000/256);//500毫秒
TL0=-(50000%6);
EA=1;
ET0=1;
TR0=1;
}
void lcd_init()
{
LCD_PSB = 1; //并口方式
uchar code dis1_2[] = {" 外部存储器 "};
uchar code dis2_2[] = {"以用大小: 12%"};
uchar code dis3_2[] = {"剩余大小: 88%"};
uchar code dis4_2[] = {" 返回"};
write_dat(0x10); //写箭头的数据
write_cmd(0x90);
for(i=0;i<16;i++)
{
write_dat(dis2[i]);
}
write_cmd(0x88);
for(i=0;i<16;i++)
uchar code dis1_1[] = {" 液晶屏背光灯"};
uchar code dis2_1[] = {"亮度: 0/9"};
uchar code dis3_1[] = {"延时时间: 0/9"};
uchar code dis4_1[] = {"保存——————返回"};
uchar code dis1_8[] = {" 万年历 "};
uchar code dis2_8[ห้องสมุดไป่ตู้ = {"2011年02月01日 "};
uchar code dis3_8[] = {"12时:52分:23秒 "};
uchar code dis4_8[] = {"更改设置——返回 "};
uchar count1,i,flag,flag1,tt;
#define LCD_data P0 //数据口
sbit LCD_RS = P2^5; //寄存器选择输入0写指令:1写数据
sbit LCD_RW = P2^6; //液晶读/写控制
sbit LCD_EN = P2^7; //液晶使能控制
sbit LED1 = P0^0;
void xuanzekey(); //选择子函数··flag
void quedingkey(); //确定子函数··flag1
void fanhuikey(); //返回子函数··
void LED_(uchar kai);
{
flag=2; //选择键标志位
write_cmd(0x90+1);
write_dat(0x10); //横三角符号
write_cmd(0x80);
for(i=0;i<16;i++)
{
write_dat(dis1[i]);
uchar code dis1_7[] = {" Word文件 "};
uchar code dis2_7[] = {" "};
uchar code dis3_7[] = {" "};
uchar code dis4_7[] = {" 保存————返回 "};
uchar code dis1_3[] = {" 多媒体播放器 "};
uchar code dis2_3[] = {"选择歌曲: 0/10"};
uchar code dis3_3[] = {"声音大小: 0/9 "};
uchar code dis4_3[] = {"保存————返回 "};
uchar code dis1[] = {"系 1:背光灯 "};
uchar code dis2[] = {"统 2:存储器管理"};
uchar code dis3[] = {"菜 3:MP3 播放 "};
uchar code dis4[] = {"单 4:文件夹选项"};
本文主要介绍89c51下,12864显示菜单程序,用户只用设置12864的命令数据端口
读写控制端口,使能端口和串并方式控制接口,以及按键端口即可。
#include <reg51.h>
#define uchar unsigned char