[原创] TFT液晶(ssd1289驱动)快速上手『基于msp430单片机的程序讲解』

hjl240   2014-2-16 18:19 楼主
首先讲个题外话,论坛上有很多分享代码的,不过,我觉得,唯一不好的一点就是:只上传代码,却没有具体讲解一下代码。要是代码里有详细的注释,那样的话,不具体讲解代码也没什么关系;但是有一些代码连注释都没有或者注释很少,让人看得很费力,那就有点不太好了。上传代码共享是一件好事,要是有一个好的注释那就更好了!!
好了,不扯了,现在聊聊ssd1289液晶。
这几天用了一下ssd1289液晶,调好了程序,在此分享一下。该液晶使用msp430f149/169单片机控制的。
先看看效果图:
a1.png
下面说一下代码关键的一些地方: /*******************************************

函数名称:Address_set

功 能:给ssd1289液晶的坐标位置 参 数:16位数据 返回值 :无 ********************************************/ void Address_set(uint x1,uint y1,uint x2,uint y2) { Lcd_Write_Com_Data(0x0044,(x2<<8)+x1);//水平方向RAM地址位置 Lcd_Write_Com_Data(0x0045,y1);//垂直方向RAM起始地址 Lcd_Write_Com_Data(0x0046,y2);//垂直方向RAM终止地址

Lcd_Write_Com_Data(0x004e,x1);//SetGDDRAM X address counter

Lcd_Write_Com_Data(0x004f,y1);//SetGDDRAM Y address counter

Lcd_Write_Com(0x0022); //RAM data write

} 注:也就是显示汉字或者图片的区域,由于液晶的分辨率是240×320,故若是采用竖屏模式,x1x2范围为0-239y1y2范围为0-319 /*******************************************

函数名称:LCD_PutChar8x16

功 能:显示8×16大小的字符串 参 数: x:x轴起始位置 y:y轴起始位置 c:要显示的字符 fColor:字体颜色 bColor:背景颜色 返回值 :无 ********************************************/

void LCD_PutChar8x16(unsigned short x, unsigned short y, char c,uint fColor, uint bColor)

