用户工具

站点工具


侧边栏

抱歉,您没有权限增加页面
4.单片机入门教程:14.点阵液晶屏驱动

单片机入门教程之点阵液晶屏驱动

一:实验原理:
点阵液晶屏有很多种,单片机初学者通常学习的有1206和12864这两款显示屏,但是1206只能显示英文字符,12864能显示中英文但价格昂贵,本开发板上用的是诺基亚5110液晶屏,就是这款大哥大用的显示屏哈,拆机后做成一个模块。

这款显示屏小巧玲珑,傲娇的品牌呆萌的价格,液晶显示范围为84*48,可以显示16*16大小的15个中文字或者8*16大小的30个英文字符,且采用串行接口只需要5根IO口,实属Diy必备之选。

关于点阵液晶的显像原理请自行百度,在这里来看下怎么让液晶显示字符,所谓点阵液晶屏,即屏幕由一个个小点组成,称之为像素。5110液晶的像素为84*48=4032,由4032个点组成,我们将坐标原点定在整个屏幕左上角(0,0),向右为X坐标,向下为Y坐标。屏幕上每一个点的亮与不亮和坐标对应关系是由专用驱动芯片来完成的,同时芯片也控制液晶的对比度和温度补偿等,这颗芯片已经封装在屏幕上了。

屏幕上的点与驱动芯片中的显示缓存RAM区是一一对应的,你想控制哪个点显示与不显示,只要往对应的RAM位中写1或者0就可以了。5110液晶共有84*48=4032个点,所以控制芯片中的RAM共有4032个位,分为6排(范围bank0-5),每排84字节,每字节对应8个点。RAM区域显示点映射图如下:

上图好好看一看啊,一定要明白显示点和RAM的对应关系,知道了对应关系,就可以和坐标对应起来了,比如我想往X的0,Y的1处寻址写0x01,那么Bank1的第1个点就会点亮。
下面再来看看如何寻址,寻址就是往RAM区中写数据的方式,分为垂直寻址和水平寻址两种方式,看看下面的图就会明白:

垂直寻址:就是从Y-address依次从上到下写数据,先写bank0的第1个字节8个点,然后在写bank1的第1个字节8个点,一直到bank5的第1个字节8个点,然后再从bank0的第2个字节写8个点,继续以此循环,写满504个字节,再从0开始。
水平寻址:就是从X-address依次从左到右写数据,先写bank0的第1个字节8个点,再写bank0的第2个字节8个点,然后以此,直到bank0的第84个字节,然后在从bank1第1个字节,继续以此循环,写满504个字节,再从0开始。

还有一些概念,简单说一下。
1.偏置系统:网上的解释是这样的,为防止对比度不均匀,在不点亮象素对应的电极上也加有一定电压,这对降低点亮象素产生的交叉干扰和防止对比度不均匀很重要。LCD中非点亮象素(非选点)的电压有效值与点亮象素(选择点)电压有效值之比称为偏压比。
2.温度系数:由于液晶粘性对于温度的依赖性,LCD控制电压VLCD在较低温度时必须增加,以保证最合适的对比度。
3.对比度:对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小。

概念讲完了,下面就可以来看下液晶所使用的驱动芯片怎么来驱动了,5110液晶使用的驱动芯片为飞利浦生产的PCD8544,与单片机通信接口为串行总线,接口如下:

与单片机连接的原理图如下:

二:代码演示与解释
实验现象:液晶初始化,写指令测试,显示全黑和空白。

先来看下串行接口的时序图,不管是啥芯片,首先都要弄明白通信协议才能写代码。

来,带你走一下时序图,液晶我们只需要写数据和命令而不需要读,所以简单点。先把CE置低电平,使能芯片,D/C有两条线是灰色的,这个是高低电平都有,置低电平是命令模式,置高电平为数据模式。在SCLK时钟线为上升沿时,SDIN线上的数据就写入了。来看下代码更容易理解:

