由LCD12864初探嵌入式菜单设计(完全资料)
嵌入式课程设计报告完整版

目录前言 (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地址开始执行的部分。
电子信息工程专业毕业设计--基于51单片机的12864液晶显示器的设计和研究

目录设计总说明 (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)鸣谢................................................................................................................................ 错误!未定义书签。
由LCD12864初探嵌入式菜单设计(最完整资料)

PDF 文件使用 "pdfFactory Pro" 试用版本创建
case LCD12864_Graphic_Not: TempData ^= (1 << BX); break;
//计算出属于哪个字节 //属于该字节的哪个位
2、读取 12864 的数据的时候,一定要注意,E 信号要在一个下降延之后持续拉高,然后才能正常独处数据;
假设直接拉高,的确也能读出数据,但是,等着抓头皮,发帖子“[跪求]大侠帮忙关于 12864——请使用明
确的大标题……”^_^
500361 --------------------------------------------ll648 废话少说(说的不少了),看源代码:
default: TempData |= (1 << BX);
}
setY(X);
500361 sendDataToLCD(TempData); ll648 } om/ba 特别说明一下,关于贪食蛇范例的问题,这篇文章里面只会简单得提及一下。 idu.c 作为嵌入式系统开发的一个范例,我会另外开一个帖子详细说明开发过程。 i.ba 这个范例将作为介绍嵌入式系统开发方法的一个很好的例子,用于解释一个系统和一段表示您调通了某一 ://h 个功能的代码之间有什么区别,同时也将介绍嵌入式开发系统的几种模式(超级循环、调度器),顺便侃一
PDF 文件使用 "pdfFactory Pro" 试用版本创建
储器的访问,其速度显然没有对片内 SRAM 的操作速度要快。如果我们使用那种常用的串行方式来作图(所 谓串行方式作图,就是绘图指令的执行和系统的其他操作时串行的,指令不完成,其它操作就不回被执行), 那么对于一些实时性要求高的系统来说就会造成重大隐患——甚至是不符合要求的;如果开辟一段片内存 储空间和 LCD 的存储器一一对应,在相同的时间段内,花费相同的资源来保持着两个存储空间的一致性, 那么就可以保证实时系统的稳定和可靠,保证画面显示的正常(因为允许跳帧嘛^_^)。这就是我们为什么 需要另外在片内选取一个显示缓冲区的原因。
LCD模块的菜单方式人机交互界面

图形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.响应式和自适应设计当设备屏幕的尺寸和分辨率发生变化时,嵌入式菜单应能够自动适应并进行相应的调整,以保证页面的合理显示和操作的便捷性。
可以使用响应式设计和流式布局等技术来实现菜单的自适应性。
以上是嵌入式菜单设计的一般方案,具体的设计细节和实施过程需要根据具体的应用场景和用户需求来定。
在设计过程中,可以进行原型设计和用户测试,根据用户的反馈和需求进行优化和调整,以提供更好的用户体验和功能性。
12864液晶多级菜单设计

LCD12864菜单程序

一起来学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,帮助<。
基于12864的菜单设计

编写者:董新凯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;}}}.。
Lcd12864最全中文资料

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多级菜单课程设计

