12864笔记.docx
- 文档编号:11876527
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:57
- 大小:505.90KB
12864笔记.docx
《12864笔记.docx》由会员分享,可在线阅读,更多相关《12864笔记.docx(57页珍藏版)》请在冰点文库上搜索。
12864笔记
DDRAM:
(DataDisplayRam),数据显示RAM,往里面写啥,屏幕就会显示啥。
CGROM:
(CharacterGenerationROM),字符发生ROM。
里面存储了中文汉字的字模,也称作中文字库,编码方式有GB2312(中文简体)和BIG5(中文繁体)。
笔者使用的是育松电子的QC12864B,讲解以此为例。
CGRAM:
(CharacterGenerationRAM),字符发生RAM,,12864内部提供了64×2B的CGRAM,可用于用户自定义4个16×16字符,每个字符占用32个字节。
GDRAM:
(GraphicDisplayRAM):
图形显示RAM,这一块区域用于绘图,往里面写啥,屏幕就会显示啥,它与DDRAM的区别在于,往DDRAM中写的数据是字符的编码,字符的显示先是在CGROM中找到字模,然后映射到屏幕上,而往GDRAM中写的数据时图形的点阵信息,每个点用1bit来保存其显示与否。
HCGROM:
(HalfheightCharacterGenerationROM):
半宽字符发生器,就是字母与数字,也就是ASCII码。
注意第三脚VO的连接方式,这个是对比度电位引脚,实际中常采用10k的可变电阻滑动端连接vo脚,固定端的一段接vcc,另外一端应根据实际硬件连接。
如果用的是1602,另一端直接接到gnd就可以了,但是对于12864就应该看18脚的标记了,如果写的是NC,那么另一端直接接地,如果是VEE,那么就应该接到18脚,因为这时的18脚是负压输出端。
根据这点确定你的对比对调节电路接法正确无 误。
8位并行写时序:
8位并行读时序:
DDRAM结构如下所示:
80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
A0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFH
B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH
地址与屏幕显示对应关系如下:
第一行:
80H、81H、82H、83H、84H、85H、86H、87H
第二行:
90H、91H、92H、93H、94H、95H、96H、97H
第三行:
88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
第四行:
98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
指令集:
指令集分为基本指令集和扩展指令集,使用相应的指令集必须先写相应指令,表明后续指令均为该类指令。
使用基本指令集时,写指令(0x30),
使用扩展指令集时,写指令(0x34)。
基本指令集:
清屏指令(0x01):
往DDRAM写满0x20,指针地址写0x00。
表现在屏幕就是显示空白
回车指令(0x02/0x03):
地址指针内容写0x00,且光标移至开头位置。
该指令不改变DDRAM内容
进入模式:
000001I/DS:
设置读写数据之后光标、显示移位的方向。
内部有2个可编程位,I/D表示读写一个字符后数据指针是加一还是减一。
I/D=1指针加一,I/D=0指针减一。
S=1开启整屏移动。
SI/D=HH,屏幕每次左移一个字符。
SI/D=HL,屏幕每次右移一个字符。
但是平时不开启屏幕移动,这里说明一个概念,就是屏幕移动,实际试验中若开启了屏幕移动你会发生显示是灰常怪异的,说明如下:
由于DDRAM的结构是下方表所示:
上半屏 下半屏
80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
A0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFH
B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH
在未开启屏移时,屏幕是以表格第一列作为参考起点,然后前8列归上半屏显示,后8列归下半屏显示。
如果此时向左屏移一个字符,那么DDRAM内容与显示映射关系变为:
80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
A0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFH
B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH
可以看到实际上原来第三第四行开始的字符跑到了第一行第二行的末尾,整个DDRAM的结构就是一种循环的结构,发生屏移时DDRAM与显示映射关系不断在改变。
但是这不太符合我们的阅读习惯,所以如果需要使用该项功能还需编程校正之。
显示状态:
00001DCB:
D=1,开显示C=1,,光标显示开B=1,光标位置闪烁开
光标显示移位控制:
0
0
0
1
S/C
R/L
X
X
说明:
S/CR/L
LL:
这时仅仅是将地址指针AC的值减1。
在屏幕上表现是光标左移一个字符。
LH:
这时仅仅是将地址指针AC的值加1。
在屏幕上表现是光标右移一个字符。
HL:
AC指针不变,向左屏移一个字符。
这是DDRAM结构循环左移,80H接在8FH后面,90H接在9FH后面。
这与上面讲的屏移是一样的。
HH:
AC指针不变,向右屏移一个字符。
这是DDRAM结构循环右移,80H接在8FH后面,90H接在9FH后面。
功能设置:
0
0
1
DL
X
RE
X
X
DL=1表示8位接口,DL=0表示4位接口。
RE=1表示开启扩展指令,RE=0表示使用基本指令。
开启基本指令则设置为0x30,开启扩展指令则设置为0x34。
CGRAM地址设置:
0x40+地址。
地址范围是00H~3FH。
前提是SR=0,即允许设置IRAM和CGRAM地址!
!
!
DDRAM地址设置:
只有字地址。
如下表所示。
(注意DDRAM地址有4行×16字)如下所示:
80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
A0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFH
B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH
所以某一时刻只能显示其中的2行。
只有卷动显示才能将另两行的数据显示出来。
读忙标志(地址):
BF
X
X
X
X
X
X
X
同时忙标志和地址读出来。
忙状态时,ST7920不会接受任何指令。
按照时序图将RS置0,RW置1,然后读取状态寄存器。
BF=1表示忙,不能写入内容
扩展指令集:
待机模式:
0x01,不影响DDRAM,所以跟清屏指令不同,任何指令可以结束待机模式。
卷动地址/IRAM地址允许设置:
0
0
0
0
0
0
1
SR
SR=1:
允许设置垂直卷动地址。
SR=0:
允许设置IRAM和CGRAM地址。
设置卷动/IRAM地址:
0x40+地址。
(卷动地址为行地址,即纵向地址).
这里讲解卷动,卷动就是上下滚屏,实现屏幕的垂直滚动。
卷动地址:
地址范围为0x00~0x63,共64行卷动地址其实就是垂直地址。
每一个地址代表着DDRAM中的一行的像素点。
卷动一次就是把该行所有点移到上半屏和下半屏幕最上方。
80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
A0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFH
B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH
还是DDRAM的结构图,需要注意的是卷屏是分上半屏卷动和下半屏卷动,两屏之间没有关系,也就是DDRAM中左边红色部分在上半屏滚动,右边绿色部分在下半屏滚动。
B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H的下一行是
80H、81H、82H、83H、84H、85H、86H、87H
也就是说左边是一个上下相接的循环结构。
同理右边也是上下相接的循环结构。
左边内存中的字符上下滚动。
右边内存中的字符上下滚动,两者木有关系。
要开启卷动,首先开启扩展指令集,然后允许卷动地址设置,再设置卷动地址。
wrtcom_12864(0x34); //打开扩展指令
wrtcom_12864(0x03); //允许输入卷动地址
wrtcom_12864(0x40+地址 //设置卷动地址
wrtcom_12864(0x30); //回到基本指令
要实现全屏滚动,就必须使用循环不断地修改卷动地址。
从00~63如此循环,但遗憾的是这也不符合我们的阅读习惯,后续的应用的中将讲解全屏滚动的实现方法。
这里只是把卷动原理讲清楚。
反白显示:
0
0
0
0
0
1
R1
R0
R1、R0初始化的值为00。
选择1~4任一行反白显示并可决定是否反白。
如何开启反白显示:
首先开启扩展指令(0x34),然后设置选中某一行设置反白显示(0x04+R1R0)。
00为第一行,01为第二行,10为第三行,11为第四行。
需要说明的是,这里的行是指DDRAM所有内存的行,而不是显示的行,屏幕只显示2行。
所以如果我们开启第3第4行的反白显示,不卷动我们是看不到效果的。
同时,如果我们开启第1行反白显示,那么在屏幕中第1行第3行都会反白显示,第2行则对应屏幕第2第4行,这一点需要注意。
如何关闭反白显示:
只需在此写一次地址即可关闭,也就说,第一次写第一开启反白,第二次写相同的地址关闭反白显示。
wrtcom_12864(0x34); //反白显示试验
wrtcom_12864(0x04); //开启反白显示
delay_12864(60000); //延时
delay_12864(60000); //延时
wrtcom_12864(0x04);//关闭反白显示
wrtcom_12864(0x30); //开启基本指令集
睡眠模式:
0
0
0
0
1
SL
X
X
SL=1,退出睡眠模式
SL=0,进入睡眠模式
扩展功能设置:
0
0
1
1
X
RE
G
0
RE=1扩展指令,G=1开绘图显示
0x36设置绘图显示开。
当GDRAM写完了之后,写0x36则屏幕显示你所绘制的图形。
设置GDRAM地址:
1
X6
X5
X4
X3
X2
X1
X0
绘图时,需要将GDRAM的地址写入地址指针中,然后才能写入数据。
连续写入两个字节,第一个为行地址(Y),第二个为列地址(X)。
需要注意的是:
写了数据之后,地址指针会自动加一(以字为单位),当到达该行的行尾时,指针下一次加一会使得地址指针跳回该行行首,也就说如果地址值为8FH时,下一次它就是80H(以第一行为例)。
指针地址在本行之间循环。
1)、读数据时千万不要忘记单片机的IO口要先置为高电平,然后才能再读引脚,这一点笔者大意地忽略了。
2)、12864在写完地址,读数据之前需要一个假读,虚假的读数据,假读之后才是真读,从内部RAM读取数据(DDRAM/CGRAM/GDRAM),当设定地址指令后,若需读取数据时需先执行一次空的读数据,才会读取到正确数据,第二次读取时则不需要,除非又下设定地址指令。
单片机IO拉高部分:
//读数据子程序
unsignedcharreddat_12864(void){
unsignedchartemp;
busychk_12864();
E_12864=0;
IO_12864=0xff; //IO口置高电平,读引脚
RS_12864=1;
RW_12864=1;
E_12864=1;
delay_12864(500);
temp=IO_12864;
returntemp;
}
假读部分:
wrtcom_12864(0x34); //开启扩展指令
wrtcom_12864(Y); //写行位地址
wrtcom_12864(X); //写列位元组地址
DH=reddat_12864(); //假读
DH=reddat_12864(); //读高字节
DL=reddat_12864(); //读低字节
初始化函数如下:
//延时子程序
voiddelay_12864(unsignedintdel){
unsignedinti;
for(i=0;i } //初始化12864子函数 voidinitial_12864(void){ delay_12864(40000); RST_12864=1; RST_12864=0; //复位 delay_12864(500); RST_12864=1; wrtcom_12864(0x30); //设置为基本指令集动作 delay_12864(100); wrtcom_12864(0x30); //设置为基本指令集动作 delay_12864(37); wrtcom_12864(0x08); //设置显示、光标、闪烁全关。 delay_12864(100); wrtcom_12864(0x01); //清屏,并且DDRAM数据指针清零 delay_12864(100000); wrtcom_12864(0x06); //进入模式设置 } 应用部分: 这里讲解12864的几个典型应用: 1)、自编字符创建以及显示 2)、GDRAM的绘制及显示 3)、全屏卷动的实现方法 1)、自编字符创建以及显示 先明确的要点,12864具有4个自编字符,每个字符的编码为0000H、0002H、0004H、0006H,4个自定义字符的CGRAM地址分别为00H~0FH、10H~1FH、20H~2FH、30H~3FH。 我们以第3个字符为例: 在这里先把整个源文件的宏定义以及各子函数贴出: #include #defineIO_12864 P0 sbit RS_12864=P2^5; sbit RW_12864=P2^6; sbit E_12864=P2^7; sbit RST_12864=P2^2; //忙检测,若忙则等待,最长等待时间为60ms voidbusychk_12864(void){ unsignedinttimeout=0; E_12864=0; RS_12864=0; RW_12864=1; E_12864=1; while((IO_12864&0x80)&&++timeout! =0); //忙状态检测,等待超时时间为60ms E_12864=0; } //写命令子程序 voidwrtcom_12864(unsignedcharcom){ busychk_12864(); E_12864=0; RS_12864=0; RW_12864=0; IO_12864=com; E_12864=1; delay_12864(50); //使能延时! ! ! 注意这里,如果是较快的CPU应该延时久一些 E_12864=0; } //读数据子程序 unsignedcharreddat_12864(void){ unsignedchartemp; busychk_12864(); E_12864=0; IO_12864=0xff; //IO口置高电平,读引脚 RS_12864=1; RW_12864=1; E_12864=1; delay_12864(50); //使能延时! ! ! 注意这里,如果是较快的CPU应该延时久一些 temp=IO_12864; returntemp; } //写数据子程序 voidwrtdat_12864(unsignedchardat){ busychk_12864(); E_12864=0; RS_12864=1; RW_12864=0; E_12864=1; IO_12864=dat; delay_12864(50); //使能延时! ! ! 注意这里,如果是较快的CPU应该延时久一些 E_12864=0; } //初始化12864子函数 voidinitial_12864(void){ delay_12864(40000); RST_12864=1; RST_12864=0; //复位 delay_12864(500); RST_12864=1; wrtcom_12864(0x30); //设置为基本指令集动作 delay_12864(100); wrtcom_12864(0x30); //设置为基本指令集动作 delay_12864(37); wrtcom_12864(0x08); //设置显示、光标、闪烁全关。 delay_12864(100); wrtcom_12864(0x01); //清屏,并且DDRAM数据指针清零 delay_12864(100000); wrtcom_12864(0x06); //进入模式设置 wrtcom_12864(0x0c); //开显示 } 以上函数定义在main()函数之前,我们在主函数中编写程序: voidmain(){ unsignedchari,*addr; unsignedchardefchar[] ={0x08,0x10,0x08,0x10,0x08,0x10,0x7F,0xFE,0x20,0x04,0x12,0x48,0x08,0x10,0x05,0xA0,0x02,0x40,0x01,0x80,0x01,0x80,0x07,0xE0,0x09,0x90,0x11,0x88,0x11,0x88,0x11,0x88}; //自定义字符,这里是笔者画的一个小机器人。 delay_12864(100); //启动延时 initial_12864(); //初始化12864 addr=defchar; wrtcom_12864(0x40+0x20);//写CGRAM首行地址 for(i=0;i<32;i++){ wrtdat_12864(*addr++); } wrtcom_12864(0x80); //在第一行第一个字符出显示自定义字符 wrtdat_12864(0x00); //写第三个自定义字符编码的高字节 wrtdat_12864(0x04); //写第三个自定义字符编码的低字节 while (1); } 运行程序就可以看到第一个字符处出现一个小机器人了。 2)、GDRAM的绘制及显示 先明确的要点,GDRAM是32行×16字。 写数据之前必须先送行地址,然后送列地址。 读写的基本操作单元是字(2个字节)。 读写完一个字后地址指针在本行自动加一,到达行末则返回行首地址(地址循环)。 我们这里先以一个画点函数函数为例,然后再根据画点函数写一个绘制矩形的函数: 先建一个坐标左上角为(0,0),右下角为(63,127)。 画点原理: 由于GDRAM的读写基本操作单元是字,那么我们需要画一个点但是又不改变其他点的内容,那么需要把该点所处的字中的2个字节均读出,然后再单独修改我们需要画的那个点(其他位保持不变),最后把该字再写回去。 因此,涉及的操作有先读GDRAM,再写GDRAM,再显示GDRAM。 在写主函数之前先写几个子函数,说明其作用: voidclnGDR_12864(void) //清空GDRAM voiddrawdot_12864(unsignedchary,unsignedcharx,unsignedchartype)//画点子函数 为什么要清空GDRAM呢,因为指令集中没有GDRAM清空指令,而我们往里写了什么它就会一直保存着,所以我们画点之前先清空GDRAM,其实清空GDRAM就是不断往里写0x00。 //清空GDRAM,总共就是写1KB的0x00。 voidclnGDR_12864(void){ unsignedcharj,k; wrtcom_12864(0x34); //在写GDRAM的地址之前一定要打开扩充指令集 //否则地址写不进去! ! for(j=0;j<32;j++) { wrtcom_12864(0x80+j); //写Y坐标 wrtcom_12864(0x80); //写X坐标 for(k=0;k<32;k++)//写一整行数据 { wrtdat_12864(0x00); } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 12864 笔记