//说明:类似SPI总线,写入液晶一个字节(指令或数据)
//参数:CommandOrData:写指令和数据切换  WByte:要写的数据
void Nokia_5110_Write_Byte(uchar CommandOrData,uchar WByte)
{
  uchar i;
  TFT_CE=0;//使能芯片
  TFT_DC=CommandOrData; //写命令或写数据选择 1:数据 0:命令查看中文手册13页
  
  for(i=0;i<8;i++) //串行数据 每次往数据线上送一位
  {
    if(WByte&0x80) //把要写的数据最高位,每次与0x80相与
    {			   
	  TFT_DIN=1; //如果为1则送1
	} 
	else{TFT_DIN=0;}

	TFT_CLK=0; 
	WByte<<=1; //左移一位 准备送下一位
	TFT_CLK=1; //在时钟为上升沿时写入数据 查看中文手册13页
  }
  TFT_CE=1;	//关闭芯片				
}

有了这个函数,我们就可以给芯片初始化配置功能或者写数据了,步骤如下:

指令分为基本指令和扩展指令,由功能设置寄存器H这一位控制,先要设置你是使用基本的(H=0)还是扩展的指令(H=1),然后才能写数据或指令。看下寄存器表就能明白:

初始化就是配置下偏置系统,对比度,温度系数,显示模式和起始地址,对照上面的寄存器表然后看下面的代码慢慢理解吧:

void Nokia_5110_Init(void) //液晶初始化
{
   TFT_RST=0;
   delay_ms(5);
   TFT_RST=1; //复位
			//见英文手册14页指令和22页编程示例
   Nokia_5110_Write_Byte(0,0x21);//功能设置:水平寻址 扩展指令
   Nokia_5110_Write_Byte(0,0x13);//设置偏置系统(BSx) 1:48 设置为0x10~0x17 
   Nokia_5110_Write_Byte(0,0xc6);//设置对比度Vop,设置为0x80~0xff;
   Nokia_5110_Write_Byte(0,0x07);//设置温度系数	0x04~0x07,越小越黑

   Nokia_5110_Write_Byte(0,0x20);//功能设置:水平寻址 基本指令
   Nokia_5110_Write_Byte(0,0x0c);//设置显示模式:普通模式
   Nokia_5110_Write_Byte(0,0x40);//起始地址Y初始化为0  0<=Y<=5
   Nokia_5110_Write_Byte(0,0x80);//起始地址X初始化为0  0<=X<=83
}

可以看到,首先得给芯片一个复位信号,因为接通电源后,内部寄存器和RAM的内容不确定,必须给一个低电平来复位。然后先使用扩展指令配置芯片让液晶稳定显示,然后再使用基本指令设置显示模式和起始地址。
接下来,就可以看看我们的液晶有没有显示了,可以使用一个指令来测试,在基本指令中有一个显示控制寄存器,可以让液晶显示空白和开所有显示段。代码如下:

//液晶显示控制(不影响DDRAM) 见手册14页 Table2
#define LCD_Show_Blank	 0x08	//显示空白
#define LCD_Show_Normal	 0x0c	//正常显示
#define LCD_Show_Black	 0x09	//显示全黑
#define LCD_Show_Inverse 0x0d	//反色显示

然后在main函数中就可以测试液晶有没有初始化成功了。

Nokia_5110_Write_Byte(0,LCD_Show_Black); //写全黑指令
delay_ms(3000);
Nokia_5110_Write_Byte(0,LCD_Show_Blank); //写空白指令
delay_ms(3000);

OK了,完整工程在stc51 discovery开发板【实验例程】【进阶实验】【实验三十九】

当液晶初始化成功了,就可以写数据了,写数据也属于基本指令,你想在哪显示,就寻址到那个地方往RAM中写就行了。接下来我们把液晶的显示RAM区从起始坐标(0,0)处全部填满,来显示一个48*84大小的图片。

要让液晶显示,就是往显示RAM中写数据对不对?怎么把一张48*84大小的黑白图片转换成数据写进去呢,这要借助一个软件,这个软件叫PCtoLCD2002。来导入一张图片看看,图片必须是BMP格式,且满足以下条件,图片可以用Photoshop做出来:

