打印

LPC2214采用总线模式读TFT屏,寄存器地址遇到困难

[复制链接]
2629|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我是土匪|  楼主 | 2009-3-25 16:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为什么要读屏:
手持设备,CPU进入掉电模式后只要连接TFT的电源(已经关闭背光和驱动电路),就会产生接近200ma电流,所以采用这样的措施:
硬件用IO口控制三极管 ,可以切断TFT电源;
软件CPU先休眠一段时间,没有触发采用定时器唤醒,然后读全屏数据保存到片外SRAM,切断TFT电源,CPU进入掉电模式,当CPU被按键唤醒后,先对屏供电,背光关闭,打开TFT驱动电路,对TFT初始化,恢复掉电前显示界面,打开背光。

目前遇到困难:读屏数据不正确。

相关帖子

沙发
我是土匪|  楼主 | 2009-3-25 17:16 | 只看该作者

硬件平台2套

一套采用ZLG的SMARTARM2200和TFT4267模块
一套自己制板 LPC2214 + 4.4
均采用总线方式驱动。

其中写屏操作2者几乎相同,现把相关代码发到下面
1、SMARTARM2200平台下读一段屏屏显示代码:


// TFT液晶模块硬件操作宏
#define  S6D0129_IR        (*((volatile unsigned short *) 0x83200000)) 
#define  S6D0129_DR        (*((volatile unsigned short *) 0x83200002))
// 定义S6D0129的部份寄存器
#define  SET_ADDR_X            0x0020        /* GRAM地址设置(R21H,R20H) */
#define  SET_ADDR_Y            0x0021
#define  WR_RD_DATA            0x0022        /* 写/读GRAM数据 (R22H) */
void  DisDemo(void)
{  uint32  x, y;
   uint32  no = 0;
   uint16  dat;

   // 第1幅图  
   TftSetWindow(0,0, 239, 319); //设置数据填充窗口大小
   TftSetWrite(0,0);   
   no = 0;
   for(y=0; y<320; y++)
   {  for(x=0; x<240; x++)
      { 
         TftSendDat(data[no ++]);        
      }
   }      
}
/*******************************************************
* 名称: TftSetWrite
* 功能: 设置数据地址指针(坐标值),并发送写数据命令。
*       接着不断的写入数据即可,GRAM地址会自动增加。
* 入口参数: x        横坐标的值 (0-239)
*           y       纵坐标的值 (0-319)
* 出口参数: 设置正确返回TRUE,参数超出范围返回FALSE
*******************************************************/
uint8  TftSetWrite(uint16 x, uint16 y)
{  uint8  ret;

   ret = TftSetAddr(x, y);
   TftSendCom(WR_RD_DATA);        // 写数据
   return(ret);
}
/*******************************************************
* 名称: TftSetAddr
* 功能: 设置数据地址指针(坐标值)。
* 入口参数: x        横坐标的值 (0-239)
*           y       纵坐标的值 (0-319)
* 出口参数: 设置正确返回TRUE,参数超出范围返回FALSE
*******************************************************/
uint8  TftSetAddr(uint16 x, uint16 y)
{  TftSendCom(SET_ADDR_X);        // 设置地址低8位
   TftSendDat(x);
   
   TftSendCom(SET_ADDR_Y);        // 设置地址高9位
   TftSendDat(y);
   
   if((x<240) && (y<320)) return(TRUE);
     else  return(FALSE);
}
/*******************************************************
* 名称: TftSendCom
* 功能: 向TFT液晶模块发送命令字。
* 入口参数: com   命令字(uint16)
* 出口参数: 无
*******************************************************/
void  TftSendCom(uint16 com)
{  S6D0129_IR = com;
}

使用特权

评论回复
板凳
我是土匪|  楼主 | 2009-3-25 17:19 | 只看该作者

读屏

/*******************************************************
* 名称: TftSendDat
* 功能: 向TFT液晶模块发送数据。
* 入口参数: dat   待发送的数据(uint16)
* 出口参数: 无
*******************************************************/
void  TftSendDat(uint16 dat)
{  S6D0129_DR = dat;
}


/*******************************************************
* 名称: TftRcvDat
* 功能: 读取TFT液晶模块的数据。
* 入口参数: 无
* 出口参数: 返回值即是读出的数据
*******************************************************/
uint16  TftRcvDat(void)
{  uint16  ret;

   ret = S6D0129_DR;
   return(ret);
}
uint16 data[320 * 240] = {0};
void Read_Lcd(void)
{
    uint16 x,y;
    uint16 no = 0;
    
    for(y = 0 ;y < 320;y++)
        for(x = 0 ;x < 240; x++)
            GUI_ReadPoint(x,y, & data[no++]);
}

