- 1、小猪外链里发表的文章仅代表作者本人的观点,与本网站立场无关。
2、小猪外链网资源分享仅为个人学习、交流之用,同时向原著作者表达敬意。
3、小猪外链网仅提供信息存储空间服务,小猪外链网信息均来源于用户自行发布,不承担任何法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,可以按照《小猪外链网文章侵权处理流程》进行处理,同时向原著作者表达敬意。
4、内容由网友自主上传,如有侵权、违规请联系邮箱616859395@qq.com进行处理。


文章开头备注名称:这一篇文章只是是对12864实际操作的一个实际详细介绍,仅限于给刚触碰12864的初学者,高手请拍砖,文章内容写的较为散,提议初学者先参照12864指南及其操纵控制器ST7920英语指南,在有一个基本了解以后再阅读文章该一篇文章,将会出现更为深层次的了解。强烈要求细心的阅读文章ST7920英语指南!关键点內容里边有完整的详细介绍,汉语的12864也大多数是以中译回来的。
文中是分成三个流程来详细介绍12864的內部資源基本原理,指令系统详尽解读,及其运用的事例。
针对12864的任何实际操作归纳起來就会有4种:
1)、读忙情况(与此同时会读取表针详细地址的內容),在复位以后每一次对12864的读写能力均要开展忙检验。
2)、写指令:全部的指令可以去查询指令表,后面会解读命令的详尽使用方法。写详细地址也就是写命令。
3)、写数据信息:实际操作的目标有DDRAM、CGRAM、GDRAM。
4)、读取数据:实际操作的目标也是DDRAM、CGRAM、GDRAM。
针对12864的培训最先要去掌握其內部資源,知道它里边究竟有什么物品,你也就可以更为方便快捷的去运用它了。
先简易详细介绍几个英文的名称:
DDRAM:(Data Display Ram),统计显示RAM,往这里边写啥,显示屏它便会表明啥。
CGROM:(Character Generation ROM),标识符产生ROM。里边是储存了汉语中国汉字的点阵字,也称作中文字库,编码方法有GB2312(中文简体)和BIG5(中文繁体)。小编所应用的是育松电子器件的QC12864B,解读为此为例子。
CGRAM:(Character Generation RAM),标识符产生RAM,12864內部是给予了64×2B的CGRAM,可以用以客户自定4个16×16标识符,每一个字符占有了32个字节数。
GDRAM:(Graphic Display RAM):图型表明RAM,这一块地区是用以制图的,同样——往里写啥,显示屏也便会表明啥,它与DDRAM的差异取决于,往DDRAM中写的数据信息是标识符的编号,标识符的表明起先在CGROM中寻找点阵字,随后再投射到显示屏上的,而往GDRAM中写数据信息时,图型的点阵式信息内容每一个点都用1bit来储存其表明是否。
HCGROM:(Half height Character Generation ROM):半宽标识符产生器,是英文字母与数据,也就是ASCII码。
对于ICON RAM(IRAM):好像如今市面上的12864沒有此项作用,小编都没有去寻找它的运用材料,因此在这儿未作详细介绍了。
下边咱们就紧紧围绕这上边例举的这列資源来进行对12864的解读:
DDRAM:
小编所采用的这方面12864內部是有4行×32字节数的DDRAM室内空间。可是在某一时时刻刻,显示屏只可以表明2行×32字节数的室内空间,那麼剩下的那些室内空间呢?他们是可以用以存储的,在完成卷屏表明时这种室内空间就可以大展身手了。
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
表明:鲜红色一部分的数据信息是归上边屏所表明,翠绿色一部分的数据信息是归下半屏所表明。一般我们在用以显示应用的是上边二行的室内空间,也就是80H~8FH,90H~9FH,每一个详细地址的室内空间是2个字节数,也就是1个字,因此它可以用以储存字符集的室内空间一共便是128字节数。由于每一个汉字的编码是2个字节数,因此每一个详细地址就要应用2个字节数来储存一个中国汉字。自然假如将这2个字节数拆出来应用也是可以的,那便是表明出2个半宽标识符了。
DDRAM內部所储存的信息全是标识符的编号,可以载入的编号有ASCII码、GB2312码、BIG5码。小编所采用的12864中文字库好像不太全,标识符的“数”都不显示,反而是表明出别的标识符。假如表明长篇小说中国汉字文章内容就优势不太合适了。
DDRAM数据信息的读写能力:
全部的数据信息读写能力都应该是先送详细地址,随后再开展读写能力。对DDRAM写数据信息时,保证 在主要的指令系统下(应用命令0x30打开),随后载入详细地址,以后再持续的载入2个字节数的数据信息。在读取数据时,在基本上指令系统下先写详细地址,随后再假读一次,以后再持续读取2个字节数的数据信息,看完以后详细地址表针全自动加一,跳到下一个字,若必须读下一个字的內容,只需再实行持续读2个字节数的数据信息。这儿的假读必须留意,不仅是读CGRAM必须假读,读别的的GDRAM、DDRAM都必须先假读一次,以后的读才算是真读,假读便是读一次数据信息,可是不容易储存该数据信息,换句话说送详细地址以后第一次读的数据信息时不正确的,以后的数据信息才算是准确的。(dummy为假读)
有关编号在DDRAM中的储存必须表明的事宜如下所示:
1)、每一次针对DDRAM的实际操作企业全是一个字,也就是2个字节数,当往DDRAM载入数据信息时,最先要写详细地址,随后持续送进2个字节数的数据信息,先送高字节的数据,再送低字节的数据信息。读取数据时也是这般,先写详细地址,随后再读取高字节数据信息,再读取低字节的数据信息(读取数据时一定要注意要先假读一次)。
2)、表明ASCII码半宽标识符时,往每一个详细地址送进2个字节数的ASCII编号,相匹配显示屏上的部位便会展现出2个半宽标识符,左侧的为高字节标识符,右侧的则为低字节标识符。
3)、表明中国汉字时,汉字编码的2个字节数务必要储存在同一详细地址室内空间当中,不能够分离放到2个详细地址储放,不然表明的就不可能就是你要想的标识符。每一个字中的2个字节数全自动融合搜索点阵字而且显示。因此,如果我们往一个详细地址中载入的是一个文字的2字节数编号便会恰当表明该标识符,编号高字节储放在前一详细地址低字节,编号低字节储放在后一详细地址高字节,显而易见她们就不容易融合搜索点阵字,反而是与各详细地址相对应字节数融合搜索点阵字。
4)、由于控制板ST7920给予了4个自定标识符,因此这4个自定标识符也是可以彻底表明出去的,一样这4个自定标识符也是选用了编号的方法,可是这4字符的编号是确定的,分别是0000H,0002H,0004H,0006H。如下图所示:
图中仅仅把2字符的CGRAM室内空间画出去,后面还会继续有2字符。能够看见每一个字符都是有16行16列,每一行应用了2个字节数,因而一个字符所占有的室内空间是32字节数,详细地址是6位的,4字符的详细地址分别是:00H~0FH、10H~1FH、20H~2FH、30H~3FH。编号应用的是2个字节数,能够看见有2个位数是随意的,表明实际上这4字符的编号可以有好几个,仅仅大家常见前边例举的4个编号。
CGRAM: (数据信息读写能力)
CGRAM的构造便是上边所显示的了,这儿再度填补一些读写能力CGRAM的內容,读写能力以前要先写详细地址,写CGRAM的命令为0x40 详细地址。可是我们在写详细地址时只必须写第一行的详细地址,例如第一个标识符便是0x40 00H,随后持续载入2个字节数的数据信息,以后详细地址表针便会全自动加一,跳至下一行的详细地址,随后再载入2个字节数的数据信息。实际上程序编写完成便是载入详细地址,随后持续载入32个字节数的数据信息。读取数据也是先写首详细地址,随后假读一次,然后持续读32个字节数的数据信息。
GDRAM:(制图表明RAM)
制图RAM的空间布局如下图所示:
这种全是点阵式,制图RAM便是给这种点阵式置1或是置0,能够看见实际上它原本是32行×256列的,可是它分为了左右两屏表明,每一个点都相匹配了显示屏上的一个点。要应用制图作用必须打开拓展命令。随后写详细地址,再读写能力出数据信息。
GDRAM的读写能力:
最先要表明对GDRAM的实际操作基本要素是一个字,也就是2个字节数,也就是说读写能力GDRAM时一次至少要写2个字节数,一次至少读2个字节数。
写数据信息:先打开拓展的指令系统(0x36),随后再送详细地址,这儿的详细地址与DDRAM中的略有一些不一样,DDRAM中的详细地址就只有一个,那便是字的详细地址。而GDRAM中的地址就仅有2个,各自是字详细地址(列地址/水准详细地址X)及其位详细地址(行地址/竖直详细地址Y),图中当中的竖直详细地址便是00H~31H,水准详细地址便是00H~15H,在写详细地址时要先写竖直的详细地址(行地址)再写水准详细地址(列地址),换句话说要持续载入2个详细地址以后,随后再持续载入2个字节数的数据信息。如下图中所显示,左侧的为高字节右侧的为低字节。为1的点被描黑,为0的点则是表明出空缺。这儿就例举一个写详细地址的事例:写GDRAM详细地址命令的是0x80 详细地址。被再加上的详细地址便是上边所例举的X和Y,假定我们要写第一行的2个字节数,那麼载入详细地址便是0x00H(写行详细地址)随后写0x80H(列详细地址),以后才持续的载入2个字节数的数据信息(先高字节后低字节)。再如写显示屏右下方的2个字节数,先写行详细地址0x9F(0x80 32),再写列地址0x8F(0x80 15),随后持续载入2个字节数的数据信息。程序编写中写详细地址函数公式中立即用主要参数(0x 32),而就无须自身累加。
读取数据:最先打开拓展指令系统,随后再写行详细地址、写列地址,假读一次,再持续读2字节数的数据信息(先高字节后低字节)。
读写能力时钟频率:
读写能力状态图如下所示:(图中为写,下面的图为读)
状态图当中的数据信号管脚便是12864最首要的管脚,分别是:
RS:指令/数据寄存器挑选端
WR:读写能力的操纵端
E:也就能端
DB7~DB0:数据信息端
全部针对12864的实际操作基本上全是紧紧围绕着两根管脚所进行的。包含写指令、写数据信息、读取数据、读状态便是根据这一些管脚的高低电频配搭来完成的。
依据状态图可以编写出相对应的写指令函数公式、写数据信息函数公式、读取数据函数公式、读状态函数。必须的留意的是合理数据信息发生的那一段时间Tc务必适合,不可以过短,不然便会导致读写能力不成功。
得出好多个函数公式实例:
//忙检验,若忙则等候,最多等待的时间为60ms
void busychk_12864(void){
unsigned int timeout = 0;
E_12864 = 0;
RS_12864 = 0;
RW_12864 = 1;
E_12864 = 1;
while((IO_12864 & 0x80) && timeout != 0); //忙情况检验,等候请求超时時间为60ms
E_12864 = 0;
}
//写指令程序段
void wrtcom_12864(unsigned char com){
busychk_12864();
E_12864 = 0;
RS_12864 = 0;
RW_12864 = 0;
IO_12864 = com;
E_12864 = 1;
delay_12864(50); //50us也就能延迟!!!留意这儿,如果是迅速的CPU应当延迟久一些
E_12864 = 0;
}
//读取数据程序段
unsigned char reddat_12864(void){
unsigned char temp;
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;
return temp;
}
//写数据信息程序段
void wrtdat_12864(unsigned char dat){
busychk_12864();
E_12864 = 0;
RS_12864 = 1;
RW_12864 = 0;
E_12864 = 1;
IO_12864 = dat;
delay_12864(50); //也就能延迟!!!留意这儿,如果是迅速的CPU应当延迟久一些
E_12864 = 0;
}
在其中,忙检验是必不可少的,当BF=1时,表明內部已经开展相应的实际操作,即:处在忙情况。在BF变成0以前ST7920不容易接纳一切命令。MCU务必要检验BF以明确ST7920內部使用是不是顺利完成,随后才可以再推送命令。还可以应用延迟来取代忙检验,可是必须延迟充足的時间。盲检验具体便是读內部的情况存储器,该寄存器最大位(D7)为忙标示BF,剩下的7位为详细地址表针的內容,因此在完成盲检验事实上也把详细地址表针中的详细地址读出了。
指令系统:
指令集是分成基本上指令系统及其拓展指令系统,应用对应的指令系统务必要先写相对应命令表明后面命令均为此类命令。如应用基本上指令系统时,写命令(0x30),必须应用拓展指令系统时写命令(0x34)转换到拓展指令系统。
一)基本上的指令系统(RE=0):(在应用拓展指令系统时先写命令0x30,这促使RE=0)
清屏命令(0x01):往DDRAM填满0x20,表针的详细地址写0x00。主要表现在显示屏幕上的便是表明空缺。
回车键命令(0x02/0x03):详细地址表针內容写上0x00.
进到方式:0 0 0 0 0 1 I/D S:设定读写能力数据信息以后鼠标光标、表明挪动的方位。內部有2个可编位,I/D表明读写能力一个字符后数据信息表针是加一或是减一。I/D=1表针加一,I/D=0指针减一。S=1打开屏面挪动。
S I/D= H H,显示屏每一次偏移一个字符。
S I/D= H L ,显示屏每一次偏移一个字符。
可是平常若不打开显示屏挪动,这儿表明一个定义,那便是显示屏挪动,具体实验中若打开了显示屏挪动你能产生表明是特别古怪的,表明如下所示:因为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与表明投射关联持续的在更改。可是这不太合乎大家的阅读习惯,因此要是必须应用到此项作用还需程序编写校准之。
表明、鼠标光标、闪动电源开关:0 0 0 0 0 0 1 D C B:
D=1: 表明开(Display) C=1: 鼠标光标开(Cursor) B=1: 光标部位闪动开(Blink)。为0则就为关。
鼠标光标表明挪动操纵:0 0 0 1 S/C R/L X X
表明:
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行。仅有托动表明才可以将另二行的统计显示出去。
读忙标示(详细地址):与此同时忙标示和详细地址读出。忙情况时,ST7920不容易接纳一切命令。依照状态图将RS置0,RW置1,随后载入情况存储器。
写RAM(DDRAM/CGRAM/GDRAM):写了操纵逻辑性(函数公式wrtcom_12864(详细地址);)以后,立即送数据信息(wrtdat_12864)。写完后详细地址表针依据进到方式中的设定加一或减一。写数据信息前先写详细地址,而写地址自身是一个写详细地址指令,随后再写数据信息。
读RAM(DDRAM/CGRAM/GDRAM):还记得先假读一次,后边的才算是真读,假读以后不用再假读过,除非是更改了详细地址。
二)拓展指令系统(RE=1):(应用拓展指令系统先写命令0x34,这促使RE=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); //打开基本上指令系统
拓展作用设定:0x36设置制图表明开。
当GDRAM写完了以后,写0x36则屏幕上显示你所制作的图型。
0 0 0 0 1 DL x RE G x (RE=1拓展命令,G=1开制图表明,DL=1表示8为插口)
设定GDRAM详细地址:制图时,必须将GDRAM的详细地址载入详细地址表针中,随后才可以载入数据信息。持续载入2个字节数,第一个为行详细地址(Y),第二个为列地址(X)。
必须留意的是:写了数据信息以后,详细地址表针会全自动加一(以字为企业),当抵达这家银行的行尾时,表针下一次加一会促使详细地址表针跳回这家银行行首,也便说假如详细地址数值8FH时,下一次它便是80H(以第一个人行为例)。表针详细地址在行内中间循环系统。
命令详细介绍完
再讲下复位全过程,依据ST7920的指南给予的复位流程就可以了。
复位函数公式如下所示:
//延迟程序段
void delay_12864(unsigned int del){
unsigned int i;
for(i = 0; i < del; i ){; }
}
//复位12864子函数
void initial_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 <reg52.h>
#define IO_12864 P0
sbit RS_12864 = P2^5;
sbit RW_12864 = P2^6;
sbit E_12864 = P2^7;
sbit RST_12864 = P2^2;
//忙检验,若忙则等候,最多等待的时间为60ms
void busychk_12864(void){
unsigned int timeout = 0;
E_12864 = 0;
RS_12864 = 0;
RW_12864 = 1;
E_12864 = 1;
while((IO_12864 & 0x80) && timeout != 0); //忙情况检验,等候请求超时時间为60ms
E_12864 = 0;
}
//写指令程序段
void wrtcom_12864(unsigned char com){
busychk_12864();
E_12864 = 0;
RS_12864 = 0;
RW_12864 = 0;
IO_12864 = com;
E_12864 = 1;
delay_12864(50); //也就能延迟!!!留意这儿,如果是迅速的CPU应当延迟久一些
E_12864 = 0;
}
//读取数据程序段
unsigned char reddat_12864(void){
unsigned char temp;
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;
return temp;
}
//写数据信息程序段
void wrtdat_12864(unsigned char dat){
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子函数
void initial_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()函数公式以前,我们在主函数中程序编写:
void main(){
unsigned char i,*addr;
unsigned char defchar[] = {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。
在写主函数以前先写好多个子函数,表明其功效:
void clnGDR_12864(void) //清除GDRAM
void drawdot_12864(unsigned char y,unsigned char x,unsigned char type) //画好点子函数公式
为何要清除GDRAM呢,由于命令集中化沒有GDRAM清除命令,而大家往里写了哪些它便会一直储存着,因此大家画点以前先清除GDRAM,实际上清除GDRAM便是持续往里写0x00。
//清除GDRAM,一共便是写1KB的0x00。
void clnGDR_12864(void){
unsigned char j,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 );
}
}
}
//画点函数,左上方为定位点(0,0)
//右下方为(63,127),点座标方式为(行座标,列坐标)
//主要参数type用以设定画小黑点、小白点或取反(黑泛白,白变黑)
//type = 0为乳白色,1 为灰黑色,2为取反
void drawdot_12864(unsigned char y,unsigned char x,unsigned char type){
unsigned char X,Y,k; //X储存行详细地址,Y储存列详细地址
//k存储点在字中的地方从左至右为0~15
unsigned char DH,DL; //储放读出数据的高字节和低字节
if(y >= 0 && y <= 63 && x >= 0 && x <= 127) {
if(y < 32){ //优化算法:明确所画点的详细地址行与列地址
X = 0x80 (x >> 4);
Y = 0x80 y;
}else{
X = 0x88 (x >> 4);
Y = 0x80 (y - 32);
}
wrtcom_12864(0x34); //打开拓展命令,关掉制图表明
wrtcom_12864(Y); //载入所明确的点的行位详细地址
wrtcom_12864(X); //载入所明确的点的列字详细地址
DH = reddat_12864(); //假读
DH = reddat_12864(); //读高字节
DL = reddat_12864(); //读低字节
k = x % 16; //被除数为点在字中的部位
//画点
switch(type){ //画点种类,1黑或0白或2取反
case 0:
if(k < 8){ //点在高字节
DH &= ~(0x01 << (7 - k)); //改动该点与此同时维持别的位不会改变
}else{ //点在低字节
DL &= ~(0x01 << (7 - (k % 8))); //改动该点与此同时维持别的位不会改变
}
break;
case 1:
if(k < 8){
DH |= (0x01 << (7 - k)); //改动该点与此同时维持别的位不会改变
}else{
DL |= (0x01 << (7 - (k % 8))); //改动该点与此同时维持别的位不会改变
}
break;
case 2:
if(k < 8){
DH ^= (0x01 << (7 - k)); //改动该点与此同时维持别的位不会改变
}else{
DL ^= (0x01 << (7 - (k % 8))); //改动该点与此同时维持别的位不会改变
}
break;
default:
break;
}
wrtcom_12864(Y); //写行位详细地址
wrtcom_12864(X); //写列字地址
wrtdat_12864(DH); //将高字节数据信息写回
wrtdat_12864(DL); //将低字节数据写回
wrtcom_12864(0x30); //转到一般命令
}
}
下边撰写主函数,这就简易了,如下所示:
void main(void){
delay_12864(1000);
initial_12864();
clnGDR_12864(); //清除GDRAM
drawdot_12864(20,50,1); //画点
wrtcom_12864(0x36); //开制图表明
while(1);
}
程序执行后相对应部位发生了一个小黑点,手机屏幕坏了,拍不上照,要不然就贴下相片。
随后依据画点函数,拓展一个画矩形框的函数公式吧:
//画矩形框子函数,主要参数为(点1行座标,点1列坐标,
//点2行座标,点2列坐标,线框色调(0为白,1为黑,2对本色取反))
void drawrec_12864(unsigned char y1,unsigned char x1,unsigned char y2,unsigned char x2,unsigned char type){
unsigned char largex,largey,smallx,smally; //将二点横纵轴按尺寸储存
unsigned char i;
if(x1 > x2){
largex = x1;
smallx = x2;
}else{
largex = x2;
smallx = x1;
}
if(y1 > y2){
largey = y1;
smally = y2;
}else{
largey = y2;
smally = y1;
}
//下列制作4条矩形框外框
for(i = smallx; i < largex; i ){
drawdot_12864(largey,i,type);
}
for(i = largey; i > smally; i--){
drawdot_12864(i,largex,type);
}
for(i = largex; i > smallx; i--){
drawdot_12864(smally,i,type);
}
for(i = smally; i < largey; i ){
drawdot_12864(i,smallx,type);
}
wrtcom_12864(0x30); //回到一般命令
}
主函数为:
void main(void){
delay_12864(1000);
initial_12864();
clnGDR_12864(); //清除GDRAM
drawrec_12864(20,50,30,120,1); //画矩形框
wrtcom_12864(0x36); //开制图表明
while(1);
}
有关GDRAM的实际操作就到这吧,下边解读下12864全屏幕托动的完成方式。
3)、12864全屏幕托动的完成方式
最先必须确立的关键点:
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的构造发觉,假如在托动全过程中,在同一时时刻刻屏幕上显示的內容较多涉及到3行DDRAM的內容,而另一行是沒有表明的,那麼这一行便是用于缓存文件的数据信息的。
当屏幕上显示如下所示2行后逐渐托动(一):
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
则显示屏与此同时发生下面3行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
必须留意的是,左侧是上边屏表明,右侧是下半屏表明。
在程序流程的逐渐处往DDRAM相匹配地区填好如下所示內容:
第一行标识符 第三行字符--> 逐渐表明
第二行标识符 第四行字符
第三行标识符 第五行字符--> 将要表明
第四行标识符 第六行字符
那样在逐渐托动以后,就可以完成无缝拼接的作用了。当托动了16次以后,也就是第一行标识符早已移出来显示屏,屏幕上显示的DDRAM如下所示:
第一行标识符 第三行字符
第二行标识符 第四行字符
第三行标识符 第五行字符
第四行标识符 第六行字符
这时,显示屏然后翻转,表明內容涉及到3行的DDRAM,如下所示:
第一行标识符 第三行字符--> 已表明结束
第二行标识符 第四行字符
第三行标识符 第五行字符
第四行标识符 第六行字符--> 将要表明
第一行DDRAM是空闲的,下一次就该往第一行写数据信息,写完后DDRAM內容如下所示:
第五行标识符 第七行字符
第二行标识符 第四行字符
第三行标识符 第五行字符
第四行标识符 第六行字符
通过又一次的16次卷屏以后屏幕上显示內容如下所示:
第五行标识符 第七行字符--> 将要表明
第二行标识符 第四行字符--> 表明结束
第三行标识符 第五行字符
第四行标识符 第六行字符
随后下面又托动16次,小编的优化算法是,在每一次托动后写一个字到表明结束的那一行中,卷完16次,表明结束的那一行也就写完了。随后下面的16次托动又写刚表明结束的那一行,而刚被写完的那一行将在后面16次托动中表明。
基本原理便是这般,随后从这当中获取出规律性,设计方案出优化算法,并程序编写完成:
下边是程序代码:
void main(void){
unsigned char code ser[] = {"一一一一一一一一二二二二二二二二叁叁叁叁叁叁叁叁四四四四四四四四中国中国中国"}; //这也是要展现的字符串数组
//沒有检验回车符作用,只有表明一长串的中国汉字或一串ASCII码标识符。
unsigned char i,addr,flag,hang,over,*ptdat;
//addr用以储存载入详细地址
//flag储存托动详细地址,名称没取好!
//hang储存下一行要载入数据信息的行号(1~4)
//over纪录载入的空字符数
//ptdat储存字符串数组的表针
delay_12864(1000);
initial_12864();
ptdat = ser;
over = 0; //载入空字符数
//这儿先把前边DDRAM中的前3行的标识符数据信息载入
//假如标识符不够<=4行,那麼不托动,以后标识符>4行才托动
//一直到末行表明结束则终止托动
wrtcom_12864(0x80); //写显示屏第一行标识符
for(i = 0; i < 16; i ){
if(*ptdat != '\0'){
wrtdat_12864(*ptdat );
}else{
wrtdat_12864(0x20);
over ;
}
}
wrtcom_12864(0x90); //写显示屏第二行标识符
for(i = 0; i < 16; i ){
if(*ptdat != '\0'){
wrtdat_12864(*ptdat );
}else{
wrtdat_12864(0x20);
over ;
}
}
wrtcom_12864(0x88);//写显示屏第三行标识符
for(i = 0; i < 16; i ){
if(*ptdat != '\0'){
wrtdat_12864(*ptdat );
}else{
wrtdat_12864(0x20);
over ;
}
}
wrtcom_12864(0x98);//写显示屏第四行标识符
for(i = 0; i < 16; i ){
if(*ptdat != '\0'){
wrtdat_12864(*ptdat );
}else{
wrtdat_12864(0x20);
over ;
}
}
ptdat = ptdat - 32;
wrtcom_12864(0xa0); //写DDRAM第3行数据信息
for(i = 0; i < 16; i ){
if(*ptdat != '\0'){
wrtdat_12864(*ptdat );
}else{
wrtdat_12864(0x20);
over ;
}
}
ptdat = ptdat 16;
for(i = 0; i < 16; i ){
if(*ptdat != '\0'){
wrtdat_12864(*ptdat );
}else{
wrtdat_12864(0x20);
over ;
}
}
//前边的编码是往DDRAM中写如下所示內容:
//第一行标识符 第三行字符
//第二行标识符 第四行字符
//第三行标识符 第五行字符
//假如写第5行后全为空,表明标识符恰好4行,不托动。
//这时第5行载入16个0x20空字符,over用以纪录空字符数量。
//假如不够4行,则前边也可能载入空字符,这时写完了3行DDRAM后
//over的值必超过16,而只需over>15,也不托动
wrtcom_12864(0x0c); //开表明
if(over > 15){;} //显示不够4行,不托动
else //显示超过4行,打开托动
{
hang = 4; //下面要写DDRAM第4行数据信息
flag = 0x01; //原始托动详细地址为1
while(1){
switch(hang){ //设定载入DDRAM的详细地址
case 1: addr = 0x80; break; //往地址自变量中写第一行首详细地址
case 2: addr = 0x90; break; //往详细地址自变量中写第二行首详细地址
case 3: addr = 0xa0; break; //往地址自变量中写第三行首详细地址
case 4: addr = 0xb0; break; //往地址自变量中写第四行首详细地址
}
switch(hang){ //强调下一次要写的行详细地址
case 1: hang = 2; break;//第1行写完了,下一行要写第2行
case 2: hang = 3; break;//第2行写完了,下一行要写第3行
case 3: hang = 4; break;//第3行写完了,下一行要写第4行
case 4: hang = 1; break;//第4行写完了,下一行要写第1行
}
//后面编码为往每一行写数据信息,托动一次写一个字。
ptdat = ptdat - 32;
for(i = 0; i < 8; i ){ //写一行中的前8字符
wrtcom_12864(0x34); //开启拓展命令
wrtcom_12864(0x03); //容许键入托动详细地址
wrtcom_12864(0x40 flag ); //设定托动详细地址
wrtcom_12864(0x30); //返回基本上命令
wrtcom_12864(addr i);
delay_12864(20000);
if(*ptdat != '\0'){
wrtdat_12864(*ptdat ); //载入高字节
}else{
wrtdat_12864(0x20); //字符串数组完毕则载入空字符
}
if(*ptdat != '\0'){
wrtdat_12864(*ptdat ); //写入低字节
}else{
wrtdat_12864(0x20); //字符串数组完毕则载入空字符
}
}
ptdat = ptdat 16;
for(i = 8; i < 16; i ){ //写一行中的后8字符
wrtcom_12864(0x34); //开启拓展命令
wrtcom_12864(0x03); //容许键入托动详细地址
if(flag == 64){flag = 0;}
wrtcom_12864(0x40 flag); //设定托动详细地址
flag ;
wrtcom_12864(0x30); //返回基本上命令
wrtcom_12864(addr i);
delay_12864(20000);
if(*ptdat != '\0'){
wrtdat_12864(*ptdat ); //载入高字节
}else{
over ; //写完最终一行标识符,必须再托动16次才可以展现出去。
wrtdat_12864(0x20); //字符串数组完毕则载入空字符
}
if(*ptdat != '\0'){
wrtdat_12864(*ptdat ); //写入低字节
}else{
wrtdat_12864(0x20); //字符串数组完毕则载入空字符
}
}
if(over < 8){;}
else {break;}
}
}
while(1);
}
讲到这儿全部的內容基本上就都详细介绍完后。
黑白液晶屏商品型号选择:http://www.hzjingxian.com/DS/
【申明】一部分信息内容来源于互联网技术,力争安全性立即、准确,目地取决于传送其他信息,并不意味着对其思想观点赞成或对其真实有效承担。如本网转截信息内容涉及到出版权等问题,请立即与本网联络删掉。
网站公告
近期本站被人为恶意注册及发布垃圾帖,每一个发帖都会经过审核,一经发现违法或垃圾帖的用户,帖子将被删除或封号,请大家共同维护互联网环境,共创美好互联网未来。
详细的发帖规则请阅读:
《小猪外链网发帖规则》
《小猪外链网最新金币规则》
注:本站严禁发布灰色违禁违法内容,如发现立刻永久封号,如开通会员的概不退款。
免责申明:本网站内容由平台入驻会员撰写,除创始人账号外,其他观点仅代表作者本人,不代表小猪外链网立场。如果内容涉及侵犯其他公司、团体的利益、请联系小猪SEO外链网客服举证删除
您的IP:3.16.50.172,2025-05-05 15:21:03,Processed in 0.27491 second(s).