打印
[STM32]

STM32f4 TFTLCD显示实验代码(02)

[复制链接]
815|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小乐Tzz|  楼主 | 2018-9-11 13:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32f4————TFTLCD显示实验代码(02)
/*******************************************************/
第七个要介绍的函数是坐标设置函数,该函数代码如下:
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
  if(lcddev.id==0X9341||lcddev.id==0X5310)
  {
    LCD_WR_REG(lcddev.setxcmd);   
    LCD_WR_DATA(Xpos>>8);   
    LCD_WR_DATA(Xpos&0XFF);     
    LCD_WR_REG(lcddev.setycmd);   
    LCD_WR_DATA(Ypos>>8);   
    LCD_WR_DATA(Ypos&0XFF);
  }else if(lcddev.id==0X6804)
  {
    if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//横屏时处理
    LCD_WR_REG(lcddev.setxcmd);   
    LCD_WR_DATA(Xpos>>8);   
    LCD_WR_DATA(Xpos&0XFF);     
    LCD_WR_REG(lcddev.setycmd);   
    LCD_WR_DATA(Ypos>>8);   
    LCD_WR_DATA(Ypos&0XFF);
  }else if(lcddev.id==0X5510)
  {
    LCD_WR_REG(lcddev.setxcmd);   
    LCD_WR_DATA(Xpos>>8);   
    LCD_WR_REG(lcddev.setxcmd+1);   
    LCD_WR_DATA(Xpos&0XFF);     
    LCD_WR_REG(lcddev.setycmd);   
    LCD_WR_DATA(Ypos>>8);   
    LCD_WR_REG(lcddev.setycmd+1);   
    LCD_WR_DATA(Ypos&0XFF);     
  }else
  {
    if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//横屏其实就是调转x,y坐标
    LCD_WriteReg(lcddev.setxcmd, Xpos);
    LCD_WriteReg(lcddev.setycmd, Ypos);
  }      
}
该函数实现将 LCD 的当前操作点设置到指定坐标(x,y)。因为 9341/5310/6804/5510 等的设置同其他屏有些不太一样,所以进行了区别对待。
接下来我们介绍第八个函数:画点函数。该函数实现代码如下:
//画点
//x,y:坐标
//POINT_COLOR:此点的颜色
void LCD_DrawPoint(u16 x,u16 y)
{
  LCD_SetCursor(x,y);    //设置光标位置   
  LCD_WriteRAM_Prepare();  //开始写入GRAM
  LCD->LCD_RAM=POINT_COLOR;   
}
该函数实现比较简单,就是先设置坐标,然后往坐标写颜色。其中POINT_COLOR 是我们定义的一个全局变量,用于存放画笔颜色,顺带介绍一下另外一个全局变量:BACK_COLOR,该变量代表 LCD 的背景色。LCD_DrawPoint 函数虽然简单,但是至关重要,其他几乎所有上层函数,都是通过调用这个函数实现的。
有了画点,当然还需要有读点的函数,第九个介绍的函数就是读点函数,用于读取 LCD的 GRAM,这里说明一下,为什么OLED模块没做读GRAM的函数,而这里做了。因为OLED模块是单色的,所需要全部GRAM也就1K个字节,而TFTLCD 模块为彩色的,点数也比OLED模块多很多,以16位色计算, 一款320×240的液晶,需要320×240×2个字节来存储颜色值,也就是也需要 150K 字节,这对任何一款单片机来说,都不是一个小数目了。而且我们在图形叠加的时候,可以先读回原来的值,然后写入新的值,在完成叠加后,我们又恢复原来的值。这样在做一些简单菜单的时候,是很有用的。这里我们读取 TFTLCD 模块数据的函数为LCD_ReadPoint,该函数直接返回读到的 GRAM 值。该函数使用之前要先设置读取的 GRAM地址,通过LCD_SetCursor函数来实现。LCD_ReadPoint的代码如下:
//读取个某点的颜色值     
//x,y:坐标
//返回值:此点的颜色
u16 LCD_ReadPoint(u16 x,u16 y)
{
  vu16 r=0,g=0,b=0;
  if(x>=lcddev.width||y>=lcddev.height)return 0;    //超过了范围,直接返回        
  LCD_SetCursor(x,y);        
  if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310)LCD_WR_REG(0X2E);
//9341/6804/3510  发送读GRAM指令
  else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00);  //5510 发送读GRAM指令
  else LCD_WR_REG(R34);                 //其他 IC 发送读GRAM指令
  if(lcddev.id==0X9320)opt_delay(2);        //FOR 9320,延时2us        
    LCD_RD_DATA();                //dummy Read      
  opt_delay(2);      
    r=LCD_RD_DATA();                    //实际坐标颜色
    if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)           
{  //9341/NT35310/NT35510要分 2次读出

    opt_delay(2);      
    b=LCD_RD_DATA();   
    g=r&0XFF;//9341/5310/5510等,第一次读取的是RG的值,R 在前,G 在后,各占 8位
    g<<=8;
  }   
  if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0XB505||
lcddev.id==0XC505)return r;  //这几种 IC 直接返回颜色值
  else if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)return (((r>>11)<<11)
|((g>>10)<<5)|(b>>11));  //ILI9341/NT35310/NT35510 需要公式转换一下
  else return LCD_BGR2RGB(r);  //其他 IC
}
在 LCD_ReadPoint 函数中,因为我们的代码不止支持一种 LCD 驱动器,所以,我们根据不同的 LCD 驱动器((lcddev.id)型号,执行不同的操作,以实现对各个驱动器兼容,提高函数的通用性。
/*******************************************************/



相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

70

主题

70

帖子

0

粉丝