LCD12864驱动(Proteus中用51单片机驱动AMPIRE128X64)

致谢:先贴张图来感谢一下我那傻逼的王志学长,要不是你给我的资料跟我用的LCD型号不一样,我TM早就驱动起来了。

填坑:1、TMD Proteus的AMPIRE128X64这个型号的LCD内部没有所谓的ASCII码解码器,所以在驱动的时候就不能直接使用之前惯性使用的ASCII,不然你会在坑里待得很久很久,直到吐血。因此老老实实的,别想什么乱七八糟的,老实点到网上下载一个字符取模器。

2、估计是该厂家知道自己的东西傻逼,所以开发资料也是少得可怜,所以也不要期待能在网上找到多少有关该模块的资料了,即使有,估计也就是像我看过的一样,大多都是不全的。这里推荐一个写得不错的文档,有兴趣的可以照着这个文档自己开发驱动程序。https://wenku.baidu.com/view/7cd053e2ec630b1c59eef8c75fbfc77da369975a.html

好了,抱怨也抱怨完了,该做的事情也不能因为它难就放弃,更不能因为抱怨而放弃。

首先登场的是我们今天的主角——AMPIRE128X64

你看他绿色的外衣下藏着蓝哇哇的皮肤,但是那不是重点,重点是TMD他足足有18个脚,晚上洗脚咋办。接下来我们一个个来认识一下它的这18只脚都有啥作用。

CS1:左半屏选择引脚,低电平有效。该引脚有效时左半屏幕操作有效。(现在可能有点绕口,此处有坑,待会再填)

CS2:右半屏选择引脚,低电平有效。该引脚有效时右半屏幕操作有效。(现在还是有点绕口)

GND:电源地

VCC:电源正

V0:LCD的驱动电压,其实可以用它来调节LCD蓝哇哇的皮肤的深浅。

RS:命令/数据控制引脚。该脚为高电平是DB数据线上传输的是数据,该脚为低电平是DB数据线上传输的是命令。

R/W:读/写控制引脚。该脚为高电平时从LCD模块中毒数据,该脚为低电平时写数据到LCD模块中。

E:LCD读写使能引脚(此处有TMD螺旋坑,坑里还有各种大头钉,钉的尖头还朝上,一般来说,E表示模块使能引脚,但是注意这里他喵的表示的是读写使能引脚,千万不要他喵的初始化的时候给一个高电平就觉得万事大吉了,相反我在这里建议你最好初始化的时候给个低电平,不要问我为什么,我曾在这个坑里待了良久。高电平准备数据,低电平发送数据。)

DB:数据总线。这就是沟通的桥梁啊。

RST:复位脚,一般来说没啥卵用,用的时候直接拉高就行了,当然不排除你做程序比较严谨。

-Vout:LCD的驱动电源。

MD,长这么多脚累不累啊,以为长得脚多就了不起啊,一样制服你。在前面知道各个引脚的功能的前提下,可以给LCD设计如下图所示的建议驱动电路。

其中标有网络标号的统统接到单片机上。

/************************************************************************************************************************************************//************************************************************************************************************************************************/

介绍完硬件电路,接下来就可以给他设计软件驱动程序了,当时我用的是51单片机做的。

总而言之,该模块的引脚驱动电路还是比较容易,其实软件驱动也很容易,只是没有一份合适的开发文档就显得特别想骂娘。

其实要驱动该模块,软件只需要简简单单的几步就行。

step1:选择需要显示的屏幕。(PS填坑来了)                                                                                                                                              通过CS1,CS2组合来选择驱动的是左半边屏幕还是右半边屏幕,还是两边的屏幕一起驱动,还是说两边的屏幕都不驱动显示。具体组合如下。

CS1 CS2 驱动屏幕状态
0 0 两边屏幕同时驱动
0 1 仅仅驱动左半屏幕
1 0 仅仅驱动右半屏幕
1 1

   两边屏幕都不驱动

      这有啥坑?就按照这个来做就行了呗。

      注意描述,所谓的驱动并不是讲的显示,并不是说CS1==0 CD2 == 1就只显示左边屏幕而不显示右边屏幕。而是描述的是接下来的操作只与左边屏幕有关,与右边屏幕半毛钱关系都没有。就像是有两个士兵站在你面前,你跟他们说去把你的意大利大炮拉过来,要是你没有指明是哪一个,那么谁也不敢动,要是你两个都指明了,那么可能最后你收到的会有两台意大利大炮。所以说,当你在操作屏幕显示的时候必须先指明要修改哪一边屏幕的内容。可能你会问为啥不把两边的屏幕放到一块驱动,为什么要搞的那么复杂,这他妈的我哪知道他妈的那个**公司为啥要那么搞。不过我们可以猜测,但是这不是我写这篇文档的目的,现在我们只需要知道要想让屏幕显示,就得先告诉他左右那边屏幕显示。