{ uint i,j;

Address_set(x,y,x+8-1,y+16-1);

for(i=0;i<16;i++) { uchar m=Font8x16[c*16+i]; for(j=0;j<8;j++) { if((m&0x80)==0x80)

Lcd_Write_DATA(fColor);

else

Lcd_Write_DATA(bColor);

m<<=1; } } } 注:颜色的设定(fColorbColor的值)可以采用如下: /* LCD color */ #define White 0xFFFF #define Black 0x0000 #define Blue 0x001F #define Blue2 0x051F #define Red 0xF800 #define Magenta 0xF81F #define Green 0x07E0 #define Cyan 0x7FFF #define Yellow 0xFFE0 也可以自己随意用其他16位的颜色参数。
/*******************************************
函数名称:PutGB1616
功 能:显示16×16大小的汉字
参 数: x:x轴起始位置
y:y轴起始位置
c[2]:要显示的字符 ,由于一个汉字占两个字节,故数组位数为2位
fColor:字体颜色
bColor:背景颜色
返回值 :无
********************************************/
void PutGB1616(ushort x, ushort y, uchar c[2], uint fColor,uint bColor)
{
uint i,j,k;
Address_set(x,y,x+16-1,y+16-1);
for(k=0;k<64;k++) //64标示自建汉字库中的个数,循环查询内码
{
if((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1]))
{
for(i=0;i<32;i++)
{
ushortm=codeGB_16[k].Msk;
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
Lcd_Write_DATA(fColor);
else
Lcd_Write_DATA(bColor);
m<<=1;
}
}
}
}
}
注:显示的汉字需要用字模软件生成,用到什么汉字生成什么汉字,字模软件见附件。
/*******************************************
函数名称:PutGB3232
功 能:显示32×32大小的汉字
参 数: x:x轴起始位置
y:y轴起始位置
c[2]:要显示的字符 ,由于一个汉字占两个字节,故数组位数为2位
fColor:字体颜色
bColor:背景颜色
返回值 :无
********************************************/
void PutGB3232(ushort x, ushort y, uchar c[2], uint fColor,uint bColor){
unsigned int i,j,k;
Address_set(x,y,x+32-1,y+32-1);
for (k=0;k<15;k++)
{ //15标示自建汉字库中的个数,循环查询内码
if((codeGB_32[k].Index[0]==c[0])&&(codeGB_32[k].Index[1]==c[1]))
{
for(i=0;i<128;i++)
{
unsigned shortm=codeGB_32[k].Msk;
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
Lcd_Write_DATA(fColor);
else
Lcd_Write_DATA(bColor);
m<<=1;
}
}
}
}
}
注:与上一个函数区别是:此处文字大小是32×32的。显示的文字依旧用字模软件生成。
/*******************************************
函数名称: LCD_PutString
功 能:显示字符串
参 数: x:x轴起始位置
y:y轴起始位置
*s:要显示的字符串
fColor:字体颜色
bColor:背景颜色
返回值 :无
********************************************/
void LCD_PutString(ushort x, ushort y,uchar *s, uint fColor, uint bColor) {
unsigned char l=0;
while(*s)
{
if( *s < 0x80) //汉字内码索引,当s小于128为ASCII码,大于128时为汉字,
{
LCD_PutChar(x+l*8,y,*s,fColor,bColor);//显示8X16大小的字符
s++;l++;
}
else
{
PutGB1616(x+l*8,y,(unsigned char*)s,fColor,bColor);//显示16X16大小的汉字
s+=2;l+=2;
}
}
}
/*******************************************
函数名称: LCD_Picture
功 能:显示一幅80X240的图片
参 数: picture1:待显示的图片
返回值 :无
********************************************/
void LCD_Picture(const uchar *picture1)//此处一定要加 const
{
uchar i,j,pixH,pixL;
for(i=0;i<80;i++)
for(j=0;j<240;j++)
{
pixH=*picture1++;
pixL=*picture1++;
Lcd_Write_DATA2(pixH,pixL);
}
}
注:绘图函数。如果要显示320×240大小的图片,只需要把i<80改为i<320.
/*******************************************
函数名称:void ssd_Initializtion(void)
功 能:液晶的初始化
参 数:无
返回值 :无
********************************************/
void ssd_Initializtion(void)
{
LCD_DataOut_H; //数据端口设置成输出模式
LCD_DataOut_L;
LCD_CMDOut; //控制端口设置成输出模式
LCD_REST_H;
delay_ms(5);
LCD_REST_L;
delay_ms(10);
LCD_REST_H;
LCD_CS_H;
LCD_RD_H;
LCD_WR_H;
delay_ms(20);
Lcd_Write_Com_Data(0x0000,0x0001);
Lcd_Write_Com_Data(0x0000,0x0001); //打开晶振
Lcd_Write_Com_Data(0x0003,0xA8A4); //0xA8A4
Lcd_Write_Com_Data(0x000C,0x0000);
Lcd_Write_Com_Data(0x000D,0x080C);
Lcd_Write_Com_Data(0x000E,0x2B00);
Lcd_Write_Com_Data(0x001E,0x00B0);
Lcd_Write_Com_Data(0x0001,0x2B3F); //驱动输出控制320*240 0x6B3F
Lcd_Write_Com_Data(0x0002,0x0600); //LCD Driving Waveform control
Lcd_Write_Com_Data(0x0010,0x0000);
Lcd_Write_Com_Data(0x0011,0x60b0); //0x4030 //定义数据格式 16位色 横屏 0x6058 6070
Lcd_Write_Com_Data(0x0005,0x0000);
Lcd_Write_Com_Data(0x0006,0x0000);
Lcd_Write_Com_Data(0x0016,0xEF1C);
Lcd_Write_Com_Data(0x0017,0x0003);
Lcd_Write_Com_Data(0x0007,0x0233); //0x0233
Lcd_Write_Com_Data(0x000B,0x0000);
Lcd_Write_Com_Data(0x000F,0x0000); //扫描开始地址
Lcd_Write_Com_Data(0x0041,0x0000);
Lcd_Write_Com_Data(0x0042,0x0000);
Lcd_Write_Com_Data(0x0048,0x0000);
Lcd_Write_Com_Data(0x0049,0x013F);
Lcd_Write_Com_Data(0x004A,0x0000);
Lcd_Write_Com_Data(0x004B,0x0000);
Lcd_Write_Com_Data(0x0044,0xEF00);
Lcd_Write_Com_Data(0x0045,0x0000);
Lcd_Write_Com_Data(0x0046,0x013F);
Lcd_Write_Com_Data(0x0030,0x0707);
Lcd_Write_Com_Data(0x0031,0x0204);
Lcd_Write_Com_Data(0x0032,0x0204);
Lcd_Write_Com_Data(0x0033,0x0502);
Lcd_Write_Com_Data(0x0034,0x0507);
Lcd_Write_Com_Data(0x0035,0x0204);
Lcd_Write_Com_Data(0x0036,0x0204);
Lcd_Write_Com_Data(0x0037,0x0502);
Lcd_Write_Com_Data(0x003A,0x0302);
Lcd_Write_Com_Data(0x003B,0x0302);
Lcd_Write_Com_Data(0x0023,0x0000);
Lcd_Write_Com_Data(0x0024,0x0000);
Lcd_Write_Com_Data(0x0025,0x8000);
Lcd_Write_Com(0x0022);
}
注:这是液晶的初始化,至于具体设置了哪些,可以去查数据手册,数据手册见附件。
最后主函数中显示汉字,图片的代码如下:
LCD_PutString(40,10,"ILOVE MCU ",Blue2,Yellow);
LCD_PutString(20,30,"电子工程世界论坛",Magenta,Green);
LCD_PutString(20,50,"bbs.eeworld.com.cn",0x07e0,0xf800);
LCD_PutString(40,70,"1234567890",0xF800,0x07e0);
LCD_PutString(0,90,"abcdefghijklmnopqistuvwxyz",0x008f,Yellow);
LCD_PutString(0,110,"`,./<>';:[]{}|?)(-=+*&^%$",0xF800,Yellow);
PutGB3232(0,130,"电",Blue,Yellow); //写入32x32汉字
PutGB3232(40,130,"子",Blue,Red);
PutGB3232(80,130,"技",Blue,Magenta);
PutGB3232(120,130,"术",Blue,Green);
Address_set(0,170,239,170+80-1);//指定图片显示的位置
LCD_Picture(picture);//显示一幅图片
效果如下:
a1.png a2.png
上面显示的两幅图像:qq表情和电子工程世界的logo。本来想一块显示的,但是出现了如下编译错误:
Building configuration: Template - Debug
Updating build tree...
Linking
Error[e16]: Segment DATA16_C (size: 0x10464 align:0) is too long for segment definition. At least 0x1584 more bytes needed. Theproblem occurred while
processing the segment placement command"-Z(CONST)DATA16_C,DATA16_ID,TLS16_ID,DIFUNCT,CHECKSUM=1100-FFDF",where at the moment of
placement the available memory ranges were"CODE:1100-ffdf"
Reservedranges relevant to this placement:
1100-ffdf DATA16_C
Error while running Linker
Total number of errors: 1
Total number of warnings: 0
这是存放两幅图片的数组长度太大了,超出了单片机的存储空间(电子工程世界logo产生的数组为gImage_eeworld[23528],那张qq表情产生的数组就更长了),故只能分开来显示。
最后补充一句,取字模的软件和图片取模的软件是两种软件。要是不会用的话,可以在下面回复我。hjl
图片取模软件.rar (697.94 KB)
(下载次数: 144, 2014-2-16 18:16 上传)
msp430_ssd1289参考程序.rar (169.58 KB)
(下载次数: 204, 2014-2-16 18:15 上传)
LCD点阵提取工具zimo221.rar (256.31 KB)
(下载次数: 139, 2014-2-16 18:15 上传)
SSD1289控制器资料.pdf (618.53 KB)
(下载次数: 236, 2014-2-16 18:16 上传)
本帖最后由 hjl240 于 2014-2-16 18:28 编辑
欢迎关注:JL单片机

