查看: 3994|回复: 1

[求助] 【玩转ChipKIT Uno32】第三节LCD5110 的驱动

[复制链接]

该用户从未签到

发表于 2012-8-8 13:04:14 | 显示全部楼层 |阅读模式
分享到:
原帖由
nongxiaoming
发自:dev.eefocus.com
------------------------------------------------------------------------------------------------------------------------------------------

                             LCD5110的驱动

     上一节我们讲了ChipKIT Uno32的串口的使用,这节我们来讲一下LCD5110点阵屏的驱动。在前面两节当中,我们的代码量都比较少,使用的也都是板子库里面的函数,所以都写到了一起。也许很多新手会有这样的疑惑,以前我们写的工程都是好多的.c.h文件,模块化编程,但这个Mpide建立的工程似乎都不是.c.h文件的,能支持模块化编程吗?
      笔者刚刚接触这个也是有这样的的疑惑。答案是肯定的。而且Mpide不仅仅是支持多个.c.h哦,更让人惊讶的是Mpide是支持使用C++编写程序的,呵呵,这个对于经常使用C++的人来说,绝对是一阵狂喜。
      好了,不多说了,下面笔者就带大家一起使用C++把我们的LCD5110液晶点阵屏用类封装好驱动起来。
     LCD5110液晶点阵屏是早期诺基亚手机上使用的点阵屏,这款屏幕分辨率为84x48,最多可以显示412x12的汉字。这屏的优势在于价格便宜,笔者用的是9.9元淘宝上买的,显示面积比1602大,价格相当。
     LCD5110液晶使用的是PCD8544作为控制器,使用SPI协议进行数据传输,这个可以减少很多的连线,使用非常方便。   
    LCD5110点阵液晶屏的接口如下:   
  1. RST ——复位
  2. CE  —— 片选
  3. DC  —— 数据/指令选择
  4. DIN —— 串行数据线
  5. CLK —— 串行时钟线
  6. VCC —— 电源输入(3.3v和5v均可,经过实验验证,没有问题)
  7. BL  ——  背光控制端
  8. GND —— 地线
下面为笔者的ChipKIT板子管脚与LCD管脚的连接:
  1. RST ——板子上的10引脚
  2. CE  —— 板子上的9引脚
  3. DC  —— 板子上的8引脚
  4. DIN —— 板子上的7引脚
  5. CLK —— 板子上的6引脚
  6. VCC —— 5V0
  7. BL  ——  板子上的5引脚
  8. GND —— GND
   下面是LCD5110的数据传输时序图:

1.jpg
     从图上可以看出,片选信号CE为低时数据传输的数据才有效,DC用于表示是写指令还是写数据,写指令时DC为低电平,写数据为高电平。数据传输高位在前低位在后,数据格式为8bit
具体液晶屏的寄存器配置这里就不多说了,可以参照PCD8544的数据手册,有详细说明。

下面我们开始进行实验,首先新建工程保存为“LCD5110Test”。
点击右上角的 1111.jpg 按钮选择“New Tab”新建一个标签页,如下图。

2.jpg

在下方的提示框中输入新建标签的文件名,我们这里命名为“lcd5110.cpp”并点击OK完成创建,因为我们要使用C++所以是以cpp为后缀的,如下图:
3.jpg
按次步骤依次创建“lcd5110.h”作为“lcd5110.cpp”的头文件,建立“font_ascii.h”用于存放我们的ASCII码字符取膜编码,建立“img.h”用于存放图片取膜编码。
到此我们的工程建立完成,下面开始代码的编写。
切换到“lcd5110.h”标签编写lcd5110的头文件代码,写入如下代码:
#ifndef __LCD5110_H                //防重复包含
#define __LCD5110_H
#include "WProgram.h"               //包含我们的板子硬件头文件