/****************************************************************************
* 名称:GUI_ReadPoint()
* 功能:读取指定位置点的颜色数据。
* 入口参数:x        指定点所在列的位置
*           y        指定点所在行的位置
* 出口参数:返回值即是读出值(RRRRRGGGGGGBBBBB)。
****************************************************************************/
uint8  GUI_ReadPoint(uint16 x, uint16 y, TCOLOR *ret)
{  uint16  bak;

   /* 参数过滤 */
   if(x>=GUI_LCM_XMAX) return(0);
   if(y>=GUI_LCM_YMAX) return(0);
   
   /* 读取数据 */
   TftSetAddr(x, y);        // 设置地址
   TftSendCom(WR_RD_DATA);
   bak = TftRcvDat();
   bak = TftRcvDat();      
   *ret = bak;
   
   return(1);
}

使用特权

评论回复
地板
我是土匪|  楼主 | 2009-3-25 17:31 | 只看该作者

第二套平台


#define        SET_ADDR_X        0x27        //读高位地址
#define        SET_ADDR_Y        0x28        //读低位地址
#define      WR_RD_DATA        0x26        /* 写/读GRAM数据 (R22H) */
/****************************************************************************
* 名称:void Read_Full_Lcd(void)
* 功能:用于关闭TFT电源前的保存操作
****************************************************************************/
void Read_Full_Lcd(void)
{
    uint32 x,y;
    uint32 no = 0;
    
    AMP506_WindowSet(0,0, 480, 271);

    for(y = 0;y < GUI_LCM_YMAX; y ++)
        for(x = 0;x < GUI_LCM_XMAX;x ++) 
            GUI_ReadPoint(x,y, & data[no++]);    
}

/****************************************************************************
* 名称:void Reappear_Lcd(void)
* 功能:用于掉电唤醒后TFT的恢复操作
****************************************************************************/
void Reappear_Lcd(void)
{
    
    uint32 x,y;
    uint16 dat;
    uint32  no;
    
    no=0;
    
    AMP506_WindowSet(0,0, GUI_LCM_XMAX,GUI_LCM_YMAX);    //AMP506_WindowSet(0,0, 480, 271);
    FD506_DisplayRAM_WriteEnable;
   
    for(y = 0;y < GUI_LCM_YMAX; y ++)
        for(x = 0;x < GUI_LCM_XMAX;x ++)   
            {
                dat = data[no ++];                        //图片作为程序一部分存储
                TftSendDat(dat);
            }      
    FD506_DisplayRAM_WriteDisable;
       



这段代码读出来的始终为常量,经过分析始终感觉一直在读一个地址。换句话第二个代码问题极有可能出现在开都的宏(TFT寄存器)的使用

使用特权

评论回复
5
我是土匪|  楼主 | 2009-3-25 17:37 | 只看该作者

贴datasheet

TFT4267涉及到的寄存器:

使用特权

评论回复
6
我是土匪|  楼主 | 2009-3-25 17:40 | 只看该作者

4.3TFT寄存器

使用特权

评论回复
7
我是土匪|  楼主 | 2009-3-25 17:48 | 只看该作者

实际工作量很小

相当于我把// 定义S6D0129的部份寄存器
#define  SET_ADDR_X            0x0020        /* GRAM地址设置(R21H,R20H) */
#define  SET_ADDR_Y            0x0021
#define  WR_RD_DATA            0x0022        /* 写/读GRAM数据 (R22H) */

换成了

#define        SET_ADDR_X        0x27        //读高位地址
#define        SET_ADDR_Y        0x28        //读低位地址
#define      WR_RD_DATA        0x26        /* 写/读GRAM数据 (R22H) */ 

使用特权

评论回复
8
我是土匪|  楼主 | 2009-3-25 18:48 | 只看该作者

晕菜

截图上传后很容易发现问题:

地址寄存器宽度明显不同,因为TFT大小不同;
我读的数据一直都是某个地址数值,所以出现上述结果。

原因找到,继续,争取早点解决问题

使用特权

评论回复
9
我是土匪|  楼主 | 2009-3-26 16:18 | 只看该作者

设置地址

uint8  TftSetAddr_1(uint16 x, uint16 y)
{  
    TftSendCom(SET_ADDR_3);      // 设置地址低8位
       TftSendDat(x);
   
       TftSendCom(SET_ADDR_2);      // 设置地址中8(1(X高位) + 7(y低7位)位)
       TftSendDat((y << 1) | (x >> 7));
    
    TftSendCom(SET_ADDR_1);      // 设置地址高2(X高位) + 7(y低7位)位
       TftSendDat( y >> 6 );
         
       if((x<GUI_LCM_XMAX) && (y<GUI_LCM_YMAX)) return(TRUE);
    else  return(FALSE);
}

使用特权

评论回复
10
我是土匪|  楼主 | 2009-3-30 14:48 | 只看该作者

结贴

最后用尽所有办法仍旧没有读取屏的内容,商家提供代码也是中看不中用。
周末休息2天,发现自己钻死胡同了,今早另辟新径,已经解决:
写屏同时将数据写到片外SRAM中,在SRAM开辟2维数组,对应TFT的行列点数,这样就OK了

使用特权

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

本版积分规则

226

主题

1761

帖子

30

粉丝