历史上的今天
今天是:2024年12月04日(星期三)
2019年12月04日 | 轻松玩转LCD12864-基于AVR单片机的LCD12864串行显示
2019-12-04 来源:eefocus
LCD12864是一种常用的图形液晶显示模块,顾名思义,就是可以在水平方向显示128个点,在竖直方向显示64个点。通过对控制芯片写入数据,可以控制点的亮灭,从而显示字符、数字、汉字或者自定义的图形。尽管LCD12864有各个不同厂家生产的产品,控制芯片和引脚定义也不尽相同,但是控制原理都大同小异。本文是对我个人使用LCD12864的经验做一个总结,希望能对入门者起到抛砖引玉的作用。
就以深圳市亚晶达电子有限公司生产的YJD12864C-1为例,我不想深究显示屏的内部结构,单讲讲各个引脚的作用以及数据读写时的时序。

上图是YJD12864C-1的实物图,从右往左,1脚到20脚的定义如下:
1:VSS,接地端
2:VDD,电源正,接+5V
3:VO,对比度调整,一般接+5V就行了
4:D/I(CS*),片选,也叫使能,接+5V
5:R/W(SID*),数据输入端
6:E(SCLK*),时钟输入端
7~14:DB0 ~ DB7,并行数据总线
15:PSB,串并模式选择,串行模式下接地,并行模式下接+5V
16:NC,空引脚,不需要连接
17:RSTB,复位端,低电平有效,一般接+5V就行了
18:VEE,空引脚,不需要连接
19:BLA,背光正极,接+5V
20: BLK,背光负极,接地
在实际编程时,有串行、并行两种模式可以选择。个人觉得,并行模式占用单片机引脚多(11个),优点是速度快(一次传8位数据,速度自然快),串行模式占用引脚少(2个),速度慢点。我喜欢使用串行模式,AVR单片机的时钟频率最快可达20MHZ(不用除以12),经过实测,从头到尾刷一次屏大约只需0.1s,这在很多场合已经够用了。由于并行模式用的少,不熟悉,下面只讲串行模式。
在串行模式下,硬件的连接为:1、15、20接地,2、3、4、17、19接+5V,5接单片机SPI输出(下图第6脚),6接单片机SPI时钟信号输出(下图第8脚)。