//指令宏定义
#define X_Col_Addr     0x80 //定位到第0列指令(列起始地址)(0 - 83)
#define Y_Page_Addr    0x40 //定位到第0页指令(页起始地址)(0 - 5)
class lcd5110
{
public:
lcd5110(int rstPin,int csPin,int dcPin,int dinPin,int clkPin,int blPin);    //构造方法
void Init(void);                                              //初始化函数
void Clear(void);                                             //清屏函数
void setBackLight(unsigned char state);                           //设置背光函数,0开启,1为关闭
void WriteCmd(unsigned char cmd);                             //写指令
void WriteData(unsigned char dat);                              //写数据
void HardWareREST(void);                                    //硬件复位
void SoftWareREST(void);                                     //软件复位
void setXY(unsigned char x, unsigned char y);                      //设置XY坐标
void ClearLow(unsigned char num);                              //清除一行
void DrawChar6_8(unsigned char x, unsigned char y, char c_dat);      //输出6x8ASCII
void printStr6_8(unsigned char x, unsigned char y, const char *s_dat);   //输出6x8字符串
void printlnStr6_8(unsigned char x, unsigned char y,const char *s_dat);  //输出字符串可自动换行
void DrawImage(const unsigned char *img_dat);                    //画个全屏图片
void DrawImage(unsigned char col, unsigned char pag, unsigned char x, unsigned char y,const unsigned char *img_dat);                                            //画指定大小的图片
private:
int RST,CS,DC,DIN,CLK,BL;
};
#endif
这里主要声明我们的LCD5110类,类里面定义了RST,CS,DC,DIN,CLK,BL六个私有变量分别表示LCD5110的相应的管脚与ChipKIT板子的连接。同时,这个类提供了一个构造方法,需要传入液晶屏的相应管脚连接的ChipKIT的管脚号。
Lcd5110.cpp的代码比较多,这里就挑几个讲就行了。

lcd5110::lcd5110(int rstPin,int csPin,int dcPin,int dinPin,int clkPin,int blPin)
{
  RST=rstPin;
  CS=csPin;
  DC=dcPin;
  DIN=dinPin;
  CLK=clkPin;
  BL=blPin;
}
这个是构造方法,学过C++的肯定知道的。
void lcd5110::WriteCmd(unsigned char cmd)
{
   digitalWrite(CS,LOW);
   digitalWrite(DC,LOW);
   shiftOut(DIN,CLK,MSBFIRST,cmd);
   digitalWrite(CS,HIGH);
}
void lcd5110::WriteData(unsigned char dat)
{
  digitalWrite(CS,LOW);
   digitalWrite(DC,HIGH);
   shiftOut(DIN,CLK,MSBFIRST,dat);
   digitalWrite(CS,HIGH);
}
这两个分别是写指令和写数据函数,用到了shiftOut(dataPin, clockPin, bitOrder, value)   
这个是SPI外部IO扩展函数,通常使用带SPI接口的74HC5958IO扩展,把资料传给用来延伸数位输出的暂存器,此函式通常使用在延伸数位的输出。函式使用一个脚位表示资料、一个脚位表示时脉。dataPin为数据口,clockPin为时钟口,bitOrder用来表示位元间移动的方式,为数据传输方向(MSBFIRST高位在前,LSBFIRST低位在前),value会以byte形式输出,表示所要传送的数据(0255)。
接下来我们将如何使用,在我们的主程序页面中输入以下代码进行测试:
#include "lcd5110.h"
#include "img.h"
lcd5110 mylcd(10,9,8,7,6,5);   //构造我们的LCD5110,相应管脚写上
void setup()
{
mylcd.Init();   //初始化
}
void loop()
{
mylcd.printlnStr6_8(1,0,"LCD5110 TEST");      //输出字符
delay(200);
mylcd.printlnStr6_8(0,1,"This is a demo test for the Nokia LCD5110!");  //输出字符
delay(200);
mylcd.printlnStr6_8(0,4,"I love ChipKIT Uno32!");   //输出字符
delay(5000);
mylcd.Clear();    //清屏
  delay(1000);
mylcd.DrawImage(0, 0, 72, 14, pic1);   //显示72x14的图片
delay(1000);
mylcd.DrawImage(0, 2, 72, 28, pic2);        //显示72x28的图片
delay(3000);
mylcd.DrawImage(pic);                   //显示全屏图片
delay(5000);
}
不知道大家注意到没有,DrawImage()函数竟然有两个不同的也不报错,呵呵,这个就是C++的方法重载的好处了,而且可以多个LCD5110构造哦~C方便多了~
好了,激动人心的时刻到了,编译上传到板子上就可以看到效果了,以下是实验的效果:
4.jpg


5.jpg


6.jpg

LCD5110Test.rar (5.46 KB, 下载次数: 31)
ͼƬ4.png
回复

使用道具 举报

  • TA的每日心情
    奋斗
    2018-8-29 20:40
  • 签到天数: 1341 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2014-1-7 23:12:33 | 显示全部楼层
    多谢 学习啦!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-20 04:19 , Processed in 0.133016 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.