LCD12864多级菜单课程设计一、课程目标知识目标:1. 理解LCD12864液晶显示屏的基本工作原理和接口技术。
2. 掌握多级菜单的设计方法,包括菜单结构、界面布局及跳转逻辑。
3. 学会编写程序代码实现LCD12864多级菜单的显示与操作。
技能目标:1. 能够运用所学知识设计出结构清晰、界面友好的多级菜单界面。
2. 熟练使用相关编程语言和开发工具,完成程序编写和调试。
3. 培养学生的动手操作能力和团队协作能力,提高问题解决能力。
情感态度价值观目标:1. 培养学生对电子技术和编程的兴趣,激发学习热情。
2. 培养学生严谨、细心的学习态度,养成良好的编程习惯。
3. 增强学生的创新意识,鼓励学生敢于尝试、勇于实践。
分析课程性质、学生特点和教学要求,本课程目标旨在帮助学生在掌握LCD12864多级菜单设计的基础上,提高实际操作能力,培养学生的创新思维和团队协作精神。
通过本课程的学习,使学生能够在实际项目中运用所学知识,为我国电子信息产业的发展做出贡献。
同时,注重培养学生的情感态度价值观,使学生在学习过程中形成积极向上的人生态度。
二、教学内容1. LCD12864液晶显示屏原理介绍:包括显示原理、接口技术、指令集等基本知识。
- 教材章节:第三章第二节- 内容列举:LCD12864工作原理、接口类型、指令功能。
2. 多级菜单设计方法:- 教材章节:第五章- 内容列举:菜单结构设计、界面布局、跳转逻辑、操作流程。
3. 编程实现LCD12864多级菜单:- 教材章节:第六章- 内容列举:编程环境搭建、代码编写、程序调试、功能实现。
4. 实例分析与操作:- 教材章节:第七章- 内容列举:典型多级菜单实例、操作方法、优化技巧。
5. 动手实践与团队协作:- 教材章节:第八章- 内容列举:实践任务分配、协作流程、成果展示。
根据课程目标,教学内容分为五个部分,确保学生系统掌握LCD12864多级菜单设计的相关知识。
教学大纲明确指出各部分内容的安排和进度,以及教材对应的章节和具体内容。
LCD12864 多级菜单

searchMenu.subMenus = malloc(sizeof(&searchMenu)*6); searchMenu.subMenus[0] = searchMenu.subMenus[1] = searchMenu.subMenus[2] = searchMenu.subMenus[3] = searchMenu.subMenus[4] = searchMenu.subMenus[5] = NULL; searchMenu.func = malloc(sizeof(&printf)*6); searchMenu.func[0] = searchMenu.func[2] = searchMenu.func[2] = searchMenu.func[3] = searchMenu.func[4] = searchMenu.func[5] = NULL; searchMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询 子菜单后按返回键,将会显示这个菜单 项
Lcd_Write_Data(*s); s++; } Lcd_Write_Cmd(0x36); //返回图形模式 }
void highlight(uchar x,uchar y,uchar width,u8 mode)
//反
白,X值为0-7,Y值为0-3,width为行反白格数
{
uchar i,j,flag=0x00;
break; } case 8://向下 if(currentMenu->selected == currentMenu->itemCount-1) break; else { currentMenu->selected++; if(currentMenu->selected>currentMenu->range_to) {
嵌入式系统12864液晶显示实验

引脚号
引脚名称
方向
功能说明
1
GND
-
模块的电源地
2
VDD
-
模块的电源正端
3
V0
-
LCD对比度调节端
4
RS(CS)
H/L
并行的指令/数据选择信号;串行的片选信号
5
R/W(SID)
H/L
并行的读写选择信号;串行的数据口
6
E(CLK)
H/L
并行的使能信号;串行的同步时钟
7
DB0
{
DataPort=0xff;
RW=1;
RS=0;
EN=1;
while(DataPort&0x80);
EN=0
}
其中,RW设置为低电平RW=0,RS依据传命令和数据的不同分别设置为0和1,将需要传输的数据赋值给DB0-DB7,EN设置为高电平。
延时Tpm(查看芯片手册),代码实现如下所示
void lcdDelay(unsigned int m)
图1-4 12864读时序
读操作过程与写过程类似,如下:
DB0~DB7的初始化设置为0或是1
RW设置为高即读状态
RS设置为低,读命令
EN使能位设置为高,开始读取数据
判断DB7是否为高
EN设置为高,结束读取
3.初始化12864液晶。
查12864液晶的数据手册,可以知道12864有两种指令集:基本指令集和扩充指令集。由于本实验只是进行基本的数据显示,所以选择基本指令集。设置完指令集以后需要将显示开关打开,移位控制和光标的设置。详细的设置参数可以参考12864数据手册。其基本步骤总结如下:
20
嵌入式lcd显示课程设计