step2:设置显示的行。(坑!神坑!!神他妈让我选择显示的行。)

          整个屏幕从上到下共有64行,我他妈的一开始以为我可以选择从任意一行还是显示,我他妈连驱动程序都做好了,最后综合调试的时候发现并不是那么回事,注意,真正让我们选择的只有8行,only8行,也就是手册上和我们接下来所讲的页,记住8页!8页!8页!8ye!8ye!,1也有8行,一行就是一行1*64个像素点(注意我没说1*128),也就是说所谓的设置显示的行只是选择显示的在哪一页(我也不知道为什么要命名这么奇葩的名字。);

         搞清楚了设置显示的行(呸,页)的问题,那么所谓的64行是什么玩意,那又是怎么回事呢。其实还有条指令是设置开始显示的首行位置,也就是说,你可以通过设置开始行来选择第一行的位置,如果你设置第开始行是0行,那么第1页就是0-7行,第二页就是8-15行,如果你设置的开始行数是第1行,那么第一页就是1-8行,第二页就是9-16行......。其可以表示为设置的首行为x(x<64)行,那么第y页的起始行数是 (y*8+x)%64,结束行数是(y*8+x+7)%64;所以别奢望在这里实现从任意行还是显示。

step3:设置显示的开始列

         整个屏幕共有64*128个像素点,也就是说共有64行和128列,那么亲,你从0-128行随意设置吧,那你就在坑里舒舒服服的呆着吧。

         前面说过,该LCD分为左右两块屏幕,两块屏幕需要通过CS1与CS2组合来进行控制。这两块屏幕各占64列,也就是说一块屏幕的像素点是64*64,所以我们在设置显示起始列的时候实际上能选择的只有0-63列这个范围。

        还有就是这里讲的起始列真的是可以选择显示起始列哦,不会像前面讲的显示起始行会改变整个屏幕的每一页行的范围一样,这个起始列你设置的在哪一列开始显示,他就在那一列开始显示,并且每显示完一列就自动加1。

step4:设置显示的数据(图像)

       该LCD显示的方式是一列一列开始显示,每显示完一列,记录列数的地址自动加1,也就是说如果你送人的数据是0x88,那么他就会显示当前页的当前列的8个相熟点,由上往下为10001000,了解这个对取模至关重要。

/************************************************************************************************************************************************//************************************************************************************************************************************************/

可能看到这里还是一脸懵逼,还是不知道该怎么办,我是知道了驱动方式,但是驱动的命令指令和时序我都不知道,我还搞个屁啊。别急接下来就给你总结了一些常用指令,足以用来完成正常显示。

#define LCD_CLEAR                   0X01  //lcd清屏
#define LCD_SHOW_MODE(x)   (0x02+x) //选择显示模式 0允许输入IRAM地址 1允许输入垂直卷动地址
#define LCD_SHOW_OFF           0X3E  //lcd显示关
#define LCD_SHOW_ON            0X3F  //lcd显示开
#define LCD_PAGE(x)                (0xb8+x) //设置页数
#define LCD_HANG(x)               (0xc0+x) //设置起始行
#define LCD_LEI(x)                    (0x40+x) //设置起始列

这个是我从自己的驱动程序上copy下来的。有了这些指令就足以完成对LCD的驱动显示了。

其实写一条数据到LCD中特别简单。

(1)查忙。

(2)RS = H/L(H:显示数据 L:操作指令)

(3)RW = L(写数据)

(4)E = H (使能读写数据)

(5)送入数据到DB口

(6)E = L (送入数据)

其具体程序如下所示:

void lcd12864_WriteCommed (unsigned char commed) //12864写命令
{
        lcd12864_Busy (); //12864查忙
        lcdRsPin(PIN_LOW);
        lcdRwPin(PIN_LOW);
        lcdEnPin(PIN_HIGH);
        LCD_DATA = commed;
        lcd12864_delay (5); //延时函数
        LCD_EN = 0;
}
void lcd12864_WriteData   (unsigned char dat)    //12864写数据
{
        lcd12864_Busy (); //12864查忙
        lcdRsPin(PIN_HIGH);
        lcdRwPin(PIN_LOW);
        lcdEnPin(PIN_HIGH);
        LCD_DATA = dat;
        lcd12864_delay (5); //延时函数
        lcdEnPin(PIN_LOW) ; 
}
void lcd12864_Busy (void) //12864查忙
{
        
        LCD_DATA = 0XFF;
        lcdRsPin(PIN_LOW);
        lcdRwPin(PIN_HIGH);
        lcdEnPin(PIN_HIGH);
        while(LCD_DATA&0x80);
        lcdEnPin(PIN_LOW) ; 
}
有了这三个函数还有啥担心的。

本文档也是个人意见,主要用于个人在做项目中的心得体会记录,如有不当言辞,万望海涵,如有错误,万望批评指正(虽然我不一定会听。)

发布了4 篇原创文章 · 获赞 0 · 访问量 397

猜你喜欢

转载自blog.csdn.net/qq_33784286/article/details/103067878