ATMEGA324引脚图
下面介绍程序:
1、底层数据通信程序:包括SPI设置,SPI发送单字节,LCD写数据,LCD初始化
//////////////////////////////////////////////////////////////////////////////////////////
#define F_CPU 8//时钟频率8MHZ
#include #include"delay.h" ////////////////////////////////////////////////////////////////////////////////////////// 上面是开头部分,其中delay.h内容如下: #ifndef __IAR_DELAY_H #define __IAR_DELAY_H #include #define delay_us(x) __delay_cycles((unsigned long)(x * F_CPU)) #define delay_ms(x) __delay_cycles((unsigned long)(x * F_CPU*1000UL)) #define delay_s(x) __delay_cycles((unsigned long)(x * F_CPU*1000000UL)) #endif ////////////////////////////////////////////////////////////////////////////////////////// SPI设置: void SPI_MasterInit(void) { DDRB=(1<<7)|(1<<5)|(1<<4);//(1<<5)|(1<<7);//设置MOSI和SCK 为输出 SPCR = (1<<6)|(1<<4);// 1< ////////////////////////////////////////////////////////////////////////////////////////// SPI发送单字节: void SPI_MasterTransmit(char cData) { SPDR = cData; while(!(SPSR & (1<<7)));//1< LCD写数据: void LCD_Write (char RS,char content)//RS=1发数据RS=0发命令 { charStart,High4,Low4; Start=0xf8|(RS<<1); High4=content&0xf0; Low4=(content<<4)&0xf0; SPI_MasterTransmit(Start);//发送开始字节,前面5个1,倒数第二位RS SPI_MasterTransmit(High4);//发送数据高4位 SPI_MasterTransmit(Low4);//发送数据低4位 delay_us(300); } ////////////////////////////////////////////////////////////////////////////////////////// LCD初始化 void LCD_INIT() { LCD_Write(0,0x30); /*30---基本指令动作*/ LCD_Write(0,0x01); /*清屏,地址指针指向00H*/ LCD_Write(0,0x06); /*光标的移动方向*/ LCD_Write(0,0x0c); /*开显示,关游标*/ } ////////////////////////////////////////////////////////////////////////////////////////// 2、应用层程序,包括汉字显示,字符显示,图形显示等等 汉字显示: 分4行,一行可显示8个汉字,每个汉字占16*16个格 void Show_Chinese(char x0,char y0,chark,char *chn) //x0,y0为显示位置x0: 0~3, y0: 0~7, k为汉字个数, chn为汉字数组 { charadr,i; switch(x0) { case0: adr = 0x80 + y0;break; //在第1行y列显示 case1: adr = 0x90 + y0;break; //在第2行y列显示 case 2: adr = 0x88 + y0;break; //在第3行y列显示 case3: adr = 0x98 + y0;break; //在第4行y列显示 default:; } LCD_Write(0,adr); for(i=0;i<2*k;i++) LCD_Write(1,chn); } ////////////////////////////////////////////////////////////////////////////////////////// 显示字符串: 分4行,一行可显示16个汉字,每个汉字占8*16个格 void Show_String(char x0,char y0,chark,char *chn) //x0,y0为显示位置x0: 0~8, y0:0~3, k为字符串个数, chn为字符串 { charadr,i; switch(x0) { case0: adr = 0x80 + y0;break; //在第1行y列显示 case1: adr = 0x90 + y0;break; //在第2行y列显示 case2: adr = 0x88 + y0;break; //在第3行y列显示 case3: adr = 0x98 + y0;break; //在第4行y列显示 default:; } LCD_Write(0,0x30); LCD_Write(0,adr); for(i=0;i } ////////////////////////////////////////////////////////////////////////////////////////// 显示数字: void Show_Number(char x0,char y0,charnum)//显示两位数字 //x0,y0为显示位置x0: 0~8, y0:0~3,显示数字位数可调 { charadr; switch(x0) { case0: adr = 0x80 + y0;break; //在第1行y列显示 case1: adr = 0x90 + y0;break; //在第2行y列显示 case2: adr = 0x88 + y0;break; //在第3行y列显示 case3: adr = 0x98 + y0;break; //在第4行y列显示 default:; } LCD_Write(0,0x30); LCD_Write(0,adr); //LCD_Write(1,num/100%10+'0'); //上句不注释则显示3位数字,要显示更多位可以此类推,不过要注意num的字长 LCD_Write (1,num/10%10+'0'); LCD_Write(1,num%10+'0'); } ////////////////////////////////////////////////////////////////////////////////////////// 显示图片: char lcd_x,lcd_y; void Show_Image(char *p) //水平扫描 //P含128*64/8=1024字节 //可用字模软件获得任意图片的水平扫描码 { chari,j,k; lcd_x=0x9f; lcd_y=0x80; LCD_Write(0,0x34); for(i=0;i<2;i++)//分为上下两屏 { for(j=0;j<32;j++) { LCD_Write(0,lcd_y+j); LCD_Write (0,lcd_x); for(k=0;k<16;k++)//写入显示数据 { LCD_Write (1,*p++); } } lcd_x=0x87; } LCD_Write(0,0x36); LCD_Write(0,0x30); } 图片模式下清屏: void Clear_Gcrom() { chari,j,k; lcd_x=0x80; lcd_y=0x80; LCD_Write (0,0x34); for(i=0;i<2;i++) { for(j=0;j<32;j++) { LCD_Write(0,lcd_y+j); LCD_Write (0,lcd_x); for(k=0;k<16;k++){ LCD_Write (1,0x00); } } lcd_x=0x88; } LCD_Write(0,0x36); LCD_Write(0,0x30); } 显示两字节,LCD12864每次至少刷新16格: void Show_2Byte(char x,char y,chardat1,char dat2)// x:0~7 y:0~63 { if(y<32)//下屏 { x+=8; y=31-y; } else//上屏 { y=63-y; } LCD_Write (0,0x34); LCD_Write (0,0x80+y);//y:0~31 LCD_Write (0,0x80+x);//x:0~15 LCD_Write (1,dat1); LCD_Write (1,dat2); LCD_Write (0,0x36); LCD_Write (0,0x30); } 刷新1行: void Show_Hang(char y,char p[64][16]) //显示一行 y:0~63 { chark,y0=y; lcd_y=0x80; LCD_Write(0,0x34); if(y<32) {
史海拾趣
|
AD6.9安装程序 AD6.9 Crack.rar AD6.9中文菜单修正文件.rar Altium.Designer.v6.9.12759.rar 免License操作说明.txt Altium Designer官方网站资料 Altium 宣传信息 Altium\'s DEMOcenter Vidios Altium官方资料 Training Manuals IPC_Ove ...… 查看全部问答> |
|
哪位大大有 Buck ZVT PWM的MATLAB的模型图啊 急需Buck ZVT PWM的MATLAB的模型图啊 对MATLAB不是很懂 现在要用这个做仿真,没办法只能在这求助了 希望那位会的大大帮帮忙啊:(… 查看全部问答> |
|
早上7点,你被收音机闹钟播放的精典摇滚音乐闹醒。老天,这是什么歌?配备RDS标准的收音机屏幕上滚动显示出“Wanted Dead or Alive - John Bon Jovi”数字文本。在你吃早餐时,可以通过WLAN收发器从在家里查看电子邮件。准备出发上班时,你进入车库 ...… 查看全部问答> |
|
第四步是选择变压器和无源元件,使其与负载阻抗匹配。变压器和R、L的元件值都必须与负载相匹配,并构建一个能使ADC和次级变压器之间的总体性能达到期望值的新的AAF(图2)。 图2:在这个ADC前端原理框图中,电阻和电感的值必须与负载相匹配。 经 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 09:22 编辑 3.5V电源、工作稳定的低电压、低功耗基准电压发生电路电路的功能 三端式电路可广泛用于需要恒流置偏的场合,可则外接电阻RSET在1UA~10MA范围内随意设定输出电流。 I+=10UA时,要保证恒流,必须的 ...… 查看全部问答> |
|
WinCE 6.0模擬器下使用gethostbyname()的問題。 我在Windows下使用如下代碼, gethostbyname()函數返回正常。 但在WinCE 6.0模擬器下卻錯誤,錯誤代碼為11001。 但是在WinCE 6.0模擬器上可以登陸\"www.baidu.com\"。 是我的模擬器設置問題還是什麽問題? 請各位幫忙看下問題所在,或者幫忙驗證 ...… 查看全部问答> |
|
各位大侠好!小弟最近做了一个实验,就是想把2440 的UART0 就是硬件上的TXD0 RXD0作为普通串口用。这个串口本来是做debug串口调试用的。而且系统运行很正常。但是我今天把注册表关于UART1也就是系统层的这个debug串口的注册表信息打开(作为Debug时 ...… 查看全部问答> |
|
如果我想学嵌入式,应该从哪些方面着手啊?再有一年半就要找工作啦。。。 我现在学的东西有:操作系统,微机原理,单片机,数据库概论,图形学,算法设计与分析,软件工程,学过c和c++,数据结构,计算机组成原理,数字逻辑,学的东西太多很头疼,想往某个方面着重发展一下,但不知道应该重点学学哪些课程,请高手指点迷津 ...… 查看全部问答> |




