内置ST7920控制器和中文字库的LCD12864的使用
前言
大家好,我是小灬贱。今天我给大家带来LCD12864的使用方法以及我的一些经验。
文章里面如有不妥之处或者表达不清晰的地方还请各位多多指教。可以在文下评论或者私信我。
软件环境
1.系统:Windows 10
2.单片机:Atmega16
3.软件环境:Atmel studio 7.0
头文件
#define F_CPU 8000000
#include <avr/io.h>
#include<util/delay.h>
#include <avr/pgmspace.h>
首先我们先来了解屏幕的那么多个引脚分别是干什么的
到这里可能很多人都会有一个问题:一脚究竟是哪个脚?
好,问题不大,我这就告诉你
好,知道引脚对应的是什么功能那我们就继续了解他的控制指令
基本指令表(RE=0)
扩充指令表(RE=1)
指令详解
知道这些指令会让屏幕发什么变化还不够,最重要的就是MCU跟LCD的通信方式和通信要求;
什么是通信呢? 可以理解为MCU跟LCD之间语言(就像我跟你之间有个"普通话"),只有共同的通信方式才能传达我想传达的指令;不然就会可能出现"对牛弹琴"这种无奈又可笑的尴尬;
并行时序图
通过以上时序图,我们可以得知LCD的并行是一个跟6800一样的的通信方式
这个12864的并行通信可以分为两种
- 使用8位数据线外加三根控制线的标准6800通信
- 使用4位数据线外加三根控制线的半6800通信
下面是并行8位数据线的驱动代码
void LCD_WriteOneByte(unsigned char data,unsigned char cmd)
{
RW_0;
if (cmd) RS_1;
else RS_0;
EN_1;
PORTB = data;
_delay_us(10);
EN_0;
_delay_us(100);
}
void LCD_Init()
{
LCD_WriteOneByte(0x30,0);_delay_ms(40);
LCD_WriteOneByte(0x30,0);_delay_ms(40);
LCD_WriteOneByte(0x0c,0);_delay_ms(40);
LCD_WriteOneByte(0x02,0);_delay_ms(40);
LCD_WriteOneByte(0x01,0);_delay_ms(40);
}
下面是并行4位数据线的驱动代码
void LCD_WriteOneByte(unsigned char data,unsigned char cmd)
{
RW_0;
if (cmd) RS_1;
else RS_0;
EN_1;
PORTB = data;
_delay_us(10);
EN_0;
_delay_us(100);
EN_1;
PORTB = (data << 4);
_delay_us(10);
EN_0;
_delay_us(100);
}
void LCD_Init()
{
LCD_WriteOneByte(0x20,0);_delay_ms(40);
LCD_WriteOneByte(0x20,0);_delay_ms(40);
LCD_WriteOneByte(0x0c,0);_delay_ms(40);
LCD_WriteOneByte(0x02,0);_delay_ms(40);
LCD_WriteOneByte(0x01,0);_delay_ms(40);
}
串行时序图
这个串行通信是一个类似3线SPI的通信方式;
他这个串行通信对应的是一个控制字节和一个用户数据(指令)字节;
首先把控制字(第一字节)写入到LCD(告诉LCD我接下来要干什么)
然后把用户数据(指令)分成两个字节写入到LCD,时序的第二字节的高四位是用户数据的高4位,低四为必须为零;第三个字节的高四位是用户数据的低4位,低四位必须为零;
void SID(unsigned char x)
{
if (x) PORTC |= 0x02;
else PORTC &= ~0x02;
}
void LCD_writeOneByte(unsigned char data,unsigned char cmd)
{
CLK_0;
CS_1;
for(unsigned char i=0;i<8;i++)
{
CLK_0;
SID(cmd & (1 << (7-i)));
CLK_1;
}
for(unsigned char i=0;i<8;i++)
{
CLK_0;
SID((data & 0xf0) & (1 << (7-i)));
CLK_1;
}
for(unsigned char i=0;i<8;i++)
{
CLK_0;
SID(((data<<4) & 0xf0) & (1 << (7-i)));
CLK_1;
}
CS_0;
}
void LCD_Init()
{
LCD_WriteOneByte(0x30,0xf8);_delay_ms(40);
LCD_WriteOneByte(0x30,0xf8);_delay_ms(40);
LCD_WriteOneByte(0x0c,0xf8);_delay_ms(40);
LCD_WriteOneByte(0x02,0xf8);_delay_ms(40);
LCD_WriteOneByte(0x01,0xf8);_delay_ms(40);
}
以上是三个通信方式的驱动代码和初始化。
注意:使用8线或者4线并口通信时,12864的PSB要接到高电平;使用3线串口时PSB接低电平;
好啦,准备的差不多啦.PS(这里又有一个不怕死的12864,嘿嘿.肘子,给它上一课(2333))
void LCD_Writehanzi(unsigned char x,unsigned char y,unsigned char *data)
{
switch(y)
{
case 1 : LCD_writeOneByte(0x80+x,0);break;
case 2 : LCD_writeOneByte(0x90+x,0);break;
case 3 : LCD_writeOneByte(0x88+x,0);break;
case 4 : LCD_writeOneByte(0x98+x,0);break;
}
while(*data!='\0')LCD_writeOneByte(*data++,1);
}
int main(void)
{
DDRB = 0XFF;
PORTB = 0X00;
DDRC = 0XFF;
PORTC = 0X00;
_delay_ms(100);
LCD_Init();
while (1)
{
LCD_writehanzi(0,2,"祖国母亲70");
LCD_writehanzi(1,3,"周年快乐!!");
}
}
然后显示图片。
void LCD_Drawing(unsigned char *data)
{
for(unsigned char i=0;i<32;i++)
{
LCD_writeOneByte(0x80+i,0);
LCD_writeOneByte(0x80,0);
for (unsigned char q=0;q<16;q++)
{
LCD_writeOneByte(pgm_read_byte(&*data++),1);
}
}
for(unsigned char i=0;i<32;i++)
{
LCD_writeOneByte(0x80+i,0);
LCD_writeOneByte(0x88,0);
for (unsigned char q=0;q<16;q++)
{
LCD_writeOneByte(pgm_read_byte(&*data++),1);
}
}
}
PROGMEM const unsigned char QR[1024]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xE0,0x00,0x00,0x00,
0x00,0x01,0xF7,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0xC0,0x00,0x00,0x00,
0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x00,0x00,0x00,
0x00,0x03,0xBE,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC6,0x00,0x00,0x00,0x00,
0x00,0x03,0x08,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x00,0x00,0x00,0x00,
0x00,0x03,0x80,0xE0,0x00,0x00,0x00,0x01,0x83,0x00,0x1F,0x80,0x00,0x00,0x00,0x00,
0x00,0x03,0x81,0xE0,0x00,0x00,0x00,0x01,0x83,0x00,0x1C,0x60,0x00,0x00,0x00,0x00,
0x00,0x01,0xC3,0x80,0x00,0x1F,0xFE,0x01,0x87,0xF0,0x18,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0xE7,0x01,0x00,0x1F,0xFE,0x01,0x8F,0xF8,0x18,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0xFF,0x0F,0x80,0x0C,0x06,0x01,0xC3,0x18,0x1F,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x1D,0x98,0x0C,0x06,0x07,0xE3,0x1F,0x1F,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x1C,0x3F,0xFC,0x0C,0x06,0x0F,0x8F,0xFF,0x09,0x3A,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3F,0xFC,0x0C,0x06,0x0D,0x9F,0xF8,0x03,0xBF,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x7F,0x80,0x0F,0xF6,0x0D,0x83,0x38,0x03,0xBB,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0xE1,0x80,0x0F,0xF6,0x01,0x83,0x3C,0x03,0xB9,0xC0,0x00,0x00,0x00,
0x00,0x00,0x01,0xE1,0xF8,0x0C,0x06,0x01,0x87,0x1E,0x03,0x79,0x80,0x00,0x00,0x00,
0x00,0x00,0x01,0xDF,0xFC,0x0C,0x06,0x01,0x87,0x0E,0x00,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x1F,0xF8,0x0C,0x06,0x01,0x8E,0x06,0x00,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x80,0x0C,0x06,0x01,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x80,0x0F,0xFE,0x00,0x00,0x00,0x3B,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x80,0x0F,0xFE,0x00,0x00,0x00,0x7F,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0xFE,0x0C,0x00,0x00,0x00,0x00,0x7F,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0xFC,0x00,0xF9,0xE0,0x00,0x00,0x01,0x83,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0xFF,0x83,0xE0,0xE0,0x00,0x00,0x00,0x03,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x07,0x9F,0xE7,0x80,0x70,0x00,0x00,0x3C,0x0F,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x0F,0x03,0xFF,0x00,0x70,0x00,0x00,0x7F,0xBF,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x0E,0x00,0xFC,0x00,0x70,0x00,0x00,0x73,0xFC,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x1E,0x00,0x38,0x00,0x70,0x00,0x00,0x7C,0xF9,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0xE0,0x00,0x00,0x1F,0x7D,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x1C,0x00,0x00,0x01,0xE0,0x00,0x00,0x0F,0xDF,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x1E,0x00,0x00,0x01,0xC0,0x00,0x00,0x07,0xCF,0xE0,0x00,0x00,0x00,
0x00,0x00,0x00,0x0F,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xFB,0xF8,0x00,0x00,0x00,
0x00,0x00,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x00,0x01,0xFC,0x7C,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0xC0,0x00,0x0F,0x00,0x00,0x00,0x07,0xBF,0x3E,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0xF0,0x00,0x1E,0x00,0x00,0x00,0x0F,0xCF,0x0F,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xF8,0x00,0x3C,0x00,0x00,0x00,0x0F,0xF7,0x07,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x7E,0x00,0x38,0x00,0x00,0x00,0x1C,0xFC,0x07,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x1F,0x80,0x78,0x00,0x00,0x00,0x7C,0x7E,0x01,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0xC0,0xF0,0x00,0x00,0x00,0x7F,0x9E,0x01,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0xE1,0xE0,0x00,0x00,0x00,0x7F,0xCE,0x01,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFB,0xC0,0x00,0x00,0x00,0x3B,0xF0,0x01,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x18,0xF8,0x03,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x0E,0x3C,0x03,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x03,0x9C,0x07,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x01,0xC0,0x07,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00};
int main(void)
{
DDRB = 0XFF;
PORTB = 0X00;
DDRC = 0XFF;
PORTC = 0X00;
LCD_Init();
while (1)
{
LCD_Drawing(QR);
}
}
注意事项
注意!本文中的指令集有个别地方有按照我的理解稍加修改过!文末有原版资料
- LCD_writeOneByte(x,y):这个子程序在并行通信方式时y=1是代表写入数据,y=0代表写入指令;在串行通信时按照资料给的控制字写入即可
- 当模块在接受指令前,微处理器必须先确认模块内部处于非忙碌状态,即读取BF 标志时BF需为0,方可接受新的指令;如果在送出一个指令前并不检查BF 标志,那么在前一个指令和这个指令中间必须延迟一段较长的时间,即是等待前一个指令确实执行完成,指令执行的时间请参考指令表中的个别指令说明。
- “RE”为基本指令集与扩充指令集的选择控制位元,当变更“RE”位元后,往后的指令集将维持在最后的状态,除非再次变更“RE”位元,否则使用相同指令集时,不需每次重设“RE”位元。
- 文本显示RAM(DDRAM)
文本显示RAM 提供8 个×4行的汉字空间,当写入文本显示RAM时,可以分别显示CGROM、HCGROM与CGRAM
的字型;KM12864可以显示三种字型,分别是半宽的HCGROM 字型、自定义字符CGRAM字型及中文库CGROM
字型。三种字型的选择,由在DDRAM中写入的编码选择,各种字型详细编码如下:
显示半宽字型:将一位字节写入DDRAM 中,范围为02H-7FH 的编码。
显示CGRAM字型:将两字节编码写入DDRAM中,总共有0000H,0002H,0004H,0006H四种编码
显示中文字型:将两字节编码写入DDRAM ,范围为A1A0H-F7FFH(GB码)或A140H-D75FH(BIG5码)的编码。 - 绘图RAM(GDRAM)
绘图显示RAM 提供128×8个字节的记忆空间,在更改绘图RAM 时,先连续写入水平与垂直的坐标值,再写
入两个字节的数据到绘图RAM,而地址计数器(AC)会自动加一;整个写入绘图RAM的步骤如下:
1、开启绘图显示功能。
2、先将水平坐标(X)写入绘图RAM地址,再将垂直坐标(Y)写入绘图RAM 地址;
总结
通过这次学习让我学会了什么
- 通过这次学习我学会了怎么往Atmega16的flash里存放超过内存的常量和读取我存放进去的数据;
- 通过这次学习,大概了解了SPI通信方式的时序;
- 通过这次学习,进一步熟悉了6800通信;
- 通过这次学习,更加深入的了解了数据类型;
在这次学习中遇到了很多问题
- 比如数据类型中Signed char和char的区别:其区别在于Signed char是一个变量类型,而char是一个字符类型,所以在编译的时候因为这个的区别导致编译器警告"类型不同";这个问题也多亏马先生给我讲解;非常感谢!
- 比如Switch语句中的case,在调试过程中遇到了Switch语句不起作用的情况,看了一下警告,提示case1以定义但未使用,然后发现原来case跟1之间必须要有一个空格,代表这个是分支1的意思.也是这个语句的一个标准吧.主要是还是因为C语言的各种语句不够熟练导致的这个错误.
- 比如在使用4线通信时,启用不了绘图功能,原来是资料上的拓展指令的功能选择缺失了一个DL,所以一直以为是0x36是开启绘图,导致其用不了绘图,到后面叫马先生帮忙查看程序何处有问题,马先生找了一会发现4线的开启绘图要0x26…(写程序也不能完全相信资料,要根据上下文勇敢的去推测寄存器设定的其他可能);感谢马先生!
当然这一篇文章还有程序等等还有很多我未发现的问题,希望看到的网友不惜赐教.感谢!
总结一下这个工程的思路
好啦,12864就讲到这里
资料附上https://download.csdn.net/download/qq_35227168/11830646
明天就是新中国成立70周年的日子.祝祖国母亲70周年生日快乐!
2019/09/30
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)