嵌入式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初探嵌入式菜单设计(完全资料)

填充就是必须掌握的——几何不能太差哦。 还有,结合屏幕的硬件特点,对算法进行优化的一些方法也是需要掌握的。比方说,如何填充之类的……
后面会针对 LCD12864 作详细介绍的。
361 3、人机交互学 0 虽然很多人都没有实实在在学过这门功课,但是多多少少对于界面应该怎样有些许了解。如何利用手中 50 的基本操作函数做出一些特效,如何安排窗体,如何绘制图形界面的一些基本元素如按钮,甚至如何显示 48 汉字,都是人际交互学需要教会你的——总之,如果你没有学过这门课程,你的产品只有你自己用的话—— ll6 跟着感觉走,没错的。 m/ba 4、最最重要的物质基础 o 你要掌握一种单片机,掌握一种点阵屏幕。 u.c AVR Inside id Not Only For LCD12864 ://hi.ba 前面已经说过,对于栅格显示设备来说,点是一切图形的基础,说白了,不会在液晶屏幕的任意位置随
心所欲的画点就不能说你已经掌握了某种液晶屏幕的使用了。事实上,根据笔者的经验,尝试画点往往能
http 暴露出很多问题。就拿 LCD12864 来说吧,一段时间,笔者总是发现,在片切换的地方有一点点错误……
在说明如何画点之前先说明一个概念:显示缓冲区。
所谓显示缓冲区,顾名思义,就是显示数据的一个缓冲地带。一般情况下,我们绘图也是直接对这块缓 冲区域进行操作的。
PDF 文件使用 "pdfFactory Pro" 试用版本创建
首先,我们从最基本的数学算法说起。 如果我们使用公式 y = kx + b 来作为绘图的依据,那么就需要分 3 种情况:水平直线,斜率为 0;垂直直
我的lcd12864菜单大致框架7页word文档

我的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);}}}}}。
(完整word版)lcd12864 课程设计

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 是存储图形显示数据的。
stm32-12864液晶-菜单设计

