首先讲个题外话,论坛上有很多分享代码的,不过,我觉得,唯一不好的一点就是:只上传代码,却没有具体讲解一下代码。要是代码里有详细的注释,那样的话,不具体讲解代码也没什么关系;但是有一些代码连注释都没有或者注释很少,让人看得很费力,那就有点不太好了。上传代码共享是一件好事,要是有一个好的注释那就更好了!!
好了,不扯了,现在聊聊ssd1289液晶。
这几天用了一下ssd1289液晶,调好了程序,在此分享一下。该液晶使用msp430f149/169单片机控制的。先看看效果图:
下面说一下代码关键的一些地方:
/*******************************************
函数名称: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,故若是采用竖屏模式,x1,x2范围为0-239,y1,y2范围为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;
}
}
}
注:颜色的设定(fColor,bColor的值)可以采用如下:
/* 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);//显示一幅图片
效果如下:
上面显示的两幅图像: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
本文来自论坛,点击查看完整帖子内容。