12864多级菜单设计
看到网上有个视频,用的是12864做的菜单,很花哨,自己也心痒痒想做一个,收集了很多关于这方面的东西,但是都是五花八门,没有一个完整的可以共大家参考的程序,所以决定写偏文章供大家参考,希望读者下去自己优化,改进。有什么不足之处还请多多包涵。好了,废话不多说,直接进入正题吧。
1、首先定义一个机构体如下
typedef struct
{
uchar current; //当前状态
uchar up;//上键
uchar down;//下键
uchar enter;//确认键
void (*current_operation)(); //当前状态应该执行的功能操作
} key_table;
结构体包含5个变量,分别是函数的索引号即用户想要执行哪个函数的代号,然后有三个键,用户可以自己定义别的按键,最后一个是函数指针,即索引号对应的函数。然后在定义一个结构体数组,如下
key_table code table[n]=
{
{0,2,1,3,(*fun1)},
{1,0,2,4,(*fun2)},
{2,1,0,5,(*fun3)},
{3,0,6,3,(*fun4)},
{4,1,6,4,(*fun5)},
{5,2,6,5,(*fun6)},
{6,0,0,0,(*fun7)},
............
};
其中n为函数数组大小。下面详细介绍key_table code table[n]里面的值是怎么确定的。
首先可以先这样定义该数组
key_table code table[n]=
{
{0,x,y,z,(*fun1)},
{1,x,y,z,(*fun2)},
{2,x,y,z,(*fun3)},
{3,x,y,z,(*fun4)},
{4,x,y,z,(*fun5)},
{5,x,y,z,(*fun6)},
{6,x,y,z,(*fun7)},
............
};
其中,x,y,z是未知数,先不确定,他们对应的是三个键按下要指示的索引值,如果四个键,就有四个未知数,在确定他们之前,必须要了解自己函数执行什么命令。加入开始时时执行数组里面的第一个即table[0],而想在此按上键执行函数fun6,那么table[0]里面需要这样设置{0,5,y,z,(*fun1)},
同样,如果希望按下键执行fun7则需要设置为{0,x,6,z,(*fun1)},
如果希望按确认键执行fun3则需要设置为{0,x,y,2,(*fun1)};
如果上面三种情况都想要就设置为{0,5,6,2,(*fun1)}.
其它数组元素一次类推。这一步做完了看主程序里面(主要是while(1)里面)。
/*******************find index****************************/
switch(key)
{
case 0x44: func_index=table[func_index].up; //向上翻
break;
case 0x24: func_index=table[func_index].enter;//回车
break;
case 0x14: func_index=table[func_index].down;//向下翻
break;
default:break;
} current_operation_index=table[func_index].current_operation;
(*current_operation_index)();//执行当前操作函数
其中,key是返回的按键值,这个用户视情况而定,
下面是详细的例子,
主要是以结构体为基础设计的,以12864显示函数代替了用户需要的函数功能,只需要修改相应的函数和索引号,就可以达到任意界面切换了是小弟研究了还久才搞定的,虽然网上也有这些,但是都不够系统,只有基本的东西,这篇例子希望能够给读者一些有用的东西,仅供参考哦!
:
#include
#include "fun.h"
#include "lcd12864.h"
#include "delay.h"
#define uchar unsigned char
sbit keydown=P0^0;
sbit keyenter=P0^1;
sbit keyup=P0^2;
uchar func_index=0;
void (*current_operation_index)();
typedef struct
{
uchar current;
uchar up;//向上翻索引号
uchar down;//向下翻索引号
uchar enter;//确认索引号
void (*current_operation)();
} key_table;
key_table code table[30]=
{
{0,3,1,4,(*fun1)},//第一层,显示【清华大学】、北京大学、重庆三峡学院、返回
{1,0,2,8,(*fun2)},//第一层,显示清华大学、【北京大学】、重庆三峡学院、返回
{2,1,3,12,(*fun3)},//第一层,显示清华大学、北京大学、【重庆三峡学院】、返回
{3,2,0,25,(*fun4)},//第一层,显示清华大学、北京大学、重庆三峡学院、【返回】
{4,7,5,16,(*fun5)},//第二层,清华大学层下显示【地点】、创建时间、简介、返回
{5,4,6,17,(*fun6)},//第二层,清华大学层下显示地点、【创建时间】、简介、返回
{6,5,7,18,(*fun7)}, //第二层,清华大学层下显示地点、创建时间、【简介】、返回
{7,6,4,0,(*fun8)},//第二层,清华大学层下显示地点、创建时间、简介、【返回】
{8,11,9,19,(*fun9)},//第二层,北京大学层下显示【历史】、政治、简介、返回
{9,8,10,20,(*fun10)},//第二层,北京大学层下显示历史、【政治】、简介、返回
{10,9,11,21,(*fun11)}, //第二层,北京大学层下显示历史、政治、【简介】、返回
{11,10,8,1,(*fun12)},//第二层,北京大学层下显示历史、政治、简介、【返回】
{12,15,13,22,(*fun13)},//第二层,重庆三峡学院层下显示【简介】、最佳院系、最佳实验室、返回{13,12,14,23,(*fun14)}, //第二层,重庆三峡学院层下显示简介、【最佳院系】、最佳实验室、返回
{14,13,15,24,(*fun15)}, //第二层,重庆三峡学院层下显示简介、最佳院系、【最佳实验室】、返回
{15,14,12,2,(*fun16)}, //第二层,重庆三峡学院层下显示简介、最佳院系、最佳实验室、【返回】
{16,16,16,4,(*fun17)}, //第三层,清华大学地点层
{17,17,17,5,(*fun18)}, //第三层,清华大学创时间层
{18,18,18,6,(*fun19)}, //第三层,清华大学简介层
{19,19,19,8,(*fun20)}, //第三层,北京大学历史层
{20,20,20,9,(*fun21)}, //第三层,北京大学政治层
{21,21,21,10,(*fun22)}, //第三层,北京大学简介层
{22,22,22,12,(*fun23)}, //第三层,重庆三峡学院简介层
{23,23,23,13,(*fun24)}, //第三层,重庆三峡学院最佳院系层
{24,24,24,14,(*fun25)}, //第三层,重庆三峡学院最佳实验室层
{25,25,25,0,(*fun26)}, //第0层
};
void main()
{
init_lcd(); //初始化LCD模块
while(1)
{
/*******************find index****************************/
if((keyup==0)||(keydown==0)||(keyenter==0))
{
delay(10);//消抖
if(keyup==0)
{
func_index=table[func_index].up; //向上翻
while(!keyup);//松手检测
}
if(keydown==0)
{
func_index=table[func_index].down; //向下翻
while(!keydown);
}
if(keyenter==0)
{
func_index=table[func_index].enter; //确认
while(!keyenter);
}
init_lcd();
{
current_operation_index=table[func_index].current_operation;
(*current_operation_index)();//执行当前操作函数
}
}
由LCD12864初探嵌入式系统设计 --菜单设计 声明:本文来自互联网,由于年代久远未能找到出处,现整理如下希望大家喜欢,如有侵权请联系 真的好想你QQ: 1320249827 前言往往要解释写文章的动机和原因,同时给作者一个正题以外灌水的机会——本文也不例外。 1、为什么我要写这篇文章。 不可否认,我的确受到了Armok 的利诱影响,但是最近发生的一些事情却使我觉得写这篇文章是非常有必要的。在OurA VR 上看到很多版本的LCD 驱动程序,几乎每一个版本都只是简单的将全部或部分的显示数据Cover 到LCD 的显存上,完成一个字或者是图片的显示就等着大家喊“牛”了。其实要走的路还很远。对一个工程项目来说,增加n 多的成本来提供一个点阵屏作为用户接口,不是一两幅欢迎图片和Now Loading...Please Standy By 的提示能糊弄的过去的。用户希望你提供的是友好的图形界面GUI ,虽然比不过XP 和Apple 的华丽,但是由各种基本图形组成的窗口界面还是需要的。 当我们真的想实现一个图形界面的时候,很快就会发现,我们需要的不仅仅是一个被喊了“牛”的初级驱动,我们需要的是一个图形引擎——一个自定义的图形函数包,没有DirectX 的华丽,但是能绘制一个任意的直线或是矩形就够了——结果往往发现无所适从。这个时候,我们遇到的就是一个门槛,真正的嵌入式工程师和一个业余电子爱好者之间的门槛。 2、我如何写这篇文章 考虑到本人老王卖瓜的习惯,所以请大家一定无比在吃饭前看本人写的技术文章,同时保持耐心等待续集(绝对有续集)。本人现单身,个人问题众多,学习任务重,所以可能有时候写文章象羊拉屎,不对大家 胃口,请见谅。 硬件平台:A VR Mega8级 LCD : 不带字库的12864 软件平台:ICC 规范: 符合基本的C 编程规范 3、何时开始正文 其实,本文应该算是计算机图形学的一个具体分支,所以,计算机图形学的基本要求就是本文的基本要求,考虑到各位兄弟的胃口,我就多罗嗦下。 h t t p :// h i .b a i d u .c o m /b a l l 648500361
本例程为通过用A T89C52芯片操作LCD12864显示的程序,使用的晶振为12M。 /********************************************************** 程序说明:LCD12864显示主程序 程序调试员:莫剑辉 调试时间:2010-6-7 **********************************************************/ #include ;实验目的:熟悉12864LCD的使用 ;12864LCD带中文字库 ;编程让12864LCD显示公司名称“深圳乾龙盛电子”,公司电话“0975”,公司传真“6”;硬件设置: ;关断所有拨码开关。 #include<> ;__CONFIG _DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_H S_OSC ;芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡 #define RS PORTA,5 ;命令/数据选择 #DEFINE RW PORTA,4 ;读/写选择 #DEFINE E PORTA,3 ;使能信号 #DEFINE PSB PORTA,2 ;并口/串口选择(H/L) #DEFINE RST PORTA,0 ;复位信号 ;----------------------------------------------- LCD_X EQU 30H ;页地址 LCD_Y EQU 31H ;Y地址 COUNT EQU 32H ;循环计数用 COUNT1 EQU 33H ;循环计数用 COUNT2 EQU 34H ;循环计数用 POINT EQU 35H ;查表偏移地址 POINT1 EQU 36H ;查表偏移地址 POINT2 EQU 37H ;查表偏移地址 TEMP EQU 38H ;临时寄存器 TEMP1 EQU 39H ;临时寄存器 ;----------------------------------------------- ORG 0000H ;复位地址 NOP ;ICD需要的空指令 GOTO MAIN ;跳转到主程序 ;**********************主程序************************ MAIN BANKSEL TRISA CLRF TRISA ;A口输出 CLRF TRISD ;D口输出 BANKSEL ADCON1 MOVLW 06H MOVWF ADCON1 ;A口全为数字口 CLRF STATUS 51单片机综合学习 12864液晶原理分析1 辛勤学习了好几天,终于对12864液晶有了些初步了解~没有视频教程学起来真有些累,基本上内部程序写入顺序都是根据程序自我变动,然后逆向反推出原理…… 芯片:YM12864R P-1 控制芯片:ST7920A带中文字库 初步小结: 1、控制芯片不同,寄存器定义会不同 2、显示方式有并行和串行,程序不同 3、含字库芯片显示字符时不必对字符取模了 4、对芯片的结构地址一定要理解清楚 5、显示汉字时液晶芯片写入数据的顺序(即显示的顺序)要清楚 6、显示图片时液晶芯片写入数据的顺序(即显示的顺序)要清楚 7、显示汉字时的二级单元(一级为八位数据写入单元)要清楚 8、显示图片时的二级单元(一级为八位数据写入单元)要清楚 12864点阵液晶显示模块(LCM)就是由128*64个液晶显示点组成的一个128列*64行的阵列。每个显示点对应一位二进制数,1表示亮,0表示灭。存储这些点阵信息的RAM称为显示数据存储器。要显示某个图形或汉字就是将相应的点阵信息写入 到相应的存储单元中。图形或汉字的点阵信息由自己设计,问题的关键就是显示点在液晶屏上的位置(行和列)与其在存储器中的地址之间的关系。由于多数液晶显示模块的驱动电路是由一片行驱动器和两片列驱动器构成,所以12864液晶屏实际上是由左右两块独立的64*64液晶屏拼接而成,每半屏有一个512*8 bits显示数据RAM。左右半屏驱动电路及存储器分别由片选信号CS1和CS2选择。显示点在64*64液晶屏上的位置由行号(line,0~63)与列号(column,0~63)确定。512*8 bits RAM中某个存储单元的地址由页地址(Xpage,0~7)和列地址(Yaddress,0~63)确定。每个存储单元存储8个液晶点的显示信息。 在我们常用的人机交互显示界面中,除了数码管,LED,以及我们之前已经提到的LCD1602之外,还有一种液晶屏用的比较多。相信接触过单片机的朋友都知道了,那就是12864液晶。顾名思义,12864表示其横向可以显示128个点,纵向可以显示64个点。我们常用的12864液晶模块中有带字库的,也有不带字库的,其控制芯片也有很多种,如KS0108 T6963,ST7920等等。在这里我们以ST7920为主控芯片的12864液晶屏来学习如何去驱动它。(液晶屏采用金鹏的OCMJ4X8C) 关于这个液晶屏的更多信息,请参考它的DATASHEET,附件中有下载。 我们先来了解一下它的并行连接情况。 下面是电路连接图 从上面的图可以看出,液晶模块和单片机的连接除了P0口的8位并行数据线之外,还有RS,RW,E等几根线。其中R/S是指令和数据寄存器的选择控制线(串行模式下为片选),R/W 是读写控制线(串行模式下是数据线),E是使能线(串行模式下为时钟线)。 通过这几根控制线和数据线,再结合它的时序图,我们就可以编写出相应的驱动程序啦。 看看并行模式下的写时序图: 根据这个时序图,我们就可以写出写数据或者写命令到LCD12864液晶的子程序。 读时序图如下: 根据这个时序图我们就可以从LCD12864液晶模块内部RAM中读出相应的数据,我们的忙检测函数就是根据这个时序图写出来的。以及后面章节中讲的画点函数等都要用到读时序。有了这两个时序图,然后我们再看看OCMJ4X8C的相关指令集,就可以编写出驱动程序了。这里要注意的是指令集分为基本指令集和扩充指令集,其中扩充指令集主要是与绘图相关,在此后的章节中会有相应的介绍。 下面让我们根据这些编写出它的驱动程序吧。 我的硬件测试条件为:STC89C516(11.0592MHz) + OCMJ4X8C 实际显示效果图片如下: 程序部分如下,请结合液晶模块的DATASHEET看程序,这样能够更加快速的弄懂程序的流程。大致有如下几个函数:写数据,写指令,忙检测,初始化,指定地址显示字符串等等。[p][/p] #include "reg52.h" #include "intrins.h" sbit io_LCD12864_RS = P1^0 ; /****************************** 2012年5月19日 调试成功 编辑环境:ICCAVR 功能:用LCD12864显示汉字 ********************************/ #include 本例程为通过用AT89C52芯片操作LCD12864显示的程序,使用的晶振为12M。 /********************************************************** 程序说明:LCD12864显示主程序 程序调试员:莫剑辉 调试时间:2010-6-7 **********************************************************/ #include #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,"删除*"); AT89s52-LCD12864多页菜单按键选择操 作 这篇程序的代码还未理解清楚,再一次深刻发现自 己的算法水平不行。今天学到的东西还行,就是那些C 文件的一些知识。反正都是些优化的东西,以后肯定也 用的着,过几天有兴趣的话,再去学习一下AVR单片机。 程序代码:硬件上与前面一样,有点变化就是多了 两个翻页的按键。到现在一整天的饭都还没吃,该去吃了,干这个果然不会困。 #include #include sbit RS = P2^4; sbit RW = P2^5; sbit E = P2^6; sbit PSB= P2^1; //串并口选择端并高串低 #define DataPort P0 sbit KEY_ADD=P3^3; //按键 sbit KEY_DEC=P3^4; unsigned char curr,currold;//全局变量,当前箭头位置 unsigned char code user16x16[]={ //箭头图片 0x00,0x00,0x20,0x00,0x30,0x00,0x38,0x00,0x3C,0x00 ,0x3E,0x00,0x3F,0x00,0x3F,0x80, 0x3F,0xC0,0x3F,0x80,0x3F,0x00,0x3E,0x00,0x3C,0x00 ,0x38,0x00,0x30,0x00,0x20,0x00, }; unsigned char code *MainMenu[]= { {" 1.设置1"}, {" 2.设置2"}, {" 3.设置3"}, {" 4.设置4"}, {" 5.设置5"}, {" 6.设置6"}, {" 7.设置7"}, {" 8.设置8"}, {" 9.设置9"}, 看到工具箱旁边那个LCD12864很久没用了(当初买回来用的时候只是简单地测试了一下),于是萌生了重新写一次接口程序的想法(而且这次要给它加个图片显示的功能),好,说做就做,就用Atmega16和ICCAVR来做吧,最近这MCU和平台用得比较熟练。 马上从书堆里把当初打印出来的中文datasheet给翻了出来,依葫芦画瓢地写了个初始化程序。好,OK。编译通过。于是又写了一个可以自定义从XY坐标值开始输出显示的函数,再次编译,也通过,OK。于是呼马上写了四行简单的字符烧到单片机上试了一下,嘿嘿,一次通过。如下图: 后来在进一步测试的时候也出了点小问题。就是我是使用USBISP烧写器把程序烧写进AVR的(此时实验板由USBISP烧写器供电),想要实现从第一行的第一个字符开始连续显示"0123456789"。刚烧写完程序后能看到LCD12864上正常显示"0123456789",但是把烧写器从实验板上断开连接,单独用USB给实验板供电的时候,LCD的第一行只是显示"123456789",第一个字符消失了……,左思右想地弄了一个多小时后,终于把问题给解决了,就是把初始化程序的延时适当增加了些,真是奇怪。刚开始一直想不通为什么在烧写器供电的情况下就正常显示,而换到USB供电后就出了问题。后来再想想,估计是跟供电有关。在使用USBISP烧写器供电的时候,LCD的背光灯明显比用USB供电的时候来得亮,而且对比度也高很多,看来是因为换到USB供电后,供电不怎么充足,以至于LCD在上电初始化的时候花上了更多的时间去初始化(因为供电低了,功率小了,跑起来有点力不从心,用的时间就久了嘛……我是觉得可以这样去理解的 接下来呢,就到了有点难度的画图了。当初刚买到12864的时候只是简单测试了字符显示功能,除了因为画图还不需要用到,另外一个原因就是那datasheet上关于画图那部分的内容不怎么看得懂…。现在重新拿起来看,依然一头雾水……。马上上网百度了一下“12864 7920 显示图片”,看到了不少的例子程序,可是……就是没看到有关于这部分功能实现的详细思路和讲解……下载下来的那些程序,基本上没注释,不是说晦涩难懂,但是至少看起来一团糟,让人家不想继续看下去……于是还是硬着头皮去啃那datasheet。上面对于画图这部分的内容是这样讲解的: 以下是RT12864引脚功能定义 引脚号 管脚 说明 1 Vss 电源地(0V)。 2 VDD 电源正(+5V)。 3 V0 LCD 驱动电压,应用时在VEE 与V0之间加一20K 可调电阻。 4 D/I 数据\指令选择: 高电平:数据D0-D7将送入显示RAM 低电平:数据D0-D7将送入指令寄存器执行。 5 R/W 读\写选择:高电平:读数据;低电平:写数据。 6 E 读写使能,高电平有效,下降沿锁定数据。 7 DB0 数据输入输出。 8 DB1 9 DB2 10 DB3 11 DB4 12 DB5 13 DB6 14 DB7 15 CS1 片选择信号,低电平时选择前64列。 16 CS2 片选择信号,低电平时选择后64列。 17 RET 复位信号,低电平有效。 18 VOUT LCD 驱动电源(-10V )。 19 LED+ 背光电源,LED+(+5V)。 20 LED- 背光电源,LED-(0V)。 以下是RT12864引脚功能定义 引脚号 管脚 说明 1 Vss 电源地(0V)。 2 VDD 电源正(+5V)。 3 V0 LCD驱动电压,应用时在VEE与V0之间加一20K可调电阻。4 D/I 数据\指令选择: 高电平:数据D0-D7将送入显示RAM 低电平:数据D0-D7将送入指令寄存器执行。 5 R/W 读\写选择:高电平:读数据;低电平:写数据。6 E 读写使能,高电平有效,下降沿锁定数据。7 DB0 数据输入输出。 8 DB1 9 DB2 10 DB3 11 DB4 12 DB5 13 DB6 14 DB7 15 CS1 片选择信号,低电平时选择前64列。 16 CS2 片选择信号,低电平时选择后64列。 17 RET 复位信号,低电平有效。 18 VOUT LCD驱动电源(-10V )。 19 LED+ 背光电源,LED+(+5V)。 20 LED- 背光电源,LED-(0V)。 基于STM32--LCD12864驱动程序 STM32 LCD12864驱动程序(头文件)(2012-05-29 21:25:08)转载▼ 标签:杂谈 #ifndef LCD12864_H #define LCD12864_H #define LCD_CONTROL GPIOD //默认LCD12864的控制口在PD口 #define LCD_DATAPORT GPIOD //默认LCD12864的数据口在PD口 #define LCD_RESET_Pin GPIO_Pin_12 //默认LCD12864的复位引脚连接到PD.12 也可不用 #define LCD_RS_Pin GPIO_Pin_13 //默认LCD12864 RS -- PD.13 #define LCD_RW_Pin GPIO_Pin_14 //默认LCD12864 RW -- PD.14 #define LCD_EN_Pin GPIO_Pin_15 //默认LCD12864 E -- PD.15 #define LCD_CONTROL_CLOCK RCC_APB2Periph_GPIOD //默认LCD12864的控制口时钟 #define LCD_DATAPORT_CLOCK RCC_APB2Periph_GPIOD //默认LCD12864的数据口时钟 #define LCD_RS_1 LCD_CONTROL->BSRR &=~LCD_RS_Pin;LCD_CONTROL->BSRR |=LCD_RS_Pin //RS置高电平 #define LCD_RS_0 LCD_CONTROL->BRR &=~LCD_RS_Pin;LCD_CONTROL->BRR |=LCD_RS_Pin //RS置低电平 #define LCD_RW_1 LCD_CONTROL->BSRR &=~LCD_RW_Pin;LCD_CONTROL->BSRR |=LCD_RW_Pin //RW置高电平 #define LCD_RW_0 LCD_CONTROL->BRR &=~LCD_RW_Pin;LCD_CONTROL->BRR |=LCD_RW_Pin //RW置低电平 #define LCD_EN_1 LCD_CONTROL->BSRR &=~LCD_EN_Pin;LCD_CONTROL->BSRR |=LCD_EN_Pin //EN置高电平 #define LCD_EN_0 LCD_CONTROL->BRR &=~LCD_EN_Pin;LCD_CONTROL->BRR |=LCD_EN_Pin //EN置低电平 用12864显示单色图片 首先介绍本12864液晶显示器: 型号:QC12864B 因为单片机读取的是数据,而不是直接的图片。得将图片进行取模,图片应该是单色图片,像素128*64。 下面我为大家介绍个实例。 ①、在电脑附件画图,首先设置属性 开始画图 保存文件,注意格式: ②、然后进行取模。 ③、编程: #include 51单片机+带字库液晶12864+DS1302数字时钟C源程序(无按键修改功能)过两天的搜索与调试,在别人程序的基础上,不断修改,终于调试成功了这个程序。目前还不能修改时间与日期,只是以预定时间以始。 适用于开发板:51单片机(AT89S52)+带字库液晶12864(ST7920)+DS1302(实时时钟) 实现功能:简单,数字时钟+日期(以后会不断完美)。 C语言源程序如下: #include LCD12864原理与应用 1、LCD12864简介: LCD12864分为两种,带字库的和不带字库的,不带字库的液晶显示汉字的时候可以选择自己喜欢的字体。而带字库的液晶,只能显示GB2312字体,当然也可以显示其他的字体,不过是用图片的形式显示。 下面介绍不带字库的LCD12864,以Proteus中的AMPIRE128×64为例,如下图所示,它的液晶驱动器为KS0108。 与带字库的液晶不同,此块液晶含有两个液晶驱动器,每块驱动器都控制64*64个点,分为左右两个屏幕显示,总共为128*64个点(即有128×64个点)。这就是为什么AMPIRE128*64有CS1和CS2两个片选端的原因。此液晶有8页,一页有8行点阵点,左右各64列,共128列。如下图所示: 2、LCD12864中的几条重要指令 (一)行(line)设置命令: 由此可见显示的起始行地址为0XC0,共64行,有规律地改变起始行号,可以实现滚屏效果。(二)页(page)设置指令: 起始页地址为0XB8,因为液晶有64行点,分为8页,每页就有8行点。 (三)列(column)地址设置指令 每块驱动器的列地址都是从0X40到0X7F,共64列,所以此液晶共有128列点。 (四)读状态指令 3、用LCD12864显示汉字(一) 由于这块液晶不带字库,我们就要自己编写字库,编写字库所用的字模提取软件为Zimo21(软件下载地址https://www.doczj.com/doc/c73220716.html,/),LCD1602显示自定义字符的时候也是用它。在取模之前我们要进行一些设定,根据此液晶的显示原理,设置为“纵向取模,字节倒序”,如下图所示:(若不是这样,则取模得到的数据不是我们想要的,将会出现乱码,同样可以在https://www.doczj.com/doc/c73220716.html,/下载到关于字模提取原理文档) 字体选择默认的“宋体,常规,小四号”,小四号为16*16大小,如下图所示: LCD12864图形液晶并口显示 【教学引入】 液晶屏,在生活中很常见,我们常见的液晶显示器,如电脑的显示器,电视机,手机等等。 液晶屏在生活中已得到了普遍应用,它显示个各种各样的画面。 【教学目标】 1、掌握LCD12864液晶屏的用法; 2、编写LCD12864液晶屏的指令代码; 【知识目标】 1、掌握LCD12864液晶屏的用法; 2、掌握LCD12864液晶屏指令代码; 【教学准备】 电脑、Proteus、Keil 【教学方法】 教法:讲授法、讨论法 学法:练习法、探究法 【教学课时】 四课时 【教学过程】 一、12864液晶介绍 (1)12864是128*64点阵液晶模块的点阵数简称,业界约定俗成的简称。12864点阵的屏显成本相对较低,适用于各类仪器,小型设备的显示领域。12864M汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。 12864引脚说明 查阅“12864M.PDF”12864M液晶显示模块技术手册——四、用户指令集 1、指令表1:(RE=0:基本指令表),如下图,讲解了12864的基本指令集和扩充指令集。 当模块在接受指令前,微处理器必须先确认模块内部处于非忙碌状态,即读取BF标志时BF需为0。“RE”为基本指令集与扩充指令集的选择控制位元,往后的指令集将维持在最后的状态。 当选择G=0 :绘图显示OFF,汉字显示的时,12864屏只能显示8X4=32个汉字,下面是汉字显示的坐标 二、12864液晶屏驱动电路 原件名称所属类(Category) 所属子类(Sub-category) AT89C52 Microprocessor ICs 8051 Family POT-HG Resistors Variable RESPACK-8 Resistors Resistor Packs LCD12864A 自制- AT89C52的P0口连接12864的并行数据口,RP1为P0口的上拉排阻。 三、52代码编写 (1)打开keil uVision4,建立一个新的工程,工程名为"12864 graphic LCD parallel display",保存类型*.uvproj,单片机型号AT89C52。在工程中添加12864 graphic LCD parallel display.c文件,如下图 编写者:董新凯2011.7.20 仅供交流 #include #include LCD12864显示程序
12864液晶显示图片原理(完整版)
玩转12864液晶(1)--显示字符
LCD12864写字符串程序及其头文件
LCD显示程序
12864并行多级菜单程序
AT89s52LCD12864多页菜单按键选择操作
12864显示图形
最完整的12864测试程序
基于STM32--LCD12864驱动程序
在12864显示任意图片及参考程序
51单片机+带字库液晶12864+DS1302数字时钟C源程序(无按键修改功能)
LCD12864原理与应用(源程序+原理图+proteus仿真)
LCD12864图形液晶并口显示
基于12864的菜单设计
12864液晶显示程序(图案+文字)