/*************menu.h*******************/#ifndef __MENU_H#define __MENU_H#include "stm32f10x.h"#include "SysTick.h"#include <stdlib.h>#include "12864.h"#include "AdcDisplay.h"#include "key.h"#include "spi_tm7705.h"#include "eeprom.h"typedef struct menu//定义一个菜单{u8 range_from,range_to; //当前显示的项开始及结束序号u8 itemCount;//项目总数u8 selected;//当前选择项u8 *menuItems[17];//菜单项目struct menu **subMenus;//子菜单struct menu *parent;//上级菜单,如果是顶级则为null void (**func)();//选择相应项按确定键后执行的函数}Menu;void MainDisplay(void);void DisplayMenu(u8 line);void func(void);void Unitch1(void);void Unitch2(void);void Unitch3(void);void Unitch4(void);void DiaChange(void);void MlChange(void);u16 NumLoop(u16 num,u8 pm);u8 Change(u8 Sval,uint8_t* title);void MenuInit(void);#endif /* __MENU_H *//*************menu.h*******************//************menu.c*******************//******************** ********************* 文件名:menu.c* 描述:液晶菜单函数库* 实验平台:* 硬件连接----------------------------**** ----------------------------* 库版本:ST3.0.0******************************************************************************** ***/#include "menu.h"//菜单与AD结果显示变量,0为AD,1为菜单extern u8 MenuDis=0;//typedef struct menu//定义一个菜单//{// u8 range_from,range_to; //当前显示的项开始及结束序号// u8 itemCount;//项目总数// u8 selected;//当前选择项// u8 *menuItems[17];//菜单项目// struct menu **subMenus;//子菜单// struct menu *parent;//上级菜单,如果是顶级则为null// void (**func)();//选择相应项按确定键后执行的函数////}Menu;Menu MainMenu = { //定义主菜单0,3,4,0,//默认显示0-3项,总共4项,当前选择第0项{"单位设置\x10","直径设置\x10","模量设置\x10","关于"}};Menu UnitMenu = {//单位设置菜单0,3,4,0,{"应变量ε","锁模力KN ","锁模力Ton","取消"}};u8 UnitCh;//单位选择,0为变形量ε,1为应变量σ,2为锁模力FMenu DiaMenu = {//单位设置菜单0,0,1,0,{"主999 mm"}};Menu MlMenu = {//模量设置菜单0,0,1,0,{"主999 KN/mm2"}};u8 DiaVal;//直径数值u8 MlVal;//模量数值//菜单与AD结果显示变量,0为AD,1为菜单u8 MenuDis;//复位前指数u16 BaseAD[4];//横截面积u16 mianji;//横截直径u16 zhijing;//模量u16 moliang;//按键返回值u8 keyval;uint8_t* title1="单位:MM";uint8_t* title2="单位:KN/MM2";extern u16 ADResult[4];//存储AD结果的数组extern uint16_t VirtAddVarTab[NumbOfVar];//eepromMenu *currentMenu;//当前的菜单void MainDisplay(void){if (MenuDis==0)AdUi();keyval=KeyScan();switch(keyval){case 0://什么都不干{Delay_ms(50);break;}case 1://向上{if(MenuDis==1){if(currentMenu->selected == 0)//到了第一项break;else{currentMenu->selected--;DisplayMenu(currentMenu->selected);}}break;}case 2://向下{if(MenuDis==1){if(currentMenu->selected == currentMenu->itemCount-1)break;else{currentMenu->selected++;DisplayMenu(currentMenu->selected);}}break;}case 3://确认{if(MenuDis==0){MenuDis=1;LCD_Init();DisplayMenu(currentMenu->selected);}else{if(currentMenu->subMenus[currentMenu->selected] !=NULL){LCD_Init();currentMenu = currentMenu->subMenus[currentMenu->selected];DisplayMenu(currentMenu->selected);}else{if(currentMenu->func[currentMenu->selected] != NULL){LCD_Init();currentMenu->func[currentMenu->selected]();//执行相应的函数currentMenu->selected=0;DisplayMenu(currentMenu->selected);//返回后恢复原来的菜单状态}}}break;}case 4://取消{if(MenuDis==1){if(currentMenu->parent!=NULL)//父菜单不为空,将显示父菜单{LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected);}else{MenuDis=0;//currentMenu = MainMenu;currentMenu->selected=0;LCD_Init();AdUi();Delay_ms(100);}}else{Clr_Scr();Delay_ms(50);Write_Char(0,0x30);//关闭扩展指令//复位归零BaseAD[0]=ADResult[0];BaseAD[1]=ADResult[1];BaseAD[2]=ADResult[2];BaseAD[3]=ADResult[3];AdUi();}break;}default:break;}}//用于显示菜单项void DisplayMenu(u8 line) //显示菜单项并设置选中的项反白{int i;line = 3-(currentMenu->range_to-line);for(i = 0;i<4;i++){LCD_Write_String(i,0,currentMenu->menuItems[i+currentMenu->range_from]); }WhiteLineInit();White_Line(line,0,8);//反白显示指定行}void func(void){uint8_t* s="为人民服务";LCD_Write_String(1,0,s);Delay_ms(3000);}void Unitch1(void){UnitCh=0;LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void Unitch2(void){UnitCh=1;LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void Unitch3(void){UnitCh=2;LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void Unitch4(void){LCD_Init();currentMenu = currentMenu->parent;currentMenu->selected=0;DisplayMenu(currentMenu->selected); }void DiaChange(void){uint8_t* s="单位:MM";//测试代码u16 a=0;int i=0;//u16 tmp1;LCD_Init();LCD_Write_String(0,0,s);zhijing=Change(zhijing,title1);mianji=3.14*((zhijing/2)*(zhijing/2));EE_WriteVariable(VirtAddVarTab[0], zhijing);//测试代码//for(i=0;i<99;i++)//{//a=a+1;//LCD_Write_Tri_Value(2,3,a);//Delay_ms(50);//}}void MlChange(void){uint8_t* s="单位:KN/MM2";LCD_Init();LCD_Write_String(0,0,s);moliang=Change(moliang,title2);EE_WriteVariable(VirtAddVarTab[1], moliang);}//数字按键循环,升到9后变0,降到0后变9,参数pm为加减,1为+,0为减u16 NumLoop(u16 num,u8 pm){if (pm==1){if (num>=9)num=0;elsenum=num+1;}else{if (num<=0)num=9;elsenum=num-1;}return num;}//Sval代表直径或模量的默认值,返回修改后直径或模量的值u8 Change(u8 Sval,uint8_t* title){u16 baiwei,shiwei,gewei,Dval;//数字ascii码//char tmpval;//按键返回值u8 keyval=0;//光标位置3为百位、4为十位,5为个位u8 loc=3;//是否选中其中一位u8 clicked=0;//光标闪烁位,是否闪烁u8 flicker=0;baiwei=(u16)(Sval/100);shiwei=(u16)((Sval%100)/10);gewei=(u16)((Sval%100)%10);//tmpval=(char)baiwei + 0x30;//LCD_Write_Char(2,3,tmpval);//tmpval=(char)shiwei + 0x30;//LCD_Write_Char(2,4,tmpval);//tmpval=(char)gewei + 0x30;//LCD_Write_Char(2,5,tmpval);//LCD_Write_Single_Num(2,3,baiwei);//LCD_Write_Single_Num(2,4,shiwei);//LCD_Write_Single_Num(2,5,gewei);LCD_Write_Tri_Value(2,3,Sval);WhiteLineInit();White_Line(2,3,1);//反白显示指定行while(1){keyval=KeyScan();switch(keyval){case 0://什么都不干{if (clicked){if (flicker==0){White_Line(2,loc,1);flicker=1;}else{Shut_White_Line(2,loc,1);flicker=0;}}//else//White_Line(2,loc,1);Delay_ms(300);break;}case 1://向上{if (clicked==0){if (loc>3)loc=loc-1;elseloc=3;WhiteLineInit();White_Line(2,loc,1);}else{switch (loc){case 3:{baiwei=NumLoop(baiwei,1);LCD_Init();break;}case 4:{shiwei=NumLoop(shiwei,1);LCD_Init();break;}case 5:{gewei=NumLoop(gewei,1);LCD_Init();break;}default:break;}}break;}case 2://向下{if (clicked==0){if (loc<5)loc=loc+1;elseloc=5;WhiteLineInit();White_Line(2,loc,1);}else{switch (loc){case 3:{baiwei=NumLoop(baiwei,0);LCD_Init();break;}case 4:{shiwei=NumLoop(shiwei,0);LCD_Init();break;}case 5:{gewei=NumLoop(gewei,0);LCD_Init();break;}default:break;}}break;}case 3://确认{if (clicked)clicked=0;elseclicked=1;break;}case 4://取消{if (clicked)clicked=0;else //返回主菜单{LCD_Init();currentMenu = &MainMenu;currentMenu->selected=0;DisplayMenu(currentMenu->selected);//返回新的数值Dval=baiwei*100+shiwei*10+gewei;return Dval;}break;}default:break;}//LCD_Init();LCD_Write_String(0,0,title);Dval=baiwei*100+shiwei*10+gewei;LCD_Write_Tri_Value(2,3,Dval);Delay_ms(20);}}//初始化菜单:void MenuInit(void){MainMenu.subMenus = malloc(sizeof(&MainMenu)*4);MainMenu.subMenus[0] = &UnitMenu;//第1项没有子菜单置null,选择后程序会调用func中相应项中的函数MainMenu.subMenus[1] = NULL;//&DiaMenu;直接执行设置函数MainMenu.subMenus[2] = NULL;//&MlMenu;直接执行设置函数MainMenu.subMenus[3] = NULL;MainMenu.func = malloc(sizeof(&func)*4);MainMenu.func[0] = &func;MainMenu.func[1] = &DiaChange;MainMenu.func[2] = &MlChange;//当选择了并按了确定,会执行func函数MainMenu.func[3] = NULL;MainMenu.parent = NULL;//表示是顶级菜单UnitMenu.subMenus = malloc(sizeof(&UnitMenu)*4);UnitMenu.subMenus[0] = NULL;UnitMenu.subMenus[1] = NULL;UnitMenu.subMenus[2]= NULL;UnitMenu.subMenus[3]= NULL;UnitMenu.func = malloc(sizeof(&Unitch1)*4);UnitMenu.func[0] = &Unitch1;UnitMenu.func[1] = &Unitch2;UnitMenu.func[2] = &Unitch3;UnitMenu.func[3] = &Unitch4;UnitMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单项// DiaMenu.subMenus = malloc(sizeof(&DiaMenu)*1);// DiaMenu.subMenus[0] = NULL;// DiaMenu.func = malloc(sizeof(&func)*1);// DiaMenu.func[0] = &func;// DiaMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单项//// MlMenu.subMenus = malloc(sizeof(&MlMenu)*1);// MlMenu.subMenus[0] = NULL;// MlMenu.func = malloc(sizeof(&func)*1);// MlMenu.func[0] = &func;// MlMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单项currentMenu = &MainMenu;}/************menu.c*******************/。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、位操作 向 LCD12864 这种二值屏幕,我们习惯于用 1 个字节表示连续的 8 个点,1 对应对应位被点亮,0 表示不
亮,所以对图形的操作最基本的手段就是位操作。 复习下,常用的位操作,假设 Dis 表示某一个现存地址的内容 Dis = Dis~ 黑白颠倒 Dis &= ~(1<<n) 第 n 处被擦去, Dis |= (1<<n) 第 n 处被画了一个点 Dis ^= (1<<n) 如果 n 处是亮的,就变被擦掉;如果 n 处是空白的,就被点亮…… …… 差不多就这些
default: TempData |= (1 << BX);
}
setY(X);
500361 sendDataToLCD(TempData); ll648 } om/ba 特别说明一下,关于贪食蛇范例的问题,这篇文章里面只会简单得提及一下。 idu.c 作为嵌入式系统开发的一个范例,我会另外开一个帖子详细说明开发过程。 i.ba 这个范例将作为介绍嵌入式系统开发方法的一个很好的例子,用于解释一个系统和一段表示您调通了某一 ://h 个功能的代码之间有什么区别,同时也将介绍嵌入式开发系统的几种模式(超级循环、调度器),顺便侃一
PDF 文件使用 "pdfFactory Pro" 试用版本创建
首先,我们从最基本的数学算法说起。 如果我们使用公式 y = kx + b 来作为绘图的依据,那么就需要分 3 种情况:水平直线,斜率为 0;垂直直
硬件平台:AVR Mega8 级 LCD: 不带字库的 12864 软件平台:ICC 规范: 符合基本的 C 编程规范
3、何时开始正文 其实,本文应该算是计算机图形学的一个具体分支,所以,计算机图形学的基本要求就是本文的基本要求, 考虑到各位兄弟的胃口,我就多罗嗦下。
PDF 文件使用 "pdfFactory Pro" 试用版本创建
2、作图原理 点是一切光栅显示设备的基本要素,所有的操作都是以点为基础的,所以学会如何利用点构成线、圆、
填充就是必须掌握的——几何不能太差哦。 还有,结合屏幕的硬件特点,对算法进行优化的一些方法也是需要掌握的。比方说,如何填充之类的……
后面会针对 LCD12864 ቤተ መጻሕፍቲ ባይዱ详细介绍的。
361 3、人机交互学 0 虽然很多人都没有实实在在学过这门功课,但是多多少少对于界面应该怎样有些许了解。如何利用手中 50 的基本操作函数做出一些特效,如何安排窗体,如何绘制图形界面的一些基本元素如按钮,甚至如何显示 48 汉字,都是人际交互学需要教会你的——总之,如果你没有学过这门课程,你的产品只有你自己用的话—— ll6 跟着感觉走,没错的。 m/ba 4、最最重要的物质基础 o 你要掌握一种单片机,掌握一种点阵屏幕。 u.c AVR Inside id Not Only For LCD12864 ://hi.ba 前面已经说过,对于栅格显示设备来说,点是一切图形的基础,说白了,不会在液晶屏幕的任意位置随
{
char DX = (Y >> 3); char BX = Y - (DX << 3);
//计算出属于哪个字节 //计算出属于字节哪一位
char TempData = 0;
PDF 文件使用 "pdfFactory Pro" 试用版本创建
LCD12864_ChooseBoth;
以后,我们的操作都是针对显示缓冲区的。显示缓冲区将成为一个概念,无论这个缓冲区位于 SRAM 内 还是 LCD 内部。比方说,我们需要一个低成本的游戏机——如做一个贪食蛇游戏机送给老师作为课程设计, 或者送给小侄子,那么,M8 甚至是 M48 成为首选,问题是,M8 绝对无法开辟出一个 8 * 128 = 1K 大小的 数组,所以,这个时候,认定 LCD 的片内存储器作为显示缓冲区就是不二的选择——好在贪食蛇速度太快 了也没有办法玩哈。
很多朋友就要提问了:我们为什么不直接对屏幕操作呢?
事实上,LCD 本身存在一块显示存储器,也可以被认为是一个显示缓存,直接写在这个存储器的数据并 非直接显示出来,而多半需要一个显示指令来影射一下。我们有时候也通过这种类似的技术来实现很大的 图片的显示——先画好,再拿给大家看,让人以为你是一下就画好的,当然如果你刻意需要那种图片被“画” 出来的效果,则不在讨论之列。问题就在于,LCD 是片外资源,对其存储器的访问可以被认为是对片外存
setX(DX); if (X > 63) {
LCD12864_ChooseCS2; X -= 64;
}e{}selstLeYC(XD)1;2864_ChooseCS1h; ttp:///ball648500361
TempData = getLCD12864Data();
switch (Type) {
PDF 文件使用 "pdfFactory Pro" 试用版本创建
假设输入的是正常习惯的坐标 X,Y DX DY 就是 LCD 上的坐标,那么转换关系是
char DX = (Y >> 3); char BX = Y - (DX << 3); char DY = X;
m/ba # define LCD12864_Graphic_Draw
0x01
u.co # define LCD12864_Graphic_Clear
0x00
http://hi.baid # define LCD12864_Graphic_Not
0x02
……
void LCD12864Draw(char X,char Y,char Type)
当然,太过于理论的东西对我们是没有多少实际价值的。下面,我就介绍两种常见的画线思路,一种就 是最容易被想到的直线方程计算的方法,另外一种则是被称为布兰森汉姆(Bresenham)的计算机图形学主流 算法。
在介绍完这两种算法以后,我们会针对 LCD12864 的硬件结构为例子,介绍,具体算法的实现和优化。
再次,根据用户所需画点的类型(擦除、画点、反相点)来进行相应的操作获得一个新的数据; 最后,将该数据写回原来的地址。
--------------------------------------------LCD12864 补充知识 1、关于坐标系。很多人,包括笔者,一开始都看不懂 LCD12864 的内存影射方式,感觉 X、Y 似乎不是那 么回事。后来才发现,只要把屏幕竖着放一切就好懂了。X 还是横轴,Y 还是竖轴……但是这显然不符合 我们的习惯,我们习惯于长的那个边作为横轴,所以需要一点点坐标之间的转换。
由 LCD12864 初探嵌入式系统设计
--菜单设计
声明:本文来自互联网,由于年代久远未能找到出处,现整理如下希望大家喜欢,如有侵权请联系 真的好想你 QQ: 1320249827 前言往往要解释写文章的动机和原因,同时给作者一个正题以外灌水的机会——本文也不例外。 1、为什么我要写这篇文章。
不可否认,我的确受到了 Armok 的利诱影响,但是最近发生的一些事情却使我觉得写这篇文章是非常有 必要的。在 OurAVR 上看到很多版本的 LCD 驱动程序,几乎每一个版本都只是简单的将全部或部分的显示 数据 Cover 到 LCD 的显存上,完成一个字或者是图片的显示就等着大家喊“牛”了。其实要走的路还很远。 对一个工程项目来说,增加 n 多的成本来提供一个点阵屏作为用户接口,不是一两幅欢迎图片和 Now Loading...Please Standy By 的提示能糊弄的过去的。用户希望你提供的是友好的图形界面 GUI,虽然比
PDF 文件使用 "pdfFactory Pro" 试用版本创建
储器的访问,其速度显然没有对片内 SRAM 的操作速度要快。如果我们使用那种常用的串行方式来作图(所 谓串行方式作图,就是绘图指令的执行和系统的其他操作时串行的,指令不完成,其它操作就不回被执行), 那么对于一些实时性要求高的系统来说就会造成重大隐患——甚至是不符合要求的;如果开辟一段片内存 储空间和 LCD 的存储器一一对应,在相同的时间段内,花费相同的资源来保持着两个存储空间的一致性, 那么就可以保证实时系统的稳定和可靠,保证画面显示的正常(因为允许跳帧嘛^_^)。这就是我们为什么 需要另外在片内选取一个显示缓冲区的原因。
case LCD12864_Graphic_Clear: TempData &= ~(1<<BX); break;
PDF 文件使用 "pdfFactory Pro" 试用版本创建
case LCD12864_Graphic_Not: TempData ^= (1 << BX); break;
1 不过 XP 和 Apple 的华丽,但是由各种基本图形组成的窗口界面还是需要的。 036 当我们真的想实现一个图形界面的时候,很快就会发现,我们需要的不仅仅是一个被喊了“牛”的初级驱 50 动,我们需要的是一个图形引擎——一个自定义的图形函数包,没有 DirectX 的华丽,但是能绘制一个任 48 意的直线或是矩形就够了——结果往往发现无所适从。这个时候,我们遇到的就是一个门槛,真正的嵌入 ll6 式工程师和一个业余电子爱好者之间的门槛。 /ba 2、我如何写这篇文章 i.baid 考虑到本人老王卖瓜的习惯,所以请大家一定无比在吃饭前看本人写的技术文章,同时保持耐心等待续 ://h 集(绝对有续集)。本人现单身,个人问题众多,学习任务重,所以可能有时候写文章象羊拉屎,不对大家 http 胃口,请见谅。
1 绕了这么多的弯子,究竟如何画点呢?我还想多补充一个原因,关于,为什么需要显示缓冲区,由于点 36 阵屏幕使用的是 1 个字节来表示 8 个点的,如果你想使得一个字节中的某一个点被操作而不影响别的点, 0 你起码要知道原来这个位置是什么内容,对于有些使用 595 级联的 LCD 设备来说,无法直接从 LCD 读取 50 现存数据,所以开辟一个缓冲区,从中获得信息加以加工以后再放回去,是这种设备处理显示图形的唯一 48 方法——当然我们没有那么惨,但是从 LCD 中获取所需点所在字节的内容还是必须的,不然你画一个点就 ll6 会破坏一条线上所有的数据。 /ba 好的,那么我们实际上已经明确了如何去画一个点。 i.baid 首先,根据用户给出的坐标计算出所要画的点所在现存内的地址偏移量; http://h 然后,我们读出该地址内的数据;