12864并行多级菜单程序
- 格式:doc
- 大小:55.00 KB
- 文档页数:11
//////////////////////////////////////////////////////////////////////////////////stm32-12864并行驱动程序////////////////////////////////////////////////////#include "delay.h" //必须配合delay.c 和delay.h 文件使用,所以要包含delay.h。
#include "display12864.h"f/********** 以下是相关引脚定义。
**************/// A 口的#define DisIO GPIOE //定义12864 要使用的I/O 端口。
#define DisClk RCC_APB2Periph_GPIOE //定义12864 要使用的I/O 端口的时钟。
#define DataGPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7//定义12864 使用的数据引脚。
#define EN GPIO_Pin_10 //定义使能端使用的引脚/*********************************************/#define DisIOIO GPIOE //定义12864 要使用的I/O 端口。
#define DisClkIO RCC_APB2Periph_GPIOE //定义12864 要使用的I/O 端口的时钟。
#define RS #define RW GPIO_Pin_9GPIO_Pin_8/*光标定位函数定义结束。
*/#define x1 0x80#define x2 0x88#define y 0x80GPIO_InitTypeDef GPIOStru; //定义用于定义所以引脚为输出的变量。
FYD12864液晶中文显示模块(一) (一)概述 (3)(二)(二)外形尺寸1 方框图 (3)2 外型尺寸图 (4)(三)(三)模块的接口 (4)(四)(四)硬件说明 (5)(五) 指令说明 (7)(五)(五)读写操作时序 (8)(六)(六)交流参数 (11)(七)(七)软件初始化过程 (12)(八)(八)应用举例 (13)(九)(九)附录1半宽字符表 (20)2 汉字字符表 (21)一、概述FYD12864-0402B是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64, 内置8192个16*16点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。
可以显示8×4行16×16点阵的汉字. 也可完成图形显示.低电压低功耗是其又一显著特点。
由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。
基本特性:●●低电源电压(VDD:+3.0--+5.5V)●●显示分辨率:128×64点●●内置汉字字库,提供8192个16×16点阵汉字(简繁体可选)●●内置 128个16×8点阵字符●●2MHZ时钟频率●●显示方式:STN、半透、正显●●驱动方式:1/32DUTY,1/5BIAS●●视角方向:6点●●背光方式:侧部高亮白色LED,功耗仅为普通LED的1/5—1/10 ●●通讯方式:串行、并口可选●●内置DC-DC转换电路,无需外加负压●●无需片选信号,简化软件设计●●工作温度: 0℃ - +55℃ ,存储温度: -20℃ - +60℃二、方框图3、外形尺寸图三、模块接口说明*注释1:如在实际应用中仅使用串口通讯模式,可将PSB接固定低电平,也可以将模块上的J8和“GND”用焊锡短接。
#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多级菜单设计作者董新凯#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;}}}。
LCD12864多级菜单课程设计一、课程目标知识目标:1. 理解LCD12864液晶显示屏的基本工作原理和接口技术。
2. 掌握多级菜单的设计方法,包括菜单结构、界面布局及跳转逻辑。
3. 学会编写程序代码实现LCD12864多级菜单的显示与操作。
技能目标:1. 能够运用所学知识设计出结构清晰、界面友好的多级菜单界面。
2. 熟练使用相关编程语言和开发工具,完成程序编写和调试。
3. 培养学生的动手操作能力和团队协作能力,提高问题解决能力。
情感态度价值观目标:1. 培养学生对电子技术和编程的兴趣,激发学习热情。
2. 培养学生严谨、细心的学习态度,养成良好的编程习惯。
3. 增强学生的创新意识,鼓励学生敢于尝试、勇于实践。
分析课程性质、学生特点和教学要求,本课程目标旨在帮助学生在掌握LCD12864多级菜单设计的基础上,提高实际操作能力,培养学生的创新思维和团队协作精神。
通过本课程的学习,使学生能够在实际项目中运用所学知识,为我国电子信息产业的发展做出贡献。
同时,注重培养学生的情感态度价值观,使学生在学习过程中形成积极向上的人生态度。
二、教学内容1. LCD12864液晶显示屏原理介绍:包括显示原理、接口技术、指令集等基本知识。
- 教材章节:第三章第二节- 内容列举:LCD12864工作原理、接口类型、指令功能。
2. 多级菜单设计方法:- 教材章节:第五章- 内容列举:菜单结构设计、界面布局、跳转逻辑、操作流程。
3. 编程实现LCD12864多级菜单:- 教材章节:第六章- 内容列举:编程环境搭建、代码编写、程序调试、功能实现。
4. 实例分析与操作:- 教材章节:第七章- 内容列举:典型多级菜单实例、操作方法、优化技巧。
5. 动手实践与团队协作:- 教材章节:第八章- 内容列举:实践任务分配、协作流程、成果展示。
根据课程目标,教学内容分为五个部分,确保学生系统掌握LCD12864多级菜单设计的相关知识。
教学大纲明确指出各部分内容的安排和进度,以及教材对应的章节和具体内容。
[资料教程]玩转12864液晶(1)--显示字符12864本帖最后由无语于2009-8-11 12:14 编辑在我们常用的人机交互显示界面中,除了数码管,LED,以及我们之前已经提到的LCD1602之外,还有一种液晶屏用的比较多。
相信接触过单片机的朋友都知道了,那就是12864液晶。
顾名思义,12864表示其横向可以显示128个点,纵向可以显示64个点。
我们常用的12864液晶模块中有带字库的,也有不带字库的,其控制芯片也有很多种,如KS0108T6963,ST7920等等。
在这里我们以ST7920为主控芯片的12864液晶屏来学习如何去驱动它。
(液晶屏采用金鹏的OCMJ4X8C)关于这个液晶屏的更多信息,请参考它的DATASHEET,附件中有下载。
我们先来了解一下它的并行连接情况。
下面是电路连接图从上面的图可以看出,液晶模块和单片机的连接除了P0口的8位并行数据线之外,还有RS,RW,E等几根线。
其中R/S是指令和数据寄存器的选择控制线(串行模式下为片选),R/W是读写控制线(串行模式下是数据线),E是使能线(串行模式下为时钟线)。
通过这几根控制线和数据线,再结合它的时序图,我们就可以编写出相应的驱动程序啦。
看看并行模式下的写时序图:根据这个时序图,我们就可以写出写数据或者写命令到LCD12864液晶的子程序。
读时序图如下:根据这个时序图我们就可以从LCD12864液晶模块内部RAM中读出相应的数据,我们的忙检测函数就是根据这个时序图写出来的。
以及后面章节中讲的画点函数等都要用到读时序。
有了这两个时序图,然后我们再看看OCMJ4X8C的相关指令集,就可以编写出驱动程序了。
这里要注意的是指令集分为基本指令集和扩充指令集,其中扩充指令集主要是与绘图相关,在此后的章节中会有相应的介绍。
下面让我们根据这些编写出它的驱动程序吧。
我的硬件测试条件为:STC89C516(11.0592MHz) + OCMJ4X8C实际显示效果图片如下:程序部分如下,请结合液晶模块的DATASHEET看程序,这样能够更加快速的弄懂程序的流程。
液晶12864 分级菜单编程思想喜欢单片机的人,想必对液晶12864应该不会陌生。
对于单片机来说,如果用于显示,12864是个不错的选择,编程既简单,而资源消耗又符合单片机的使用要求,是理想的选择。
下面就我做有关单片机的一点心得分享一下我在编写液晶12864的一点思想,希望能个喜欢这些东西的同志们有所启发。
以下是我项目中分级菜单的源文件:(一个12864的五级菜单)/**************************************分级菜单***************************************/#include"STC15F2K.H"#include"KEY.H"#include"LCD.H"#include"LIST.H"#include"YINGY.H"#include"HCSR04.H"#include"HONGW.H"#include "PCF8563.H"/**************************************变量定义***************************************/uchar wendT=30; //温度上限bit fg=0;uchar key = 0; //键值获得//uchar keyq = 0; //子菜单项标志uchar flagk = 0;uint flag = 0; //菜单标志bit flag_ms = 0; //智能模式和安全模式标志位uchar timeflag=0; //时间设置标志位uchar shi=7,fen=0,miao=0; //闹钟标志位uchar ms_h1=6,ms_m1=0,ms_h2=22,ms_m2=0; //时间标志位bit bing_nao = 0; //闹钟开启标志位uchar code l1[] = "年";uchar code l2[] = "月";uchar code l3[] = " ";uchar code l4[] = "时";uchar code l5[] = "分";uchar code l6[] = " ";uchar code l7[] = ":";uchar code l8[] = "为";/**************************************函数声明**************************************/void fenjcd();void yiji_menu();void erji_menu();void sanjims_menu();void sanjiqt_menu();void xiug_time(); //时间修改void ms_back();void qt_back();void siji_nao();void nao_time();void ms_time();void wenduT();/**************************************总菜单**************************************/void fenjcd(){yiji_menu();erji_menu();sanjims_menu();sanjiqt_menu();xiug_time(); //时间修改ms_back();qt_back();siji_nao();nao_time();ms_time();}/**************************************一级菜单**************************************/void yiji_menu(){key=getKey();if(flag==0){if(key==1||IR_code==0x45) //进入功能选择页面{write_com(0x01);write(0x81,lis2);write(0x90,lis21);write(0x88,lis23);write(0x98,lis25);write_com(0x0c);flagk = 1;flag = 1;key = 0;IR_code=0;}}if(flag == 1){if(key == 1||IR_code==0x45) //返回正常页面{write_com(0x01);write(0x82,lis1);write(0x90,lcd_date_H);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);write_com(0x0c);flag = 0;flagk = 0;key = 0;IR_code=0;}}}/**************************************二级菜单**************************************/void erji_menu(){if(flag==1){if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //功能设置选择中if(keyq == 1){write(0x90,lis20);write(0x88,lis24);write(0x98,lis25);}else if(keyq == 2){write(0x90,lis20);write(0x88,lis23);write(0x98,lis26);}IR_code=0;if(keyq>=3) keyq = 0;if(keyq == 0){write(0x98,lis25);write(0x90,lis21);write(0x88,lis23);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //进入时间设置页面{flag = 20; //时间设置编码write_com(0x01);write(0x82,lis30);write(0x90,lisk0);write(0x89,lisk1);write_num(0x90,year_1);//LCD显示write_num(0x91,time.year);write_num(0x93,time.month);write_num(0x95,time.day);write_num(0x89,time.hour);write_num(0x8b,time.minute);write_num(0x8d,time.second);keyq = 0;key=0;IR_code=0;}if(keyq == 1) //进入模式设置页面{flag=21;write_com(0x01);write(0x82,lis31);write(0x90,lis311);write(0x88,lis312);keyq = 0;key=0;IR_code=0;}if(keyq == 2) //进入其它设置页面{flag=22;write_com(0x01);write(0x82,lis32);write(0x90,lis321);write(0x88,lis322);write(0x98,lis324);keyq = 0;key=0;IR_code=0;}}}}/**************************************三级菜单**************************************///三级模式void sanjims_menu(){if(flag == 21) //模式选择{if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //模式选择中if(keyq == 1){write(0x90,lis310);write(0x88,lis313);}IR_code=0;if(keyq>=2) keyq = 0;if(keyq == 0){write(0x88,lis312);write(0x90,lis311);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //开启智能模式{flag = 210; //智能模式编码flag_ms = 0;write_com(0x01);write(0x82,lis1);write(0x90,lis430);write(0x88,lis432);write(0x99,lis433);keyq = 0;key = 0;IR_code=0;}if(keyq == 1) //开启安全模式{flag = 211; //安全模式编码flag_ms = 1;write_com(0x01);write(0x82,lis1);write(0x88,lis431);keyq = 0;key=0;IR_code=0;}}}if(flag == 21) //返回功能设置页面{if(key == 1||IR_code==0x45){write_com(0x01);write(0x81,lis2);write(0x90,lis21);write(0x88,lis23);write(0x98,lis25);write_com(0x0c);flag = 1;key=0;IR_code=0;}}}//三级其它void sanjiqt_menu(){if(flag == 22) //其它设置选择{if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //其它设置项选择中if(keyq == 1){write(0x90,lis320);write(0x88,lis323);write(0x98,lis324);}else if(keyq == 2){write(0x90,lis320);write(0x88,lis322);write(0x98,lis325);}IR_code=0;if(keyq>=3) keyq = 0;if(keyq == 0){write(0x98,lis324);write(0x90,lis321);write(0x88,lis322);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //进入闹钟设置{flag = 220; //闹钟设置编码write_com(0x01);write(0x82,lis40);write(0x90,lis401);write(0x88,lis402);keyq = 0;key = 0;IR_code=0;}if(keyq == 1) //进入温度上限设置**{flag = 221; //温度上限设置write_com(0x01);write(0x81,lis41);write(0x88,lis410);write_com(0x0c);keyq = 0;key = 0;IR_code=0;}if(keyq == 2) //进入遥控器解码{flag = 222; //遥控解码编码write_com(0x01);write(0x82,lis42);write(0x90,lis420);write(0x98,lis421);keyq = 0;key=0;IR_code=0;}}}if(flag == 22) //返回功能设置页面{if(key == 1||IR_code==0x45){write_com(0x01);write(0x81,lis2);write(0x90,lis21);write(0x88,lis23);write(0x98,lis25);write_com(0x0c);flag = 1;key=0;IR_code=0;}}}/*******************************************时间设置********************************************/void xiug_time(){if(flag==20){if(key == 1||IR_code==0x45){if(timeflag == 0) //秒{write_com(0x0f);write_num(0x8d,time.second);write(0x8c,l5);}else if(timeflag == 1) //分{write_com(0x0f);write_num(0x8b,time.minute);write(0x8a,l4);}else if(timeflag == 2) //时{write_com(0x0f);write_num(0x89,time.hour);write(0x88,l6);}else if(timeflag == 3) //天{write_com(0x0f);write_num(0x95,time.day);write(0x94,l2);}else if(timeflag == 4) //月{write_com(0x0f);write_num(0x93,time.month);write(0x92,l1);}else if(timeflag == 5) //年{write_com(0x0f);write_num(0x91,time.year);write_num(0x90,year_1);}timeflag++;IR_code=0;if(timeflag>6)timeflag = 0;}if(key == 3||IR_code==0x15) //数值加1{if(timeflag == 1) //秒{time.second++;if(time.second>=60)time.second=0;write_num(0x8d,time.second);write(0x8c,l5);}else if(timeflag == 2) //分{time.minute++;if(time.minute>=60)time.minute=0;write_num(0x8b,time.minute);write(0x8a,l4);}else if(timeflag == 3) //时{time.hour++;if(time.hour>=24) time.hour=0;write_num(0x89,time.hour);write(0x88,l6);}else if(timeflag == 4) //天{time.day++;if(time.day>=31)time.day=1;write_num(0x95,time.day);write(0x94,l2);}else if(timeflag == 5) //月{time.month++;if(time.month>=13)time.month=1;write_num(0x93,time.month);write(0x92,l1);}else if(timeflag == 6) //年{time.year++;write_num(0x91,time.year);write_num(0x90,year_1);}IR_code=0;}if(key==4||IR_code==0x47) //返回正常显示页面{settime();write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk=0;timeflag = 0;key = 0;IR_code=0;}}}/******************************************* 模式选定返回设置********************************************/ void ms_back(){if(flag==211&&(key==1||IR_code==0x45)){write_com(0x01);write(0x82,lis31);write(0x90,lis311);write(0x88,lis312);write_com(0x0c);flag=21;key=0;IR_code=0;}}/********************************************** 温度上限设置**********************************************/ void wenduT(){if(flag==221){if(fg==0){write_num(0x8d,wendT);write(0x8c,l8);write_com(0x0c);}if(key == 3||IR_code==0x15) //数值加1{fg=1;wendT++;write_com(0x0f);write_num(0x8d,wendT);write(0x8c,l8);key=0;IR_code=0;}if(IR_code==0x07) //数值加1{fg=1;wendT--;write_com(0x0f);write_num(0x8d,wendT);write(0x8c,l8);key=0;IR_code=0;}}if(key==4||IR_code==0x47) //返回正常显示页面{write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk = 0;timeflag = 0;key = 0;fg=0;IR_code=0;} IR_code=0;}/*******************************************其它选项选定返回设置********************************************/void qt_back(){if((flag==221||flag==222||flag==220)&&(key==1||IR_code==0x45)){write_com(0x01);write(0x82,lis32);write(0x90,lis321);write(0x88,lis322);write(0x98,lis324);write_com(0x0c);flag=22;key=0;IR_code=0;}}/*******************************************闹钟选择设定********************************************/void siji_nao(){if(flag == 220) //闹钟选择{if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //闹钟选择中if(keyq == 1){write(0x90,lis400);write(0x88,lis403);}IR_code=0;if(keyq>=2) keyq = 0;if(keyq == 0){write(0x88,lis402);write(0x90,lis401);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //关闭闹钟{flag = 2200;bing_nao =0;write_com(0x01);write(0x82,lis40);write(0x88,lis405);keyq = 0;key = 0;IR_code=0;}if(keyq == 1) //开并设置闹钟{flag = 2201;bing_nao =1;write_com(0x01);write(0x82,lis40);write(0x90,lis404);write(0x89,lisk1);write_num(0x89,shi);write_num(0x8b,fen);write_num(0x8d,miao);keyq = 0;key=0;IR_code=0;}}}if(flag == 2200) //返回闹钟选择页面{if(key == 1||IR_code==0x45){write_com(0x01);write(0x82,lis40);write(0x90,lis401);write(0x88,lis402);write_com(0x0c);flag = 220;key=0;IR_code=0;}}}/*******************************************闹钟定时********************************************/void nao_time(){if(flag==2201){{if(key == 1||IR_code==0x45){if(timeflag == 0) //秒{write_com(0x0f);write_num(0x8d,miao);write(0x8c,l5);}else if(timeflag == 1) //分{write_com(0x0f);write_num(0x8b,fen);write(0x8a,l4);}else if(timeflag == 2) //时{write_com(0x0f);write_num(0x89,shi);write(0x88,l6);}timeflag++;IR_code=0;if(timeflag>3)timeflag = 0;}if(key == 3||IR_code==0x15) //数值加1{if(timeflag == 1) //秒{miao++;if(miao>=60)miao=0;write_num(0x8d,miao);write(0x8c,l5);}else if(timeflag == 2) //分{fen++;if(fen>=60)fen=0;write_num(0x8b,fen);write(0x8a,l4);}else if(timeflag == 3) //时{shi++;if(shi>=24)shi=0;write_num(0x89,shi);write(0x88,l6);}IR_code=0;}if(key==4||IR_code==0x47) //返回正常显示页面{write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk = 0;timeflag = 0;key = 0;IR_code=0;}}}}/*******************************************智能模式时间定时********************************************/void ms_time(){if(flag==210){{if(key == 1||IR_code==0x45){if(timeflag == 0) //分2{write_com(0x0f);write_num(0x9d,ms_m2);write(0x9c,l4);}else if(timeflag == 1) //时2{write_com(0x0f);write_num(0x9b,ms_h2);write(0x9a,l3);}else if(timeflag == 2) //分1{write_com(0x0f);write_num(0x8d,ms_m1);write(0x8c,l4);}else if(timeflag == 3) //时1{write_com(0x0f);write_num(0x8b,ms_h1);write(0x8a,l7);}timeflag++;IR_code=0;if(timeflag>4)timeflag = 0;}if(key == 3||IR_code==0x15) //数值加1 {if(timeflag == 1) //分2{ms_m2++;if(ms_m2>=60)ms_m2=0;write_num(0x9d,ms_m2);write(0x9c,l4);}else if(timeflag == 2) //时2{ms_h2++;if(ms_h2>=24)ms_h2=0;write_num(0x9b,ms_h2);write(0x9a,l3);}else if(timeflag == 3) //分1{ms_m1++;if(ms_m1>=60)ms_m1=0;write_num(0x8d,ms_m1);write(0x8c,l4);}else if(timeflag == 4) //时1{ms_h1++;if(ms_h1>=24)ms_h1=0;write_num(0x8b,ms_h1);write(0x8a,l7);}IR_code=0;}if(key==4||IR_code==0x47) //返回正常显示页面{write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk=0;timeflag = 0;key = 0;IR_code=0;}}}}。
/****************************************************************************** ******************************************************************************* *********///程序说明:本程序为12864(st7920)驱动程序,只实现了最简单的显示功能//端口设置:RS、RW、EN分别为P0口的0、1、2,数据口为P2口//注意:1.要想在液晶屏上同时显示自定义字库和绘图,必须先显示自定义字库// 2.本程序所有函数均有用且正确,由于我的keil未破解不能编译,所以将其注释了// 3.用取模软件取的图形或汉字必须是逐行取的,因为本函数是在液晶上逐行打点的/****************************************************************************** *****************************************************************************/ #include<reg51.h>#include<intrins.h> //内含-NOP-函数#include<stdlib.h> //内含rand()函数#define uchar unsigned char#define uint unsigned int//**********宏定义所需指令#define BASIC_SET 0x30#define EXTEND_SET 0x34#define DRAW_ON 0x36#define DRAW_OFF 0x34//*************端口定义sbit LCD_RS = P0^0;sbit LCD_RW = P0^1;sbit LCD_EN = P0^2;//************变量定义//uchar dis1[10];//****************短延时void delay(uint k){uint i;uchar j;for(i = 0; i < k ;i ++)for(j = 0; j < 10 ;j ++);}//***********ms级延时函数/*void delay_1ms(uint x){uint i,j;for(j = 0;j < x; j++)for(i = 0;i < 110; i++);} *///***********12864写指令函数void write_com(uchar cmd){LCD_RS = 0;LCD_RW = 0;P2 = cmd;delay(5);LCD_EN = 1;delay(5);LCD_EN = 0;}//********12864写数据函数void write_dat(uchar dat){LCD_RS = 1;LCD_RW = 0;P2 = dat;delay(5);LCD_EN = 1;delay(5);LCD_EN = 0;}//****************从LCD中读数据uchar read_dat(void){uchar temp;P2 = 0XFF; //释放数据线LCD_RS = 1; //数据LCD_RW = 1; // 读模式LCD_EN = 1; //E为高电平进行读数据或指令delay(1);temp = P2;LCD_EN = 0;return temp;}//********************************************************//设置光标(地址)函数//参数说明:x---为行号,y为列号//********************************************************void set_cursor(unsigned char x, unsigned char y){unsigned char i;switch(x) //确定行号{case 0x00: i=0x80; break; //第一行case 0x01: i=0x90; break; //第二行case 0x02: i=0x88; break; //第三行case 0x03: i=0x98; break; //第四行default : break;}i = y+i; //确定列号write_com(i);}//********************************************************//显示字符函数//********************************************************void display_char(unsigned char Alphabet){write_dat(Alphabet); //写入需要显示字符的显示码}//********************************************************//指定位置显示字符串函数//参数说明:x为行号,y为列号//********************************************************void display_string(unsigned char x,unsigned char y,unsigned char *Alphabet) {unsigned char i=0;set_cursor(x,y); //设置显示的起始地址while(Alphabet[i]!='\0'){write_dat(Alphabet[i]); //写入需要显示字符的显示码i++;}}//***********************以下为GDRAM绘图部分***************************////*********************绘图显示的清屏函数(因清屏指令在画图时不能用)------------------------------------------------------------------------------注意!!!!!!!void gui_clear(){uchar i , j , k;write_com(EXTEND_SET);//扩展指令集,8位数据传输write_com(DRAW_OFF);//绘图显示关闭for(i = 0; i < 2; i ++)//分上下两屏写{for(j = 0; j < 32; j ++){write_com(0x80 + j);//写y坐标delay(1);if(i == 0) //写x坐标{write_com(0x80);delay(1);}else //写下半屏{write_com(0x88);delay(1);}for(k = 0; k < 16; k ++)//写一整行数据{write_dat(0x00);//写高字节write_dat(0x00);//写低字节delay(1);}}}write_com(DRAW_ON);//打开绘图显示write_com(BASIC_SET);//打开基本指令集}//******************************************************************//*****有反白显示功能的打点函数***********//参数:color=1,该点填充1;color=0,该点填充白色0;//*******************************************************************void GUI_Point(unsigned char x,unsigned char y,unsigned char color){unsigned char x_Dyte,x_byte; //定义列地址的字节位,及在字节中的哪1位unsigned char y_Dyte,y_byte; //定义为上下两个屏(取值为0,1),行地址(取值为0~31)unsigned char GDRAM_hbit,GDRAM_lbit;write_com(0x36); //扩展指令命令/***X,Y坐标互换,即普通的X,Y坐标***/x_Dyte=x/16; //计算在16个字节中的哪一个x_byte=x&0x0f; //计算在该字节中的哪一位y_Dyte=y/32; //0为上半屏,1为下半屏y_byte=y&0x1f; //计算在0~31当中的哪一行write_com(0x80+y_byte); //设定行地址(y坐标),即是垂直地址write_com(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏,即是水平地址read_dat(); //预读取数据GDRAM_hbit= read_dat(); //读取当前显示高8位数据GDRAM_lbit= read_dat(); //读取当前显示低8位数据delay(1);write_com(0x80+y_byte); //设定行地址(y坐标)write_com(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏delay(1);if(x_byte<8) //判断其在高8位,还是在低8位{if(color==1){write_dat(GDRAM_hbit|(0x01<<(7-x_byte))); //置位GDRAM区高8位数据中相应的点}elsewrite_dat(GDRAM_hbit&(~(0x01<<(7-x_byte)))); //清除GDRAM区高8位数据中相应的点write_dat(GDRAM_lbit); //显示GDRAM区低8位数据}else{write_dat(GDRAM_hbit);if(color==1)write_dat(GDRAM_lbit|(0x01<<(15-x_byte))); //置位GDRAM区高8位数据中相应的点elsewrite_dat(GDRAM_lbit&(~(0x01<<(15-x_byte))));//清除GDRAM区高8位数据中相应的点}write_com(0x30); //恢复到基本指令集}//***********(给定坐标并打点的)任意位置打点函数void lcd_set_dot(uchar x,uchar y){uchar x_byte,x_bit;//确定在坐标的那一字节哪一位uchar y_ping , y_bit;//确定在坐标的哪一屏哪一行uchar tmph , tmpl;//定义两个临时变量,用于存放读出来的数据write_com(EXTEND_SET);//扩展指令集write_com(DRAW_OFF);//绘图显示关闭x_byte = x / 16;//算出在哪一字节,注意一个地址是16位的x_bit = x % 16;//& 0x0f;//算出在哪一位y_ping = y / 32;//确定在上半屏还是下半屏,0代表上半屏,1代表下半屏y_bit = y % 32;//& 0x1f;//确定在第几行write_com(0X80 + y_bit);//先写垂直地址(最高位必须)write_com(0x80 + x_byte + 8 * y_ping);//水平坐标,下半屏坐标起始地址为0x88,(+8*y_ping)就是用来确定上半屏还是下半屏read_dat();//预读取数据tmph = read_dat();//读取当前显示高8位数据tmpl = read_dat();//读取当前显示低8位数据delay(1);write_com(0x80 + y_bit);//读操作会改变AC,所以重新设置一下write_com(0x80 + x_byte + 8 * y_ping);delay(1);if(x_bit < 8){write_dat(tmph | (0x01 << (7 - x_bit)));//写高字节,因为坐标是从左向右的,GDRAM 高位在昨,低位在右write_dat(tmpl);//原低位数据送回}else{write_dat(tmph);//原高位数据送回write_dat(tmpl | (0x01 << (15 - x_bit)));}write_com(DRAW_ON); //打开绘图显示write_com(BASIC_SET);//回到基本指令集}//************画水平线函数**********************************////x0、x1为起始点和终点的水平坐标,y为垂直坐标***************////**********************************************************//void gui_hline(uchar x0, uchar x1, uchar y){uchar bak;//用于对两个数互换的中间变量,使x1为大值if(x0 > x1){bak = x1;x1 = x0;x0 = bak;}do{lcd_set_dot(x0 , y);//从左到右逐点显示x0 ++;}while(x1 >= x0);}//***********画竖直线函数***********************************////x为起始点和终点的水平坐标,y0、y1为垂直坐标***************////**********************************************************//void gui_rline(uchar x, uchar y0, uchar y1)uchar bak;//用于对两个数互换的中间变量,使y1为大值if(y0 > y1){bak = y1;y1 = y0;y0 = bak;}do{lcd_set_dot(x , y0);//从上到下逐点显示y0 ++;}while(y1 >= y0);}//*********任意两点间画直线*********************************// //x0、y0为起始点坐标,x1、y1为终点坐标**********************// //**********************************************************// void gui_line(uchar x0 , uchar y0 , uchar x1 , uchar y1){char dx;//直线x轴差值char dy;//直线y轴差值char dx_sym;//x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym;//y轴增长方向,为-1时减值方向,为1时增值方向char dx_x2;//dx*2值变量,用于加快运算速度char dy_x2;//dy*2值变量,用于加快运算速度char di; //决策变量if(x0 == x1)//判断是否为垂直线{gui_rline(x0 , y0 , y1);//画垂直线return;}if(y0 == y1)//判断是否为水平线{gui_hline(x0 , x1 , y0);//画水平线return;}dx = x1 - x0;//求取两点之间的差值dy = y1 - y0;//****判断增长方向,或是否为水平线、垂直线、点*// if(dx > 0)//判断x轴方向dx_sym = 1;else{if(dx < 0)dx_sym = -1;else{gui_rline(x0 , y0 , y1);return;}}if(dy > 0)//判断y轴方向dy_sym = 1;else{if(dy < 0)dy_sym = -1;else{gui_hline(x0 , x1 , y0);return;}}/*将dx、dy取绝对值***********/dx = dx_sym * dx;dy = dy_sym * dy;/****计算2倍的dx、dy值*******/dx_x2 = dx * 1;//我改为了一倍,这样才跟真实的两点对应dy_x2 = dy * 1;/***使用bresenham法进行画直线***/if(dx >= dy)//对于dx>=dy,使用x轴为基准{di = dy_x2 - dx;while(x0 != x1){lcd_set_dot(x0,y0);x0 +=dx_sym;if(di < 0)di += dy_x2;//计算出下一步的决策值else{di += dy_x2 - dx_x2;y0 += dy_sym;}}lcd_set_dot(x0, y0);//显示最后一点}else //对于dx<dy使用y轴为基准{di = dx_x2 - dy;while(y0 != y1){lcd_set_dot(x0, y0);y0 += dy_sym;if(di < 0)di += dx_x2;else{di += dx_x2 - dy_x2;x0 += dx_sym;}}lcd_set_dot(x0, y0);//显示最后一点}}//***************************************************************************// //*******************画指定宽度的任意两点之间的直线**************************// //参数说明:x0、y0为起始点坐标,x1、y1为终点坐标,with为线宽*****************// //***************************************************************************// void gui_linewith(uchar x0 , uchar y0 , uchar x1 , uchar y1 , uchar with){char dx; // 直线x轴差值变量char dy; // 直线y轴差值变量char dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向char dx_x2; // dx*2值变量,用于加快运算速度char dy_x2; // dy*2值变量,用于加快运算速度char di; // 决策变量char wx, wy; // 线宽变量char draw_a, draw_b;// 参数过滤if(with==0) return;if(with>50) with = 50;dx = x1-x0; // 求取两点之间的差值dy = y1-y0;wx = with/2;wy = with-wx-1;//判断增长方向,或是否为水平线、垂直线、点if(dx>0) // 判断x轴方向{dx_sym = 1; // dx>0,设置dx_sym=1 }else{if(dx<0){dx_sym = -1; // dx<0,设置dx_sym=-1 }else{//dx==0,画垂直线,或一点wx = x0-wx;if(wx<0) wx = 0;wy = x0+wy;while(1){x0 = wx;gui_rline(x0, y0, y1);if(wx>=wy) break;wx++;}return;}}if(dy>0) // 判断y轴方向{dy_sym = 1; // dy>0,设置dy_sym=1}else{if(dy<0){dy_sym = -1; // dy<0,设置dy_sym=-1 }else{//dy==0,画水平线,或一点wx = y0-wx;if(wx<0) wx = 0;wy = y0+wy;while(1){y0 = wx;gui_hline(x0, x1, y1);if(wx>=wy) break;wx++;}return;}}// 将dx、dy取绝对值dx = dx_sym * dx;dy = dy_sym * dy;//计算2倍的dx及dy值dx_x2 = dx*2;dy_x2 = dy*2;//使用Bresenham法进行画直线if(dx>=dy) // 对于dx>=dy,则使用x轴为基准{di = dy_x2 - dx;while(x0!=x1){//x轴向增长,则宽度在y方向,即画垂直线draw_a = y0-wx;if(draw_a<0) draw_a = 0;draw_b = y0+wy;gui_rline(x0, draw_a, draw_b);x0 += dx_sym;if(di<0){di += dy_x2; // 计算出下一步的决策值}else{di += dy_x2 - dx_x2;y0 += dy_sym;}}draw_a = y0-wx;if(draw_a<0) draw_a = 0;draw_b = y0+wy;gui_rline(x0, draw_a, draw_b);}else // 对于dx<dy,则使用y轴为基准{di = dx_x2 - dy;while(y0!=y1){//y轴向增长,则宽度在x方向,即画水平线draw_a = x0-wx;if(draw_a<0) draw_a = 0;draw_b = x0+wy;gui_hline(draw_a, y0, draw_b);y0 += dy_sym;if(di<0){di += dx_x2;}else{di += dx_x2 - dy_x2;x0 += dx_sym;}}draw_a = x0-wx;if(draw_a<0) draw_a = 0;draw_b = x0+wy;gui_hline(draw_a, y0, draw_b);}//***********画矩形函数*************************************// //x0、y0为矩形左上角坐标值,x1、y1为矩形右下角坐标值********// //**********************************************************// void gui_rectangle(uchar x0 , uchar y0 , uchar x1 , uchar y1){gui_hline(x0 , x1 , y0);gui_rline(x0 , y0 , y1);gui_rline(x1 , y0 , y1);gui_hline(x0 , x1 , y1);}//****************画填充矩形函数****************************// //x0、y0为矩形左上角坐标值,x1、y1为矩形右下角坐标值********// //**********************************************************// /*void gui_rectangle_fill(uchar x0 , uchar y0 , uchar x1 , uchar y1){uchar i;//转换数据的中间变量,使x1、y1大if(x0 > x1){i = x0;x0 = x1;x1 = i;}if(y0 > y1){i = y0;y0 = y1;y1 = i;}//***判断是否是直线***//* if(y0 == y1)//画水平线{gui_hline(x0 , x1 , y0);return;}if(x0 == x1)//画竖直线gui_rline(x0 , y0 , y1);return;}while(y0 <= y1)//画填充矩形{gui_hline(x0 , x1 , y0);y0 ++;}} *///*******************画正方形函数*************************// //x0、y0为正方形左上角坐标,with正方形边长****************// //********************************************************// /*void gui_square(uchar x0 , uchar y0 , uchar with){if(with == 0)return;if((x0 + with) > 127)//横轴超出液晶边界return;if((y0 + with) > 63)return;gui_rectangle(x0 , y0 , x0 + with , y0 + with);} *///****************画填充正方形函数*************************// //x0、y0为正方形左上角坐标,with正方形边长*****************// //*********************************************************// /*void gui_square_fill(uchar x0 , uchar y0 , uchar with){if(with == 0)return;if((x0 + with) > 127)//横轴超出液晶边界return;if((y0 + with) > 63)return;gui_rectangle_fill(x0 , y0 , x0 + with , y0 + with);} *///****************画圆函数*********************************////x0、y0为圆心坐标,r为圆的半径****************************////*********************************************************///*void gui_circle(uchar x0 , uchar y0 , uchar r){char a , b;char di;if(r > 31 || r == 0)//圆大于液晶屏或者没半径则返回return;a = 0;b = r;di = 3 - 2 * r;//判断下个点位置的标志while(a <= b){lcd_set_dot( x0 - b , y0 - a);//3lcd_set_dot( x0 + b , y0 - a); //0lcd_set_dot( x0 - a , y0 + b); //1lcd_set_dot( x0 - b , y0 - a); //7lcd_set_dot( x0 - a , y0 - b); //2lcd_set_dot( x0 + b , y0 + a); //4lcd_set_dot( x0 + a , y0 - b); //5lcd_set_dot( x0 + a , y0 + b); //6lcd_set_dot( x0 - b , y0 + a);a ++;//***使用bresenham算法画圆********//* if(di < 0)di += 4 * a + 6;else{di += 10 + 4 * (a - b);b --;}lcd_set_dot( x0 + a , y0 + b);}} *///***************************************************************************// //***************************画正椭圆函数************************************// //说明:给定椭圆的四个点的参数,最左、最右点的x轴坐标值为x0、x1,最上、最下点// 的y轴坐标为y0、y1.//说明:----------------------------显示效果不好//***************************************************************************// /*void gui_ellipse(char x0, char x1, char y0, char y1){char draw_x0, draw_y0; // 刽图点坐标变量char draw_x1, draw_y1;char draw_x2, draw_y2;char draw_x3, draw_y3;char xx, yy; // 画图控制变量char center_x, center_y; // 椭圆中心点坐标变量char radius_x, radius_y; // 椭圆的半径,x轴半径和y轴半径int radius_xx, radius_yy; // 半径乘平方值int radius_xx2, radius_yy2; // 半径乘平方值的两倍char di; // 定义决策变量/* 参数过滤*//* if( (x0==x1) || (y0==y1) ) return; *//* 计算出椭圆中心点坐标*//* center_x = (x0 + x1) >> 1;center_y = (y0 + y1) >> 1; *//* 计算出椭圆的半径,x轴半径和y轴半径*//* if(x0 > x1){ radius_x = (x0 - x1) >> 1;}else{ radius_x = (x1 - x0) >> 1;}if(y0 > y1){ radius_y = (y0 - y1) >> 1;}else{ radius_y = (y1 - y0) >> 1;} *//* 计算半径平方值*//* radius_xx = radius_x * radius_x;radius_yy = radius_y * radius_y; *//* 计算半径平方值乘2值*//* radius_xx2 = radius_xx<<1;radius_yy2 = radius_yy<<1; *//* 初始化画图变量*//* xx = 0;yy = radius_y;di = radius_yy2 + radius_xx - radius_xx2*radius_y ; // 初始化决策变量/* 计算出椭圆y轴上的两个端点坐标,作为作图起点*//* draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x;draw_y0 = draw_y1 = center_y + radius_y;draw_y2 = draw_y3 = center_y - radius_y;lcd_set_dot(draw_x0, draw_y0); // 画y轴上的两个端点lcd_set_dot(draw_x2, draw_y2);while( (radius_yy*xx) < (radius_xx*yy) ){ if(di<0){ di+= radius_yy2*(2*xx+3);}else{ di += radius_yy2*(2*xx+3) + 4*radius_xx - 4*radius_xx*yy;yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;}xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;lcd_set_dot(draw_x0, draw_y0);lcd_set_dot(draw_x1, draw_y1);lcd_set_dot(draw_x2, draw_y2);lcd_set_dot(draw_x3, draw_y3);}di = radius_xx2*(yy-1)*(yy-1) + radius_yy2*xx*xx + radius_yy + radius_yy2*xx - radius_xx2*radius_yy;while(yy>=0){ if(di<0){ di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy;xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;}else{ di += radius_xx2*3 - 2*radius_xx2*yy;}yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;lcd_set_dot(draw_x0, draw_y0);lcd_set_dot(draw_x1, draw_y1);lcd_set_dot(draw_x2, draw_y2);lcd_set_dot(draw_x3, draw_y3);}} *///******************************************************************* //*******画满屏图片-----本程序为逐行写,因此图片数据也应该是逐行取的//参数:dat为填充的数据------用本程序时需要满屏图的数组//******************************************************************* /*void gui_draw_full_picture (unsigned char *dat){unsigned char i;unsigned char j;unsigned char k;unsigned char bGDRAMAddrX = 0x80; //GDRAM水平地址unsigned char bGDRAMAddrY = 0x80; //GDRAM垂直地址for(i = 0; i < 2; i++){for(j = 0; j < 32; j++){for(k = 0; k < 8; k++){write_com(0x34); //设置为8位MPU接口,扩充指令集,关闭绘图显示write_com(bGDRAMAddrY+j); //垂直地址Ywrite_com(bGDRAMAddrX+k); //水平地址Xwrite_dat(*dat++); //写数据高字节write_dat(*dat++); //写数据低字节}}bGDRAMAddrX = 0x88; //写下半屏幕}write_com(0x36); //打开绘图模式write_com(0x30); //恢复基本指令集,关闭绘图模式} */unsigned char code DCB2HEX_TAB[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; //****************************输出一行数据函数,此行可任意长,不必非得是8的倍数**和下个函数合用画任意大小(矩形)的图形或汉字//参数:flag反显标志,1为反显,x、y为指定显示位置的起始点,*dat要输出的点阵数组,no显示此行所需的点个数,即图形一行的点数void gui_loadline(unsigned char x,unsigned char y,unsigned char *dat,unsigned char no,unsigned char flag){unsigned char bit_dat;unsigned char i;/* 参数过滤,若指定显示位置超出液晶屏则返回*/if(x>127) return;if(y>63) return;for(i=0; i<no; i++)//超出本行所规定的点数则本行显示完成{/* 判断是否要读取点阵数据,每字节的开始读取一次点阵数组即i为8的倍数时*/if( (i%8)==0 ) bit_dat = *dat++;/* 对相应的点打1或打0,i&0x07意思是对8求余*/if( (bit_dat&DCB2HEX_TAB[i&0x07])==0 )//取出i对应的位,并判断是否为0{if(flag==0) //判断是否反显,该位取出的数据为0,反显要打为1,flag==0代表不反显GUI_Point(x,y,0); //正常显示0,GUI_Point(x,y,0)代表在x、y处打0elseGUI_Point(x,y,1); //将0反显}else{if(flag==0)GUI_Point(x,y,1);elseGUI_Point(x,y,0);}if( (++x)>127) return;//若显示超出了液晶屏则返回}}//*********************************************************************//********在自定义大小的区域内画图或画字函数****************************//参数说明:x、y指定显示区域的起始点坐标// dat 要输出显示的图形或汉字点阵数组。
并行通信模式的演示程序:1./*****************************************************************2.程序:12864并行通信演示实例3.制作:风沙星辰4.日期:2009年07月30日5.功能:12864并行通信各项功能演示6.备注:AT89S52 11.0592M ST7920液晶驱动7.****************************************************************/8.9.10.#include <reg52.h> // 包含头文件11.#include <intrins.h>12.13.#define uchar unsigned char //简化整型,字符型变量书写14.#define uint unsigned int15.16.char code hang1[] = {"锄禾日当午"}; // 显示字符定义17.char code hang2[] = {"汗滴禾下土"};18.char code hang3[] = {"谁知盘中餐"};19.char code hang4[] = {"粒粒皆辛苦"};20.21.#define LCD_data P0 // 引脚定义22.sbit LCD_RS = P1^0;23.sbit LCD_RW = P1^1;24.sbit LCD_EN = P1^2;25.sbit LCD_PSB = P1^3;26.27.//图片代码圣诞快乐 128*3228.uchar code Photo1[][16] ={29.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,30.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,31.0x00,0x3F,0xF0,0x70,0x0F,0xF8,0x00,0x00,0x0F,0x01,0xE0,0x00,0x00,0xFC,0x00,0x00,32.0x00,0xFF,0xFC,0xFC,0x0F,0xFC,0x81,0xF0,0x0F,0x81,0xF0,0x00,0xE0,0xFC,0x1C,0x00,33.0x03,0xFF,0xFF,0xFE,0x07,0xEF,0xC1,0xF8,0x07,0x81,0xF0,0x01,0xF3,0xFF,0x1F,0x00,34.0x03,0xE3,0xDF,0xCE,0x03,0xCF,0xE3,0xF0,0x03,0xC0,0xFF,0x01,0xF3,0xFF,0xFF,0x00,35.0x01,0xDF,0xDF,0xCE,0x07,0x9F,0x67,0xE0,0x03,0xC0,0xFF,0x80,0xFB,0xFF,0xFF,0x00,36.0x00,0xFF,0xDF,0x9F,0x0F,0x9F,0x7F,0xC0,0x03,0xC0,0xFF,0xC0,0xFB,0xFF,0xFF,0x00,37.0x00,0xCF,0xDC,0x1F,0x0F,0xFE,0xFF,0xC0,0x1F,0xE3,0xFF,0xC0,0x73,0xC7,0xFC,0x00,38.0x00,0xFF,0xFC,0x3F,0x0F,0xF8,0xE3,0xC0,0x1F,0xF7,0xF3,0xE0,0xF7,0x9F,0xF0,0x00,39.0x00,0xF3,0xFF,0xFE,0x03,0xF9,0xE9,0xDC,0x1F,0xFB,0xF3,0xC1,0xCF,0xFF,0xFC,0x00,40.0x00,0xC7,0xFF,0xFF,0x07,0xF3,0xCD,0xFC,0x1F,0xFB,0xF7,0xC1,0xDF,0xFF,0xFE,0x00,41.0x01,0xFF,0xDF,0xFF,0x0F,0x87,0xCD,0xF8,0x1F,0xBD,0xFF,0xC1,0xFF,0x8F,0xFF,0x00,42.0x01,0xFF,0xCF,0x8C,0x03,0xFF,0xED,0xF8,0x3F,0xBD,0xFF,0xC1,0xFF,0xFF,0xFF,0x00,43.0x01,0xFB,0xC7,0xFC,0x03,0xFF,0xFD,0xE0,0x3F,0xBF,0xFF,0xC0,0xFB,0xFF,0xCF,0x00,44.0x00,0xE3,0xFF,0xFE,0x0F,0xFF,0x7D,0xC0,0x3F,0xBF,0xFF,0xE0,0x79,0xFC,0x0F,0x00,45.0x00,0x1F,0xFF,0xFE,0x0F,0x0E,0x7D,0xC0,0x3F,0x9F,0xFF,0xE0,0x30,0xFF,0xFE,0x00,46.0x00,0xFF,0xFC,0x3E,0x07,0x60,0x7D,0xF0,0x37,0x9F,0xF8,0xE0,0x3F,0xFF,0xFF,0x00,47.0x00,0xFD,0xFF,0xF0,0x05,0xF7,0xFF,0xF8,0x37,0x8F,0xFC,0x01,0xFF,0xFF,0xFF,0x80,48.0x00,0x01,0xFF,0xFC,0x0F,0xFF,0xF7,0xF8,0x07,0x83,0xFF,0x01,0xFF,0xFF,0xFF,0x80,49.0x00,0xFF,0xFF,0xFC,0x0F,0xFC,0xF1,0xF8,0x07,0x87,0xFF,0x80,0xFF,0xFE,0x7F,0x00,50.0x00,0xFF,0xF8,0x3C,0x0F,0xBD,0xFC,0x00,0x07,0x87,0xDF,0x80,0x7C,0xFC,0x7C,0x00,51.0x00,0x71,0xFF,0xE0,0x0F,0x3F,0xFF,0x80,0x07,0x8F,0xCF,0xC0,0xFC,0xFC,0x7E,0x00,52.0x00,0xC1,0xFF,0xFC,0x0E,0x3F,0xFF,0xF8,0x07,0x8F,0x87,0xC0,0xFF,0xFC,0x3E,0x00,53.0x00,0xDF,0xFF,0xFE,0x0F,0xFF,0xDF,0xF8,0x07,0x9F,0x83,0xC0,0xFF,0xFC,0x3E,0x00,54.0x01,0xFF,0xFF,0xFF,0x07,0xFF,0xCF,0xF8,0x07,0x9F,0x03,0xC0,0xFB,0xFC,0x3E,0x00,55.0x00,0xFF,0xC0,0x1E,0x03,0xF1,0x01,0xF0,0x03,0x8E,0x01,0x80,0x00,0x7C,0x1C,0x00,56.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,57.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,58.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,59.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,60.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};61.62.//图片代码新年进步 128*3263.uchar code Photo2[][16] ={64.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,65.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,66.0x00,0xFF,0xC3,0xF0,0x01,0xFC,0x00,0x00,0x3C,0x00,0xF8,0x00,0x01,0xF8,0x3C,0x00,67.0x00,0xFF,0xE3,0xF8,0x01,0xFE,0x00,0x00,0x3E,0x1C,0xFC,0x00,0x31,0xFC,0xFE,0x00,68.0x00,0x7F,0xF1,0xFC,0x01,0xFE,0x3F,0xE0,0x3F,0x3F,0xFF,0x80,0x7C,0xFF,0xFE,0x00,69.0x00,0xFF,0xF1,0xFC,0x03,0xFF,0xFF,0xF0,0x3F,0x1F,0x7F,0xC0,0x7C,0xFF,0xFE,0x00,70.0x01,0xFF,0xCF,0xFC,0x07,0x8F,0xFF,0xF8,0x0F,0xBE,0xFF,0xC0,0x3E,0xFF,0xFE,0x00,71.0x01,0xFF,0xDF,0xF8,0x0F,0x3F,0xFF,0xF8,0x0F,0xF1,0xFF,0xC0,0x1E,0xFE,0x00,0x00,72.0x01,0x3B,0xFC,0x00,0x0F,0xFF,0xFC,0x00,0x1F,0x3F,0xFC,0x00,0x3E,0xFF,0xFE,0x00,73.0x03,0xB3,0xFC,0x3C,0x0F,0xFF,0xF8,0x00,0x3E,0x3F,0xFF,0x80,0xFE,0xFF,0xFF,0x00,74.0x03,0xFF,0xDE,0xFE,0x07,0xF1,0xFF,0xF0,0x3F,0x3F,0x7F,0xC1,0xFF,0xFF,0xFF,0x00,75.0x01,0xFF,0xFF,0xFF,0x01,0xC3,0xFF,0xF0,0x3F,0xBC,0xFF,0xC1,0xBF,0xFF,0xFF,0x00,76.0x00,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xF8,0x3F,0xBF,0xFC,0x01,0xFF,0xFF,0x3F,0x00,77.0x01,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xF0,0x1F,0xBF,0xFF,0x80,0xFF,0xFC,0x00,0x00,78.0x03,0xFC,0x1F,0xFC,0x07,0xFF,0xFC,0x20,0x3C,0x3C,0x7F,0xC0,0x7C,0xFC,0x0C,0x00,79.0x01,0xFF,0xDF,0x7C,0x03,0xFF,0xFC,0x00,0x38,0x3F,0xFF,0xC0,0x1C,0xFE,0x1E,0x00,80.0x00,0x3F,0xFE,0x7C,0x01,0xFD,0xFC,0x00,0x3F,0xBF,0xFC,0x00,0x3E,0x7E,0x3E,0x00,81.0x00,0xFF,0xFE,0x7C,0x03,0xFD,0xFF,0xE0,0x3F,0xFF,0xFF,0x00,0x3E,0x7E,0x3E,0x00,82.0x03,0xFF,0xFE,0x7C,0x0F,0xFF,0xFF,0xF8,0x1F,0xFC,0xFF,0xC0,0xFE,0xFE,0xFE,0x00,83.0x03,0xFE,0xDE,0x7C,0x0F,0x3F,0xFF,0xF8,0x0F,0xBF,0xFF,0xC0,0xFF,0xFF,0xFC,0x00,84.0x01,0xDE,0xDE,0x7C,0x0F,0xFF,0xFF,0xF8,0x1F,0x3F,0xFF,0xC0,0xFF,0xFF,0xF8,0x00,85.0x01,0xDE,0xFF,0x7C,0x0F,0xFF,0xFF,0xF8,0x1E,0x7F,0xF0,0x00,0x78,0xFF,0xF0,0x00,86.0x01,0xFE,0xFF,0xFC,0x03,0xFF,0xFC,0x00,0x3C,0xFF,0xFF,0xC0,0x83,0xFF,0xE0,0x00,87.0x01,0xFE,0xFF,0xFC,0x00,0xF0,0xFC,0x00,0x3C,0xFF,0xFF,0xE0,0xFF,0xFF,0xC0,0x00,88.0x03,0xFE,0xFF,0xFC,0x00,0x00,0xFC,0x00,0x1F,0xFF,0xFF,0xE0,0x7F,0xFE,0x00,0x00,89.0x01,0xFF,0x7F,0xFC,0x00,0x00,0xFC,0x00,0x1F,0xFF,0xFF,0xC0,0x3F,0xFC,0x00,0x00,90.0x00,0x0E,0x0C,0x7C,0x00,0x00,0x78,0x00,0x07,0x80,0xFF,0x80,0x0F,0xC0,0x00,0x00,91.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,92.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,93.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,94.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,95.0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};96.97.98.void delay_ms(uint ms) // 延时函数 1ms99.{100.uint i,j;101.for(j=0;j<=ms;j++)102.{103.for(i=0;i<=120;i++)104.{}105.}106.}107.108.void delay4us() // 延时函数4Us109.{110._nop_();111._nop_();112._nop_();113._nop_();114.}115.116.void lcd_checkBusy(void) //检测忙标志117.{118.uchar busy;119.do{120.LCD_EN = 0;121.LCD_RS = 0;122.LCD_RW = 1;123.delay4us();124.LCD_EN = 1; //在使能端的一个上升沿读取LCD数据125.busy = P0;126.delay4us();127.LCD_EN = 0;128.}129.while(busy&0x80); //判断最高位是否为0,为0则处于空闲状态130.}131.132.void lcd_wcmd(uchar cmd) //写指令133.{134.lcd_checkBusy(); //检测忙碌状态135.LCD_RS = 0; //RS至低,指令操作136.LCD_RW = 0; //RW至低,写操作137.LCD_EN = 0;138.delay4us();139.P0 = cmd; //指令数据140.delay4us();141.LCD_EN = 1; //给使能端一个上升沿保存数据142.delay4us();143.LCD_EN = 0;144.}145.146.void lcd_wdat(uchar dat) //写数据147.{148.lcd_checkBusy(); //检测忙碌状态149.LCD_RS = 1; //RS至高,数据操作150.LCD_RW = 0;151.LCD_EN = 0;152.P0 = dat; //给LCD要显示的数据153.delay4us();154.LCD_EN = 1; //给使能端一个上升沿保存数据155.delay4us();156.LCD_EN = 0;157.}158.159.void lcd_init() //初始化LCD160.{161.LCD_PSB = 1; //选择并行模式162.lcd_wcmd(0x30); //初级指令集163.delay_ms(5);164.lcd_wcmd(0x0C); //开显示165.delay_ms(5);166.lcd_wcmd(0x01); //清屏167.delay_ms(5);168.}169.170.171.void drawphoto(uchar bmp[][16]) //绘图172.{173.uchar i,j,k;174.175.lcd_wcmd(0x34); //打开高级指令集,关绘图176.177.for(i=0;i<16;i++) //显示上半部分图片178.{179.lcd_wcmd(0x90+i); //输入Y轴坐标180.lcd_wcmd(0x80); //输入下轴坐标181.for(j=0;j<16;j++)182.lcd_wdat(bmp[j]); //写入数据183.delay_ms(1);184.185.}186.187.for(i=0,k=16;i<16,k<32;i++,k++) //显示下半部分图片188.{189.lcd_wcmd(0x80+i); //输入Y轴坐标190.lcd_wcmd(0x88); //输入X轴坐标191.for(j=0;j<16;j++)192.lcd_wdat(bmp[k][j]); //向LCD写入数据193.delay_ms(1);194.}195.lcd_wcmd(0x36); //打开绘图功能,显示所绘图片196.}197.198.void Clear_GDRAM(void) // 清屏,清除GDRAM中的数据,及向GDRAM中全写0199.{200.uchar i,j,k;201.202.lcd_wcmd(0x34); //打开扩展指令集203.i = 0x80;204.for(j = 0;j < 32;j++)205.{206.lcd_wcmd(i++);207.lcd_wcmd(0x80);208.for(k = 0;k < 16;k++)209.{210.lcd_wdat(0x00);211.}212.}213.i = 0x80;214.for(j = 0;j < 32;j++)215.{216.lcd_wcmd(i++);217.lcd_wcmd(0x88);218.for(k = 0;k < 16;k++)219.{220.lcd_wdat(0x00);221.}222.}223.lcd_wcmd(0x30); //回到基本指令集224.}225.226.void main() // 主函数227.{228.uchar i;229.LCD_PSB=1; // 选择显示模式为串行通信模式230.lcd_init(); //初始化液晶,清屏DDRAM231.lcd_wcmd(0x81); //写入要显示字符的地址232.for(i=0;i<10;i++)233.{234.lcd_wdat(hang1); //写入显示字符235.delay_ms(300);236.}237.lcd_wdat(0x2c); //显示“,”。
include<reg52.h>#include <math.h>void lcd_init(void);void clr_lcd(void);void send_com(unsigned char cmd);void send_data(unsigned char dat);void chek_busy(void);void set_xy(unsigned char xpos,unsigned char ypos);void print(unsigned char x,unsigned char y,char* str);void printstr(unsigned char xpos,unsigned char ypos,unsigned charstr[],unsigned char k);unsigned char code buf[4] ={0xbb,0xb6,0xd3,0xad};//欢迎#define DATA P2#define CONTROL P0#define E 7 //并行的使能信号 sbit E = P0^7#define RW 6 //并行的读写信号 sbit RW = P0^6#define RS 5 //并行的指令数据选择信号 sbit RS = P0^5#define PSB 4 //并/串行接口选择 sbit PSB = P0^4#define RST 3 //复位低电平有效 sbit RST = P0^3#define SETB(x,y) (x|=(1<<y))#define CLRB(x,y) (x&=(~(1<<y)))#define CHKB(x,y) (x&(1<<y))/********************测忙碌**********************///测忙碌子程序//RS=0,RW=1,E=H,D0-D7=状态字/************************************************/void chek_busy(void){ unsigned char temp1;//状态信息(判断是否忙)CLRB(CONTROL,RS); // RS = 0;SETB(CONTROL,RW); // RW = 1;SETB(CONTROL,E); // E = 1;do{temp1 = DATA;DATA=0xFF;} while(temp1&0x80);SETB(CONTROL,E); // E = 1;DATA=0xFF;}/********************写命令**********************///写命令子程序///************************************************/void send_com(unsigned char cmd)/*写命令*/{chek_busy();CLRB(CONTROL,RS); //RS = 0;CLRB(CONTROL,RW); //RW = 0;DATA = cmd;SETB(CONTROL,E); //E = 1;CLRB(CONTROL,E); //E = 0;}/********************写数据**********************///写数据子程序///************************************************/void send_data(unsigned char dat){chek_busy();SETB(CONTROL,RS); //RS = 1;CLRB(CONTROL,RW); //RW = 0;DATA = dat;SETB(CONTROL,E); //E = 1;CLRB(CONTROL,E); //E = 0;}/********************初始化**********************///复位、通讯方式选择/************************************************/void lcd_init(void){SETB(CONTROL,RST);//复位RST=1SETB(CONTROL,PSB); //通讯方式为并口PSB = 1//send_com(0x34);//34H--扩充指令操作send_com(0x30);//功能设置,一次送8位数据,基本指令集send_com(0x0C);//0000,1100 整体显示,游标off,游标位置offsend_com(0x01);//0000,0001 清DDRAMsend_com(0x02);//0000,0010 DDRAM地址归位send_com(0x80);//1000,0000 设定DDRAM 7位地址000,0000到地址计数器AC }/*******************************************************************/ // 设置显示位置 xpos(1~16),tpos(1~4)/*******************************************************************/ void set_xy(unsigned char xpos,unsigned char ypos){switch(ypos){case 1:send_com(0X80|xpos);break;case 2:send_com(0X90|xpos);break;case 3:send_com(0X88|xpos);break;case 4:send_com(0X98|xpos);break;default:break;}}/*******************************************************************/ // 在指定位置显示字符串/*******************************************************************/ void print(unsigned char x,unsigned char y,char* str){unsigned char lcd_temp;set_xy(x,y);lcd_temp=*str;while(lcd_temp != 0x00){send_data(lcd_temp);lcd_temp=*(++str);}}/********************写字符串******************///写字符串子程序//xpos1取0~7共八列,ypos1取0~3共四行。
/*以下程序是自己在做天津市TI电设时调试的12864程序,每一部分都亲自调试过,功能都可以实现,建议使用者先花一点时间把程序看懂,不是很难。
程序里有许多注释掉的函数,都是相关的一些测试函数,使用者可根据需要,解冻相关测试函数,来调试一下功能。
当然,前提还是你要先熟悉一下全部的程序结构,不然很可能改动出现错误。
实现功能:画点,画线(水平线、垂直线、任意指定首尾坐标的斜线、折线)、画圆,键盘控制上下左右来画任意图形,以及指定一初始点后按使用者指定的路径自动完成一副图形(譬如矩形、三角形,更复杂的可由使用者继续优化算法。
)*/#include <stdio.h>#include <math.h>#include <reg52.h>#include <string.h>/******************************************************************//* 定义接口信息*//******************************************************************/sbit RS =P2^4; // 并行:指令(H)/数据(L)选择;串行:片选信号(CS)sbit WRD=P2^5; //并行:读写选择;串行:数据口(SID)sbit E= P2^6; // 并行:使能信号;串行:时钟信号(SLK)sbit PSB=P2^1; // 选择并口或者串口工作模式sbit RES=P2^3; // 复位信号,低电平有效sbit key1=P3^0; //定义按键位置sbit key2=P3^1;sbit key3=P3^2;sbit key4=P3^3;/******************************************************************//* 定义数组*//******************************************************************/unsigned char code pic2[];void TransferData(char data1,bit DI);void display(void);void delayms(unsigned int n);void delay(unsigned int m);/******************************************************************//* 液晶初始化-图形*//******************************************************************/void initina2(void) //LCD显示图片(扩展)初始化程序{delay(40); //大于40mS的延时程序PSB=1; //设置为8BIT并口工作模式delay(1); //延时RES=0; //复位delay(1); //延时RES=1; //复位置高delay(10);TransferData(0x36,0); //Extended Function Set RE=1: extended instructiondelay(100); //大于100uS的延时程序TransferData(0x36,0); //Extended Function Set:RE=1: extended instruction setdelay(37); ////大于37uS的延时程序TransferData(0x3E,0); //EXFUNCTION(DL=8BITS,RE=1,G=1)delay(100); //大于100uS的延时程序TransferData(0x01,0); //CLEAR SCREENdelay(100); //大于100uS的延时程序}/****************************************************************************** **///图形区清RAM函数/****************************************************************************** */void LCD_ClearBMP( void ){unsigned char i,j;TransferData(0x34,0); //8Bit扩充指令集,即使是36H也要写两次TransferData (0x36,0); //绘图ON,基本指令集里面36H不能开绘图for(i=0;i<32;i++) //12864实际为256x32{TransferData(0x80|i,0); //行位置TransferData(0x80,0); //列位置for(j=0;j<32;j++) //256/8=32 byteTransferData(0,1);}}/******************************************************************//******************************************************************/ void v_Lcd12864CheckBusy_f( void ) //忙检测函数{unsigned int nTimeOut = 0;P0 = 0x80 ;//P0=0x80WRD= 1 ; //io_LCD12864_RW= 1,读RS=0; //io_LCD12864_RS=0,指令E=0 ; //io_LCD12864_EN=0,E=1 ; //io_LCD12864_EN=1,使能while((P0==0x80)&&(++nTimeOut!=0));//在P0==0x80时,等待E=0; //io_LCD12864_EN=0,}// 读取一个字节unsigned char u8_Lcd12864ReadByte_f( void ){unsigned char byReturnV alue ;v_Lcd12864CheckBusy_f();P0 = 0xff ;//P0=0xffRS=1; //RS=1,指令WRD=1; //RW=1,读E=0; //EN=0E=1; //EN=1byReturnV alue = P0 ;//byReturnV alue=P0delay(1);E=0; //EN=0;return byReturnV alue;}/******************************************************************//******************************************************************/void TransferData(char data1,bit DI) //传送数据或者命令,当DI=0是,传送命令,当DI=1,传送数据.{//char buffer;WRD=0;RS=DI;delay(1);//buffer = data1;//P0 = buffer;P0 = data1;/*count++;if(count == 14){P0= 0x00;count=0;} */E=1;delay(1);E=0;}/****************************************************************************** ********/// 延时函数/****************************************************************************** ********/void delayms(unsigned int n) //延时10×n毫秒程序{unsigned int i,j;for(i=0;i<n;i++)for(j=0;j<2000;j++);}void delay(unsigned int m) //延时程序{unsigned int i,j;for(i=0;i<m;i++)for(j=0;j<10;j++);}/******************************************************************/// 画点函数/******************************************************************/ void v_Lcd12864DrawPoint_f( unsigned char X, unsigned char Y, unsigned char Color ) {unsigned char Row,Tier,Tier_bit;//Tier_bit的作用:确定该位置是低八位,还是高八位unsigned char ReadOldH, ReadOldL ;TransferData( 0x34,0 ) ; //使用扩充指令集delay(1);TransferData( 0x36,0 ) ; //使用扩充指令集,图像显示开?delay(1);Tier = X >> 4 ;//X的范围是0-127,即0x7f.Tier 除以16,获取它的字。
12864液晶4位并行接口驱动程序#include#include#include#include#define uchar unsigned char#define uint unsigned int#define DATA 1#define COMMAND 0sbit rs=P2^4;sbit rw=P2^5;sbit en=P2^6;sbit psb=P2^1;sbit rst=P2^3;sbit key=P1^0;uchar code AC_TABLE[]={0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, //第一行汉字位置0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, //第二行汉字位置0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, //第三行汉字位置0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, //第四行汉字位置};uchar code str1[]="黄河远上白云间,一片孤城万仞山。
羌笛何须怨杨柳,春风不度玉门关。
";uchar code bmp1[]={//********************************************************//// 位图点阵占用1024字节//********************************************************//0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0 xFF,0x FF,0xFF,0xFF,0x80,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x70,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x3F,0xC0,0x00,0x07,0x07,0x00,0x04,0x01,0x00,0x 00,0x38,0x60, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x78,0xE0,0x00,0x3F,0x83,0x80,0x06,0x03,0x80,0x 00,0x1C,0x70, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x02,0x38,0x70,0x00,0xFF,0x07,0x80,0x06,0x39,0x80,0x 00,0x1F,0x70, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x02,0x1C,0x30,0x00,0x7C,0x0E,0x00,0x06,0x19,0xC0,0 x00,0x1F,0x8 0,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x02,0x1C,0x30,0x00,0x3E,0x1C,0x00,0x06,0x1F,0xC0,0x 00,0x7F,0x0 0,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x03,0x3E,0x30,0x00,0x62,0x1A,0x00,0x0F,0x79,0x00,0x 03,0xFE,0x00 ,0x00,0x01,0x80,0x00,0x00,0x60,0x0F,0x00,0x3F,0x00,0x00,0x00,0x3C,0x 00,0xC0,0x00 ,0x00,0x01,0x80,0x07,0x76,0x18,0x00,0xC3,0xC1,0x00,0x1F,0xFB,0x00,0x 03,0xFE,0x0 0,0x00,0x01,0x80,0x00,0x01,0xE0,0x3F,0xC0,0xF1,0xC0,0x00,0x00,0xF0,0x 01,0xC0,0x0 0,0x00,0x01,0x80,0x07,0x6E,0x18,0x00,0xCF,0xC1,0x80,0x7E,0x3F,0x80,0x 01,0xE2,0x0 0,0x00,0x01,0x80,0x00,0x07,0xE0,0x7F,0xE0,0xE0,0xE0,0x00,0x03,0xC0,0x 03,0xC0,0x0 0,0x00,0x01,0x80,0x07,0x7F,0x98,0x00,0xFE,0x83,0x81,0xFC,0x1E,0xC0,0x 00,0x83,0x0 0,0x00,0x01,0x80,0x00,0x0F,0xE0,0x63,0xE1,0xE0,0xE0,0x00,0x07,0x00,0x 03,0xC0,0x0 0,0x00,0x01,0x80,0x06,0xFF,0xD8,0x01,0xFA,0x87,0x00,0xFD,0xF8,0xC0,0x 01,0x73,0x0 0,0x00,0x01,0x80,0x00,0x01,0xE0,0xC1,0xE1,0xE0,0xE0,0x00,0x0F,0x00,0x 07,0xC0,0x0 0,0x00,0x01,0x80,0x0F,0xD9,0xD8,0x03,0xE3,0x0E,0x80,0xFE,0x7E,0xC0,0 x03,0xF9,0x8 0,0x00,0x01,0x80,0x00,0x01,0xE0,0x01,0xE1,0xF0,0xE0,0x00,0x1E,0x00,0x 0B,0xC0,0x0 0,0x00,0x01,0x80,0x0D,0xB8,0x18,0x1F,0xC3,0x08,0xC0,0x0E,0x6D,0x80,0 x03,0xF1,0x8 0,0x00,0x01,0x80,0x00,0x01,0xE0,0x01,0xE0,0xFD,0xC7,0xEF,0x9E,0x00,0x 13,0xC0,0x0 0,0x00,0x01,0x80,0x0D,0xFE,0x18,0x0F,0xC2,0x10,0xE0,0x1C,0x3F,0x00,0x 03,0xE0,0xC 0,0x00,0x01,0x80,0x00,0x01,0xE0,0x01,0xC0,0xFF,0x83,0xC6,0x1F,0xE0,0x 13,0xC0,0x0 0,0x00,0x01,0x80,0x0D,0xCE,0x18,0x06,0xC2,0x01,0xC0,0x38,0x3E,0x00,0 x00,0xE8,0xC 0,0x00,0x01,0x80,0x00,0x01,0xE0,0x01,0x80,0x3F,0x81,0xE4,0x3C,0x78,0x 23,0xC0,0x00 ,0x00,0x01,0x80,0x0C,0x4C,0x18,0x00,0xC2,0x03,0x80,0x78,0x1F,0xF0,0x 00,0xFC,0x6 0,0x00,0x01,0x80,0x00,0x01,0xE0,0x03,0x80,0x3F,0xC1,0xE8,0x3C,0x78,0x 43,0xC0,0x0 0,0x00,0x01,0x80,0x0C,0x5E,0x18,0x00,0xC2,0x07,0x00,0x68,0x3F,0xF8,0x 03,0xFC,0x2 2,0x00,0x01,0x80,0x00,0x01,0xE0,0x03,0x00,0x6F,0xC0,0xF0,0x3C,0x3C,0x 83,0xC0,0x0 0,0x00,0x01,0x80,0x06,0x3F,0x38,0x01,0x82,0x0E,0x00,0x09,0xF8,0x00,0x 03,0xC0,0x32 ,0x00,0x01,0x80,0x00,0x01,0xE0,0x06,0x00,0xC3,0xE0,0x78,0x3C,0x3C,0 xFF,0xF0,0x0 0,0x00,0x01,0x80,0x07,0x10,0x38,0x00,0x82,0x1C,0x00,0x0B,0x99,0xC0,0 x03,0x00,0x1A ,0x00,0x01,0x80,0x00,0x01,0xE0,0x0C,0x11,0xC3,0xE0,0x78,0x3C,0x3C,0 xFF,0xF0,0x0 0,0x00,0x01,0x80,0x03,0xFF,0xF0,0x00,0x02,0x38,0x00,0x08,0x30,0xE0,0x 02,0x00,0x1E ,0x00,0x01,0x80,0x00,0x01,0xE0,0x08,0x11,0xC1,0xE0,0x7C,0x3C,0x3C,0 xFF,0xF0,0x0 0,0x00,0x01,0x80,0x01,0xEF,0xF0,0x00,0x00,0xE0,0x00,0x08,0xE0,0x60,0x 00,0x00,0x0E ,0x00,0x01,0x80,0x00,0x01,0xE0,0x1F,0xF1,0xC1,0xE0,0xBC,0x1C,0x3C,0 x03,0xC0,0x 00,0x00,0x01,0x80,0x00,0x03,0xE0,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x 00,0x00,0x07, 0x00,0x01,0x80,0x00,0x01,0xE0,0x3F,0xE1,0xC1,0xC0,0x9E,0x1E,0x38,0x 03,0xC0,0x0 0,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x01, 0x00,0x01,0x80,0x00,0x01,0xF0,0x7F,0xE0,0xE3,0x83,0x1F,0x0E,0x70,0x 03,0xC0,0x0 0,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x0F,0xFC,0xFF,0xE0,0x3F,0x07,0xDF,0x83,0xE0,0x 03,0xC0,0x0 0,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00, 0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x60,0x00, 0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0 xFF,0x FF,0xFF,0xFF,};void writeByte(uchar flag,uchar content);void delayUs(uint z){while(z--);}void delay1MS(uchar x){uchar k,j;x=x<<1;for(k=0;k<x;k++)< p="">for(j=0;j<255;j++)_nop_();}/*------------------------------------------------检测忙位------------------------------------------------*/void CheckBusy(){uchar temp1,temp2;do{en=0;delayUs(5);rs=0;rw=1;en=1;temp1=P0; //读高字节delayUs(10);en=0;delayUs(5);rs=0;rw=1;en=1;temp2=P0; //读低字节en=0;/*数据处理*/temp1=temp1&0xf0;temp2=(temp2&0xf0)>>4;temp1=(temp1+temp2);}while((temp1&0x80)==0x80);}void init(){rst=0;delayUs(40);rst=1;delayUs(40);psb=1;delayUs(8);writeByte(COMMAND,0x20); //基本指令集4bit数据delayUs(8);writeByte(COMMAND,0x01);delayUs(8);writeByte(COMMAND,0x06);delayUs(8);writeByte(COMMAND,0x0c);delayUs(8);}/************************************************************** ************************** *** 函数名称:SendByte* 功能描述:串口发送一个字节*flag=1,写入数据。
#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();}}}}}。