注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
hjl240的个人空间 https://home.eeworld.com.cn/space-uid-421788.html [收藏] [复制] [分享] [RSS]
日志

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

热度 2已有 7434 次阅读2014-2-16 18:19

首先讲个题外话,论坛上有很多分享代码的,不过,我觉得,唯一不好的一点就是:只上传代码,却没有具体讲解一下代码。要是代码里有详细的注释,那样的话,不具体讲解代码也没什么关系;但是有一些代码连注释都没有或者注释很少,让人看得很费力,那就有点不太好了。上传代码共享是一件好事,要是有一个好的注释那就更好了!!
好了,不扯了,现在聊聊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







本文来自论坛,点击查看完整帖子内容。

发表评论 评论 (2 个评论)
回复 黄腾酒 2014-6-5 17:17
最近也在搞SSD1289,纯汉字显示已经没什么问题了,但是找不到合适的取模软件,不能显示图片和彩色汉字。求大神成全啊
回复 骑士的天空 2014-8-9 12:19
请问能不能把驱动程序的其他部分也分享一下,不会写

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章