由LCD12864初探嵌入式菜单设计(完全资料)
- 格式:pdf
- 大小:319.18 KB
- 文档页数:33
目录前言 (2)一、U-Boot分析 (3)1、引导程序U-Boot第一阶段分析 (3)2、引导过程 (4)3、程序流程图 (8)二、程序设计 (8)三、心得体会 (9)前言ARM嵌入式处理器已被广泛应用于消费电子厂品、无线通信、网络通信和工业控制等领域。
在嵌入式操作系统中,Linux、Vxworks、WinCE三足鼎立,其中Linux由于其开源性、稳定性、安全性、可裁剪性更是一支独秀。
在嵌入式系统中,如何实现在ARM平台下Linux操作系统的引导工作是嵌入式技术开发的重要环节。
BootLoader就是在操作系统内核运行之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。
在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader 来完成。
比如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
一、U-Boot分析嵌入式Linux系统中常用的Bootloader引导程序有U-Boot,redboot, blob 和vivii等,其中U-Boot遵循GPL条款的开放源码项目,功能最为强大,U-Boot 对PowerPC系列处理器支持最丰富,同时还支持MIPS,x86,ARM,XScale等诸多常用系列的处理器;U-Boot引导程序分为Stage1和Stage2量大部分,Stage1中主要包括设备初始化、中断设置、时间设置和储存器初始化等工作,并且采用汇编语言实现,而一些通用功能大多采用C语言实现,放在Stage2中。
1、引导程序U-Boot第一阶段分析Stage1的代码在CPU/arm920t/start.s中定义,它包括从系统上电后在0x00000000地址开始执行的部分。
目录设计总说明 (I)INTRODUCTION (II)1 绪论 (1)1.1课题背景及研究意义 (1)1.2课题研究的主要内容 (1)1.3国内外发展状况与存在问题 (1)2 总体方案设计与论述 (2)2.1 系统需求分析 (2)2.2 系统总体方案设计 (2)2.2.1 设计方案论证 (2)2.2.2总体结构框图 (3)3系统单元模块设计 (3)3.1系统硬件示意图 (3)3.2主控芯片(STC89C52模块)[5] (4)3.3 时钟控制模块[13] (6)3.3.1 DS1302简介 (6)3.3.2引脚及功能表 (7)3.3.3工作原理 (7)3.3.4 DS1302电路设计图[9] (8)3.4 温度控制模块 (8)3.5 12864接口电路模块 (9)3.6 按键电路模块 (9)3.7 电源电路模块 (10)3.8 印制电路板[9] (10)4系统整体调试与结果分析 (11)4.1 系统总体程序流程介绍 (11)4.2 按键程序设计 (13)4.3 12864驱动程序设计[15] (14)4.3.1 ST7920芯片介绍[14] (14)4.3.2 ST7920驱动程序设计 (17)4.4 12864应用程序设计 (20)4.4.1 文字显示程序设计 (20)4.4.2 点、线显示程序设计 (22)4.4.3 图形、图片显示程序设计 (23)4.5 菜单程序设计 (26)5设计调试及进一步研究 (28)5.1 系统测试 (28)5.1.1 软件调试 (28)5.1.2 硬件调试 (29)5.2 进一步研究的工作 (30)6总结 (30)鸣谢................................................................................................................................ 错误!未定义书签。
图形LCD模块的菜单方式人机交互界面摘要:在以单片机为核心的嵌入式应用中,友好的人机互界面起着十分重要的作用。
笔者在设计中使用12864图形LCD模块实现一种中文窗口菜单界面,设计中使用的方法具有普遍性意义。
关键词:人机交互界面图形LCD模块数据结构窗口菜单随着液晶显示技术的进步,高质量的液晶显示模块会被日趋广泛地应用于各种嵌入式系统中。
在系统整体设计中,人机交互界面的设计往往占据着很大一部分工作,现以某嵌入式系统的人机交互部分为例,介绍一种使用12864B图形LCD模块实现中文窗口菜单界面的方法。
摘要:在以单片机为核心的嵌入式应用中,友好的人机互界面起着十分重要的作用。
笔者在设计中使用12864图形LCD模块实现一种中文窗口菜单界面,设计中使用的方法具有普遍性意义。
关键词:人机交互界面图形LCD模块数据结构窗口菜单随着液晶显示技术的进步,高质量的液晶显示模块会被日趋广泛地应用于各种嵌入式系统中。
在系统整体设计中,人机交互界面的设计往往占据着很大一部分工作,现以某嵌入式系统的人机交互部分为例,介绍一种使用12864图形LCD模块实现中文窗口菜单界面的方法。
1 图形LCD模块12864简介12864模块是单色图形点阵液晶显示模块,点阵数为64×128,其点阵存储区如图1所示。
模块点阵分为左右两边,左右两边的结构是完全一样的。
对模块的点阵存储区进行读写操作时,由CS1、CS2进行片选,高电平有效。
模块中每8行为1页,页地址由X确定;Y确定点阵的列号,点阵数据的每一个字节所在的位置由(CSi,X,Y)唯一确定。
字节中的每一位对应着相应的像素,为1显示该像素;为0则不显示。
液晶显示模块工作时,逐行扫描点阵存储区。
首先被扫描的行显示在LCD屏幕的第1行上,其余行则依次顺序显示。
“扫描起始行”可以通过Z地址寄存器来设置。
Z可以是0~63的任意一行,如Z=56时,则显示在LCD屏幕上的次序从上到下分别为:56,57,…,62,63,0,1,2,…,54,55该模块的这一功能为窗口的滚屏提供了便利。
嵌入式菜单设计方案嵌入式菜单设计方案嵌入式菜单是指在电子设备的显示屏上呈现的一组选项,用户可以通过输入设备(如键盘、鼠标、触摸屏等)来选择并执行相关操作。
嵌入式菜单设计的目标是提供用户友好的界面,使用户可以方便、快速地获得所需的信息和功能。
设计嵌入式菜单时,需要考虑以下几个方面:1.页面布局和可视化效果页面布局应具有良好的可读性和易于操作性,菜单选项应按照一定的逻辑顺序排列,避免过多信息在一个页面上导致混乱。
可以使用不同的标签、颜色、大小等来区分不同的菜单选项,增加可视化效果,提升用户体验。
2.选项组织和层次结构根据功能的相似性和重要性,将菜单选项分组组织,形成层次结构。
常见的设计方法有水平菜单和垂直菜单两种,可以根据设备的屏幕大小和用户习惯选择合适的组织形式。
同时,可以使用意义明确的图标或文字来表示每个选项,提高用户理解和记忆的效果。
3.使用标准化和一致性在设计嵌入式菜单时,应遵循标准化的设计原则和操作规范,与其他应用程序或系统保持一致,减少用户的学习成本。
可以引用已有的界面模式和设计规范,借鉴其他成功的菜单设计案例,提高用户的熟悉度和可用性。
4.提供搜索和过滤功能随着菜单选项的增多,用户常常需要花费大量时间在菜单中寻找所需的选项。
为了提高效率,可以设计搜索和过滤功能,允许用户根据关键词、分类或其他指标来快速定位所需的选项,减少用户的犹豫和焦虑。
5.响应式和自适应设计当设备屏幕的尺寸和分辨率发生变化时,嵌入式菜单应能够自动适应并进行相应的调整,以保证页面的合理显示和操作的便捷性。
可以使用响应式设计和流式布局等技术来实现菜单的自适应性。
以上是嵌入式菜单设计的一般方案,具体的设计细节和实施过程需要根据具体的应用场景和用户需求来定。
在设计过程中,可以进行原型设计和用户测试,根据用户的反馈和需求进行优化和调整,以提供更好的用户体验和功能性。
一起来学LCD12864菜单程序(包含完整程序)一起来学LCD12864菜单程序(包含完整程序)/*-------------------------------------------项目名:家电中央控制系统工程程序名:显示MCU总体程序编写人:杜洋初写时间:2005年9月5日晚20时程序功能:实现液晶、语音部分的人机对话和总线的通信实现方法:用中断实现总线接收CPU说明:89S5212MHZ晶振接口说明:(详见初定义)信息说明:修改日志:NO.1--------------------------------------------*/;----------------------------------------初定义LCDDAT EQU P2RS EQU P3.5RW EQU P3.6E EQU P3.7REDLED EQU P3.4BACKLED EQU P3.1PLAY EQU P1.7STOPIN EQU P3.0LIN EQU P3.2SPDAT EQU P1XX2 EQU P0.0LT_RAM EQU 30HLR_RAM EQU 40HSP_RAM EQU 20HDIS1_RAM EQU 50HDIS2_RAM EQU 70HDIS3_RAM EQU 60HDIS4_RAM EQU 80HRR1 EQU 26HRR3 EQU 21HRR4 EQU 22HT0_RAM EQU 23HQR3_RAM EQU 24HQR2_RAM EQU 25HLCDDISPLAY EQU 26H ;菜单显示移位寄存器MENU_RAM EQU 27H;菜单位置寄存器ONOFFLCD EQU 28H;-------------------------------------程序入口ORG 0000HJMP LCD_STARTORG 0003HJMP LIN_INT0ORG 000BHJMP LED_T0ORG 0030H;--------------------------------------主程序开始LCD_START br>SETB PLAYMOV T0_RAM,#250MOV TMOD,#01HSETB ET0MOV TL0,#0B0H ;50MS 定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值CLR IT0SETB EX0SETB TR0SETB EAMOV DPTR,#TAB_0CALL START_LCD;-----自检程序CALL DL1SMOV MENU_RAM,#00HMOV DPTR,#TAB_HCALL START_LCDCLR LCDDISPLAY;--------------------------------------主循环体程序LCD_LOOP br>JB ONOFFLCD,DISPLAY_PROLCD_LOOP_1br>JMP LCD_LOOP;---------------------------- 菜单显示处理DISPLAY_PRO br>MOV A,MENU_RAMMOV DPTR,#MENUTAB_HOSTRLC AJMP @A+DPTRMENUNEXT br>CALL START_LCDCLR LCDDISPLAYCLR ONOFFLCDJMP LCD_LOOP;-------------------------MENUTAB_HOST:JMP HOST_H ;主菜单JMP HOST_1 ; 1,控制JMP HOST_2 ; 2,设置JMP HOST_3 ; 3,智能JMP HOST_4 ; 4,帮助<。
编写者:董新凯2011.7.20 仅供交流#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;//This指针指向本项菜单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 MenuItem *Menu_point=MainMenu;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=16;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=16;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=16;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=16;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 方框右下角横坐标Yend 方框右下角纵坐标*/{UINT8 page,num,xend,yend;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);for(num=0;num<Menu_point->MenuCount;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); */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++;if(key_number>Menu_point->MenuCount){key_number=1;Menu_point=Menu_point->This;}Menu_point=Menu_point->This+key_number-1;MenuBox(Menu_point->Local_x,Menu_point->Local_y);break;case 6:key_number--;if(key_number==0){key_number=Menu_point->MenuCount;}Menu_point=Menu_point->This+key_number-1;MenuBox(Menu_point->Local_x,Menu_point->Local_y);break;case 5://enterif(Menu_point->ChildrenMenu!=NULL){Menu_point=Menu_point->ChildrenMenu;key_number_store=key_number;key_number=0;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=key_number_store;Menu_point=Menu_point->ParentMenu+key_number-1;MenuBox(Menu_point->Local_x,Menu_point->Local_y);}break;}}}.。
128*64L C D液晶显示屏中文资料一、概述二、带中文字库的128X64是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64, 内置8192个16*16点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。
可以显示8×4行16×16点阵的汉字. 也可完成图形显示.低电压低功耗是其又一显著特点。
由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。
三、基本特性:(1)、低电源电压(VDD:+3.0--+5.5V)(2)、显示分辨率:128×64点(3)、内置汉字字库,提供8192个16×16点阵汉字(简繁体可选) (4)、内置 128个16×8点阵字符(5)、2MHZ时钟频率(6)、显示方式:STN、半透、正显(7)、驱动方式:1/32DUTY,1/5BIAS (8)、视角方向:6点(9)、背光方式:侧部高亮白色LED,功耗仅为普通LED的1/5—1/10 (10)、通讯方式:串行、并口可选(11)、内置DC-DC转换电路,无需外加负压(12)、无需片选信号,简化软件设计(13)、工作温度: 0℃ - +55℃ ,存储温度: -20℃ - +60℃模块接口说明:*注释1:如在实际应用中仅使用串口通讯模式,可将PSB接固定低电平,也可以将模块上的J8和“GND”用焊锡短接。
*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。
*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK用焊锡短接。
2.2并行接口管脚号管脚名称电平管脚功能描述1 VSS 0V 电源地2 VCC 3.0+5V 电源正3 V0 - 对比度(亮度)调整4 RS(CS)H/L RS=“H”,表示DB7——DB0为显示数据RS=“L”,表示DB7——DB0为显示指令数据5 R/W(SID) H/L R/W=“H”,E=“H”,数据被读到DB7——DB0R/W=“L”,E=“H→L”,DB7——DB0的数据被写到IR或DR6 E(SCLK) H/L 使能信号7 DB0 H/L 三态数据线8 DB1 H/L 三态数据线9 DB2 H/L 三态数据线10 DB3 H/L 三态数据线11 DB4 H/L 三态数据线12 DB5 H/L 三态数据线13 DB6 H/L 三态数据线14 DB7 H/L 三态数据线15 PSB H/L H:8位或4位并口方式,L:串口方式(见注释1)16 NC - 空脚17 /RESET H/L 复位端,低电平有效(见注释2)18 VOUT - LCD驱动电压输出端19 A VDD 背光源正端(+5V)(见注释3)20 K VSS 背光源负端(见注释3)*注释1:如在实际应用中仅使用并口通讯模式,可将PSB接固定高电平,也可以将模块上的J8和“VCC”用焊锡短接。
LCD12864多级菜单课程设计一、课程目标知识目标:1. 理解LCD12864液晶显示屏的基本工作原理和接口技术。
2. 掌握多级菜单的设计方法,包括菜单结构、界面布局及跳转逻辑。
3. 学会编写程序代码实现LCD12864多级菜单的显示与操作。
技能目标:1. 能够运用所学知识设计出结构清晰、界面友好的多级菜单界面。
2. 熟练使用相关编程语言和开发工具,完成程序编写和调试。
3. 培养学生的动手操作能力和团队协作能力,提高问题解决能力。
情感态度价值观目标:1. 培养学生对电子技术和编程的兴趣,激发学习热情。
2. 培养学生严谨、细心的学习态度,养成良好的编程习惯。
3. 增强学生的创新意识,鼓励学生敢于尝试、勇于实践。
分析课程性质、学生特点和教学要求,本课程目标旨在帮助学生在掌握LCD12864多级菜单设计的基础上,提高实际操作能力,培养学生的创新思维和团队协作精神。
通过本课程的学习,使学生能够在实际项目中运用所学知识,为我国电子信息产业的发展做出贡献。
同时,注重培养学生的情感态度价值观,使学生在学习过程中形成积极向上的人生态度。
二、教学内容1. LCD12864液晶显示屏原理介绍:包括显示原理、接口技术、指令集等基本知识。
- 教材章节:第三章第二节- 内容列举:LCD12864工作原理、接口类型、指令功能。
2. 多级菜单设计方法:- 教材章节:第五章- 内容列举:菜单结构设计、界面布局、跳转逻辑、操作流程。
3. 编程实现LCD12864多级菜单:- 教材章节:第六章- 内容列举:编程环境搭建、代码编写、程序调试、功能实现。
4. 实例分析与操作:- 教材章节:第七章- 内容列举:典型多级菜单实例、操作方法、优化技巧。
5. 动手实践与团队协作:- 教材章节:第八章- 内容列举:实践任务分配、协作流程、成果展示。
根据课程目标,教学内容分为五个部分,确保学生系统掌握LCD12864多级菜单设计的相关知识。
教学大纲明确指出各部分内容的安排和进度,以及教材对应的章节和具体内容。
嵌入式lcd显示课程设计嵌入式LCD显示课程设计一、引言嵌入式系统是应用广泛的一种计算机系统,其特点是紧凑、低功耗、高性能,并能够适应各种环境。
嵌入式系统广泛应用于智能家居、汽车电子、医疗设备等领域。
而LCD显示技术是嵌入式系统中常用的输出方式,具有低功耗、高分辨率、色彩鲜艳等优点。
本文将围绕嵌入式LCD显示课程设计展开讨论。
二、嵌入式LCD显示的原理嵌入式LCD显示是通过将图像信息转换为电信号,再通过驱动电路控制液晶显示屏的液晶分子取向,从而实现图像显示。
液晶显示屏由像素组成,每个像素点由红、绿、蓝三原色的亮度组合而成,通过调节每个像素点的亮度,可以呈现出丰富的色彩。
LCD显示的原理主要包括液晶分子取向、背光源、色彩控制等方面。
三、嵌入式LCD显示的应用嵌入式LCD显示广泛应用于各个领域,例如智能手机、平板电脑、车载导航等。
在智能手机中,LCD显示屏可以通过触摸屏实现用户的交互操作,同时显示丰富的图像和文字信息。
在平板电脑中,LCD显示屏不仅可以实现高清视频播放,还可以满足用户对于图像和文字的显示需求。
在车载导航系统中,LCD显示屏可以显示地图信息、导航路径等,方便驾驶员实时掌握导航情况。
四、嵌入式LCD显示的设计要点1. 选择合适的LCD显示屏:根据应用需求选择合适的尺寸、分辨率和色彩深度的LCD显示屏,以满足图像显示的要求。
2. 驱动电路设计:设计合理的驱动电路,使得LCD显示屏能够正常工作。
驱动电路通常包括像素驱动、背光源控制、信号转换等模块。
3. 软件设计:根据LCD显示屏的规格和接口要求,编写相应的驱动程序,实现图像显示和操作控制。
软件设计包括像素控制、色彩控制、触摸屏交互等方面。
4. 节能设计:LCD显示屏的功耗较低,但在实际应用中,为了进一步降低嵌入式系统的功耗,可以采取一些节能措施,如调节背光亮度、降低刷新频率等。
五、嵌入式LCD显示课程设计实例以智能家居智能开关为例,进行嵌入式LCD显示课程设计。
我的lcd12864菜单大致框架2019-07-12 00:24:06| 分类:ELECTRONIC | 标签:|字号大中小订阅lcd12864菜单大致框架算是完成了,主要实现了两个功能----反白,翻页。
原本是想做一个多级---起码也得二级----菜单,但有意外的时间安排,故暂且放下。
个人认为比较费脑筋的是反白功能的制作。
首先12864并没有专门为用户准备单行的反白,要么一三行一块反,要么二四一块。
所以得参照前人的方法,即将字符显示与图像显示结合,在需要反白的部分用绘图功能全写上0xff,有自带的异或逻辑能成功反白。
这部分让我摸索了几小时。
其次是这种反白实现之前,得先给原来的图像全清掉,也正是这一步让89c52耗费了不少时间,选项切换间居然要用1s 的时间。
这是不能忍的啊。
所以自己想了一个办法,让图像整体清除换成部分清除。
思路是在选项光标变量Index_P 外再添一记录变量----Index_P_Pre-----以记录上一次选项所在位置,然后在清除图像的时候专门清除Index_P_Pre 对于的图像痕迹,这样就将清屏所需的时间减少了3/4。
好了,这个菜单模块总共用了6KB。
对于64KB的89C52来说还有很多空间,自己也可以放心弄下去。
以后的工作就是整合了。
/*Index_Num 数组元素最大序号Index 数组元素当前序号Index_P 选中项序号Index_P_Pre 上一选中项序号,用于快速清理上次所画下的图案*/#include <reg52.h>#include <intrins.h>#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};#define LCD_data P0 //数据口#define Index_Num 8typedef unsigned char uchar;typedef unsigned int uint;sbit Key1 = P1^0;sbit Key2 = P1^1;sbit LCD_RS = P2^6; //寄存器选择输入cssbit LCD_RW = P2^5; //液晶读/写控制sidsbit LCD_EN = P2^7; //液晶使能控制clksbit LCD_PSB = P3^2; //串/并方式控制sbit LCD_RST = P3^7; //液晶复位端口bdata uchar DataBuf;uint Index,Index_P_Pre;uint Index_P=0;uchar code Weibo[][16]={"hello","呀咦晗昱","weibo","/maixianyu","blog.163","maixianyu@126","123","456","789"};////////////////////////////////////////////// 200usvoid delay(int ms){uchar t;while(ms--){for(t=0; t<20; t++) ;}}////////////////////////////////////////////////////////////////// void Lcd_Write_8bit(uchar msg){uint i;uchar DataBuffer;DataBuffer=msg;for(i=0;i<8;i++){LCD_RW=(bit)(DataBuffer&0x80);LCD_EN=1;_nop_();_nop_();LCD_EN=0;_nop_();_nop_();DataBuffer<<=1;}}/////////////////////////////////////////uchar Lcd_Rec(uint RS){uint i;uchar Data_H,Data_L;LCD_RS=1;if(RS)Lcd_Write_8bit(0xfe);elseLcd_Write_8bit(0xfc);delayNOP();for(i=0;i<8;i++){LCD_EN=1;Data_H=(Data_H<<1)|LCD_RW;LCD_EN=0;}delayNOP();for(i=0;i<8;i++){LCD_EN=1;Data_L=(Data_L<<1)|LCD_RW;LCD_EN=0;}LCD_RS=0;DataBuf=(Data_H<<4)|Data_L;return DataBuf;}/////////////////////////////////////////bit Lcd_Busy(){return Lcd_Rec(0)&0x80;}/////////////////////////////////////////void Lcd_Write(uchar msg,uint dc){ //if dc equals 0,msg is a kind of cmd.while(Lcd_Busy());if(dc==0)DataBuf=0xf8;elseDataBuf=0xfa;delayNOP();LCD_RS=1;Lcd_Write_8bit(DataBuf);delayNOP();DataBuf=msg&0xf0;Lcd_Write_8bit(DataBuf);delayNOP();DataBuf=(msg<<4)&0xf0;Lcd_Write_8bit(DataBuf);LCD_RS=0;}////////////////////////////////////////////////////void Disp_black() //清理上一次画下的痕迹{uchar i,j;Lcd_Write(0x34,0); //写数据时,关闭图形显示if(Index_P_Pre<2){for(i=0+16*Index_P_Pre; i<16+16*Index_P_Pre; i++){Lcd_Write(0x80+i,0);Lcd_Write(0x80,0);for(j=0;j<16;j++)Lcd_Write(0x00,1);}}else{for(i=0+16*(Index_P_Pre-2);i<16+16*(Index_P_Pre-2);i++){Lcd_Write(0x80+i,0);Lcd_Write(0x88,0);for(j=0;j<16;j++)Lcd_Write(0x00,1);}}Lcd_Write(0x36,0); //写完数据,开图形显示}void convertChar(uchar CX) // 反白函数{uchar halfLineCnt, basicBlock,lcdPosX,lcdPosY;// if(f==1)Disp_black(); //清绘图区lcdPosY = 0x80;if (CX == 0){CX = 0x80;halfLineCnt = 16;}else if (CX == 1){CX = 0x80;halfLineCnt = 32;}else if (CX == 2){CX = 0x88;halfLineCnt = 16;}else if (CX == 3){CX = 0x88;halfLineCnt = 32;}lcdPosX = CX;for (; halfLineCnt != 0; halfLineCnt--){basicBlock = 16;Lcd_Write(0x34,0);Lcd_Write(lcdPosY,0);Lcd_Write(lcdPosX,0);Lcd_Write(0x30,0);for (;basicBlock != 0; basicBlock--){if (halfLineCnt > 16){Lcd_Write(0x00,1);}else{Lcd_Write(0xff,1);}}lcdPosY++;}Lcd_Write(0x36,0);Lcd_Write(0x30,0);}///////////////////////////////////////////////////void Lcd_Pos(uchar x,uchar y){uchar pos;if(x==1){x=0x80;}else if(x==2){x=0x90;}else if(x==3){x=0x88;}else if(x==4){x=0x98;}pos=x+y;Lcd_Write(pos,0);}///////////////////////////////////////////void Lcd_Menu(uint Head){uint j,i;uint Index_End=Head+3;// if(Index_End<=Index_Num){for(j=0;Head<=Index_End;Head++,j++){Lcd_Pos(j+1,0);i=0;while(i<15){if(Weibo[Head][i]!=0)Lcd_Write(Weibo[Head][i++],1);else{Lcd_Write(0x20,1);i++;}}delayNOP();}// }}///////////////////////////////////////////void Lcd_Init(void){LCD_PSB=0;LCD_RST=0;LCD_RS=0;LCD_RW=1;LCD_EN=0;delay(2);LCD_RST=1;delay(2);Lcd_Write(0x30,0); //ordinary cmddelay(2);Lcd_Write(0x0c,0); //how to showdelay(2);Lcd_Write(0x01,0); //cleardelay(2);}/////////////////////////////////////////void main(void){Lcd_Init();Key1=1;Lcd_Menu(Index);convertChar(Index_P);while(1){if(Key1==0&&Index>=0){delay(5);if(Key1==0&&Index>=0){if(Index_P==0&&Index>0)Lcd_Menu(--Index);if(Index_P>0){Index_P_Pre=Index_P;convertChar(--Index_P);}}}if(Key2==0&&Index_P<=3){delay(5);if(Key2==0&&Index_P<=3){if(Index_P==3&&Index<(Index_Num-3)) Lcd_Menu(++Index);if(Index_P<3){Index_P_Pre=Index_P;convertChar(++Index_P);}}}}}。
LCD 128641.总体设计思路SMG12864一般用于显示汉字,字符,分辨率不高的bmp图像,可用来显示传感器采集到信息,是单片机和人交换信息的窗口,2.方案设计8051Lcd12864单片机3.硬件设计单片机控制12864的管脚来显示想要的字符和图像,P0用来发送必要的指令和数据,P2口协助P1口给12864写数据,1. 指令寄存器(IR)IR 是用于寄存指令码,与数据寄存器数据相对应。
当D/I=0 时,在E 信号下降沿的作用下,指令码写入IR。
2.数据寄存器(DR)DR 是用于寄存数据的,与指令寄存器寄存指令相对应。
当D/I=1 时,在下降沿作用下,图形显示数据写入DR,或在E 信号高电平作用下由DR 读到DB7∽DB0数据总线。
DR 和DDRAM 之间的数据传输是模块内部自动执行的。
3.忙标志:BFBF 标志提供内部工作情况。
BF=1 表示模块在内部操作,此时模块不接受外部指令和数据。
BF=0 时,模块为准备状态,随时可接受外部指令和数据。
利用STATUS READ 指令,可以将BF 读到DB7 总线,从检验模块之工作状态。
4.显示控制触发器DFF此触发器是用于模块屏幕显示开和关的控制。
DFF=1 为开显示(DISPLAY OFF),DDRAM 的内容就显示在屏幕上,DFF=0 为关显示(DISPLAY OFF)。
DDF 的状态是指令DISPLAY ON/OFF 和RST 信号控制的。
5.XY 地址计数器XY 地址计数器是一个9 位计数器。
高3 位是X 地址计数器,低6 位为Y 地址计数器,XY 地址计数器实际上是作为DDRAM 的地址指针,X 地址计数器为DDRAM的页指针,Y 地址计数器为DDRAM 的Y 地址指针。
X 地址计数器是没有记数功能的,只能用指令设置。
Y 地址计数器具有循环记数功能,各显示数据写入后,Y 地址自动加1,Y 地址指针从0 到63。
6.显示数据RAM(DDRAM)DDRAM 是存储图形显示数据的。
/*************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*******************/。