回复评论 (13)

使用任意一个单片机掌握了 液晶的操作 其他也应该不是问题了,就是时序的问题吧
点赞  2014-2-16 20:58
引用: gcxzhz 发表于 2014-2-16 20:58
使用任意一个单片机掌握了 液晶的操作 其他也应该不是问题了,就是时序的问题吧

除了时序,还有寄存器的各种操作,寄存器简单一点的模块还好,要是寄存器又多有复杂,模块的资料又少,那要是从头到尾自己开发的话那就比较麻烦,比较耗费时间了。
欢迎关注:JL单片机
点赞  2014-2-16 22:47
     首先讲个题外话,论坛上有很多分享代码的,不过,我觉得,唯一不好的一点就是:只上传代码,却没有具体讲解一下代码。要是代码里有详细的注释,那样的话,不具体讲解代码也没什么关系;但是有一些代码连注释都没有或者注释很少,让人看得很费力,那就有点不太好了。上传代码共享是一件好事,要是有一个好的注释那就更好了!!

楼主的建议非常好。
加油!在电子行业默默贡献自己的力量!:)
点赞  2014-2-17 10:12
引用: soso 发表于 2014-2-17 10:12
首先讲个题外话,论坛上有很多分享代码的,不过,我觉得,唯一不好的一点就是:只上传代码,却没有具 ...

欢迎关注:JL单片机
点赞  2014-2-17 14:30
感谢。。。。我以前的代码很模糊。。。这个希望能用
点赞  2014-2-18 17:05
取模软件怎么用?
点赞  2014-4-12 12:23
这个好!
点赞  2014-4-17 23:05
Nice·
点赞  2014-9-18 16:49
这个写的真详细,感谢楼主的分享,太细致了,慢慢研究
点赞  2014-9-18 16:53
楼主好人啊,学习学习
点赞  2015-2-2 20:34
谢谢楼主
点赞  2015-4-16 16:35
谢谢楼主
点赞  2015-4-16 16:35
学习学习
点赞  2015-7-27 11:33
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复