历史上的今天
返回首页

历史上的今天

今天是: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<SPSR = 1<<0;// 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         LCD_Write(1,chn);

}

//////////////////////////////////////////////////////////////////////////////////////////

显示数字:

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)

       {

推荐阅读

史海拾趣

APX Technologies公司的发展小趣事

随着电子行业的快速发展,技术更新换代的速度越来越快。APX Technologies面临着来自同行的激烈竞争和不断变化的市场需求。为了应对这些挑战,公司不断调整战略方向,加大研发投入,优化产品结构。在稳中求进的过程中,APX Technologies逐渐巩固了自己的市场地位。

艾迪沃德公司的发展小趣事
在仪器正常工作时,观察电源电压是否稳定,以及是否有异常波动或下降现象。
Bias Power公司的发展小趣事

Bias Power公司深知研发实力是企业发展的核心。因此,公司投入大量资源用于研发工作,建立了完善的研发团队和实验设施。通过不断的技术创新和研发投入,Bias Power公司成功推出了一系列具有竞争力的新产品,巩固了其在电子行业的领先地位。

同时,公司还注重知识产权的保护,积极申请专利,保护其核心技术不被侵犯。这些专利的申请和授权不仅提升了公司的技术实力,还为公司的发展提供了有力保障。

Ericsson Power Modules公司的发展小趣事

随着产品质量的不断提升和技术的不断创新,Ericsson Power Modules开始积极拓展市场。公司不仅在欧洲市场取得了显著成绩,还逐步将业务拓展至亚洲、北美等地区。为了更好地服务全球客户,Ericsson Power Modules在瑞典斯德哥尔摩设立了总部,并在中国、美国等地建立了生产基地和研发中心。这种全球化布局使得Ericsson Power Modules能够更快速地响应市场需求,提供更高效、更便捷的服务。

微芯(CMOSIC)公司的发展小趣事

随着产品线的逐渐丰富和技术的不断进步,微芯生物开始积极拓展市场。他们与多家国内外医药企业建立了合作关系,将自主研发的药物推向市场。同时,公司也积极参与各类学术会议和展览,提升品牌知名度和市场影响力。通过不懈的努力,微芯生物逐渐获得了市场的认可和信赖。

General Industrial Controls ( GIC )公司的发展小趣事
电感量的大小会影响电路的响应速度和稳定性。一般来说,电感量越大,电路的响应速度越慢但稳定性越好;电感量越小则相反。因此需要根据具体需求选择合适的电感量。

问答坊 | AI 解惑

天祥 Altium Designer 视频教程 5dvd

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 ...…

查看全部问答>

具有自动存储功能的语音选台电视遥控系统设计

要求: 在15000字左右的 论文  并附有电路图和原理!!!!!有奖金哦   奖金50元!!!急待解决~!!!!…

查看全部问答>

哪位大大有 Buck ZVT PWM的MATLAB的模型图啊

急需Buck  ZVT PWM的MATLAB的模型图啊 对MATLAB不是很懂 现在要用这个做仿真,没办法只能在这求助了 希望那位会的大大帮帮忙啊:(…

查看全部问答>

决定无线测试系统未来的三个趋势

早上7点,你被收音机闹钟播放的精典摇滚音乐闹醒。老天,这是什么歌?配备RDS标准的收音机屏幕上滚动显示出“Wanted Dead or Alive - John Bon Jovi”数字文本。在你吃早餐时,可以通过WLAN收发器从在家里查看电子邮件。准备出发上班时,你进入车库 ...…

查看全部问答>

ADC前端设计步骤之四

第四步是选择变压器和无源元件,使其与负载阻抗匹配。变压器和R、L的元件值都必须与负载相匹配,并构建一个能使ADC和次级变压器之间的总体性能达到期望值的新的AAF(图2)。 图2:在这个ADC前端原理框图中,电阻和电感的值必须与负载相匹配。 经 ...…

查看全部问答>

3.5V电源、工作稳定的低电压、低功耗基准电压发生电路

本帖最后由 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\"。 是我的模擬器設置問題還是什麽問題? 請各位幫忙看下問題所在,或者幫忙驗證 ...…

查看全部问答>

关于2440DEBUG串口关闭引起的问题?

各位大侠好!小弟最近做了一个实验,就是想把2440 的UART0 就是硬件上的TXD0 RXD0作为普通串口用。这个串口本来是做debug串口调试用的。而且系统运行很正常。但是我今天把注册表关于UART1也就是系统层的这个debug串口的注册表信息打开(作为Debug时 ...…

查看全部问答>

如果我想学嵌入式,应该从哪些方面着手啊?再有一年半就要找工作啦。。。

我现在学的东西有:操作系统,微机原理,单片机,数据库概论,图形学,算法设计与分析,软件工程,学过c和c++,数据结构,计算机组成原理,数字逻辑,学的东西太多很头疼,想往某个方面着重发展一下,但不知道应该重点学学哪些课程,请高手指点迷津 ...…

查看全部问答>