图中小格子就代表了像素,黑的地方表示不显示那么就代表0,亮的天意表示显示代表1,程序中我们对液晶RAM寻址的方式为水平寻址,所以还需要对软件设置一下才能生成数据,否则会显示乱码,点击软件中的选项,然后设置一下。

点阵格式:阴码,就是亮的为1。取模走向:逆向,就是低位在前。取模方式:列行式,看下右下角的取模演示就明白了,是不是和我们寻址方式一样一样滴?自定义格式要选成C51格式,下面的不要动。确定后,点击生成字模,会生成如下十六进制数据,我们把他们都放在一个数组里,如下:

uchar code pic[] = {   //84X48 图片数组 取模方式:列行式 逆向 阴码

	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,
        ………以下省略
        
然后我们把这些图片数据填充到显示RAM中就可以了,在主函数中写:
Nokia_5110_Write_Byte(0,0x40); //y=0
Nokia_5110_Write_Byte(0,0x80); //x=0 设置屏幕坐标开始区域
for(i=0;i<504;i++)	//一张84*48图片有4032像素 共4032/8=504个字节
{
                       //液晶自动水平寻址 列行式扫描写图片数据
  Nokia_5110_Write_Byte(1,pic[i]);
}

完整工程在stc51 discovery开发板【实验例程】【进阶实验】【实验四十】

如果要显示英文或者中文字符的话,原理和写图片一个样,也是先用软件取出字模。在指定地址处写进字模就可以了。以8*16大小英文字符为例,在PCtoLCD2002上点击模式,改成字符模式,(注意)字模选项设置和图片那里的一样,然后在文本框中输入英文字符,点击生成字模,会生成一串字模数组:

显示英文字符的函数如下,先设定显示地址,如要在Y=0,X=8处写一个字符,即从Y-address(0)的x-address(8)开始写8个字模,再从然后再从Y-address(1)的x-address(8)开始写8个字模,字就出来了。

//8*16大小 ASCII字符显示 
//X_Adress范围:0-83 Y_Adress范围:0-5 每个字X_Adress用8,Y_Adress用2
void Ascii_8X16_Font(uchar X_Adress,uchar Y_Adress,uchar *Font)
{
  uchar x,y;
  X_Adress=X_Adress|0x80;
  Y_Adress=Y_Adress|0x40;  //加上初始地址
  
  for(y=0;y<16;y=y+8)// 8X16 分两次扫描 上下各8
  {
	  Nokia_5110_Write_Byte(0,Y_Adress); //y
      Nokia_5110_Write_Byte(0,X_Adress); //x	  
	  for(x=0;x<8;x++)
	  {
	    Nokia_5110_Write_Byte(1,Font[x+y]);
	  }
	  Y_Adress=Y_Adress+1;
  }

}

显示16*16大小中文字符的话和英文字符同理,直接看代码吧

//16*16大小 中文字符显示
//X_Adress范围:0-83 Y_Adress范围:0-5 每个字X_Adress用16,Y_Adress用2
void Ch_16X16_Font(uchar X_Adress,uchar Y_Adress,uchar *Font)				  
{
  uchar x,y;
  X_Adress=X_Adress|0x80;
  Y_Adress=Y_Adress|0x40;  //加上初始地址
  
  for(y=0;y<32;y=y+16)// 16X16 分两次扫描 上下各16
  {
	  Nokia_5110_Write_Byte(0,Y_Adress); //y
      Nokia_5110_Write_Byte(0,X_Adress); //x	  
	  for(x=0;x<16;x++)
	  {
	    Nokia_5110_Write_Byte(1,Font[x+y]);
	  }
	  Y_Adress=Y_Adress+1;
  }
  
}

完整工程在stc51 discovery开发板【实验例程】【进阶实验】【实验四十一】

液晶如何显示温湿度请参照stc51 discovery开发板【进阶实验】【实验四十二】。

好了,都说完了,关于液晶显示和RAM的对应关系,还有寻址的概念一定要搞清楚,显示字符的代码看了才不会糊涂。

4.单片机入门教程/14.点阵液晶屏驱动.txt · 最后更改: 2017/03/08 12:54 由 wawooo