12回答

0收藏

TFT屏试验基础部分总结

 

#开源分享 #开源分享 6273 人阅读 | 12 人回复 | 2013-01-05

本帖最后由 littleway 于 2013-1-5 08:22 编辑

先看TFT屏的相关引脚,一共有21个,如下:
数据引脚:DB15-DB0      16位数据)
写引脚:WR              (低电平有效)
读引脚:RD               (低电平有效)
片选引脚:CS             (低电平有效)
数据/命令选择引脚:RS     (低电平表示写入命令;高电平表示写入数据)
数据模式选择引脚CM: (低电平表示使用16位数据模式;高电平表示使用8位数据模式)
上述引脚与f0的连接如下:
DB15-DB8<--->PC7-PC0
DB7-DB0 <--->PB7-PB0
PD2<--->WR
PC12<--->RD
PC11<--->CS  
PC10<--->RS  
PB11<--->CM
接下来WR,RD,CS,RS的置位/复位操作的代码定义,如下:(在ili9328.h中)
  1. #define Set_Cs GPIOC->BSRR = 0x00000800;

  2. #define Clr_Cs GPIOC->BRR = 0x00000800;


  3. #define Set_Rs GPIOC->BSRR = 0x00000400;

  4. #define Clr_Rs GPIOC->BRR = 0x00000400;


  5. #define Set_nWr GPIOD->BSRR = 0x00000004;

  6. #define Clr_nWr GPIOD->BRR = 0x00000004;


  7. #define Set_nRd GPIOC->BSRR = 0x00001000;

  8. #define Clr_nRd GPIOC->BRR = 0x00001000;

复制代码

有了上述的宏定义,我们就可以使用Set_Cs来执行Cs的置位操作了,其余类似。
再接下来,要来写对于TFT屏的读/写操作的代码了,先来看时序图,如下:     
               
            

写操作分为两部分,第一部分是写寄存器索引(Write register ‘index’),也就是通常所说的写命令,第二部分是写寄存器数据(Write register ‘data’),也就是通常所说的写数据。相关代码如下:
写命令函数代码:
  1. void LCD_WR_REG(uint16_t cmd)
  2. {
  3.   Clr_Rs; //RS=0,写命令
  4.   Clr_Cs; //片选有效
  5.   GPIOB->ODR &= 0xff00;
  6.   GPIOC->ODR &= 0xff00;
  7.   GPIOB->ODR |=((cmd)&(0x00ff));
  8.   GPIOC->ODR|=(cmd>>8);
  9.   Clr_nWr; //写操作有效
  10.   Set_nWr; //写操作失效
  11.   Set_Cs; //片选无效
  12. }
复制代码
写数据函数代码:
  1. void LCD_WR_DATA(uint16_t val)
  2. {
  3.   Set_Rs; //RS=1,写数据
  4.   Clr_Cs; //片选有效
  5.   GPIOB->ODR &= 0xff00;
  6.   GPIOC->ODR &= 0xff00;
  7.   GPIOB->ODR|=((val)&(0x00ff));
  8.   GPIOC->ODR|=(val>>8);
  9.   Clr_nWr; //写操作有效
  10.   Set_nWr; //写操作失效
  11.   Set_Cs; //片选无效
  12. }
复制代码
读操作也分为两部分,第一部分是写寄存器索引(Write register ‘index’),也就是通常所说的写命令,第二部分是读寄存器数据(Read register ‘data’),也就是通常所说的读数据。(这也比较好理解,第一步通过写命令操作确定要访问的寄存器id,第二步通过读数据操作将对应寄存器里的数据读出。)  相关代码如下:
读数据函数代码:
  1. uint16_t LCD_RD_DATA(void)
  2. {
  3. unsigned short val,val1,val2;
  4.   Set_Rs; //RS=1,读数据
  5. Set_nWr; //写操作失效
  6. Clr_nRd; //读操作有效
  7. GPIOB->MODER&=0xffff0000; //将GPIO设置为输入
  8.   GPIOC->MODER&=0xffff0000;
  9.   
  10. val1 = GPIOB->IDR;
  11. val2 = GPIOC->IDR;
  12. val=((val1)&(0x00ff))+((val2<<8)&(0xff00));

  13. GPIOB->MODER|=0x00005555; //输入完了后重新设置为输出
  14. GPIOC->MODER|=0x00005555;
  15. Set_nRd; //读操作失效
  16. return val;
  17. }
复制代码
然后分别将读/写操作的代码整合成一个函数,如下:
写函数代码:
  1. void LCD_WR_REG_DATA(uint16_t reg, uint16_t data)
  2. {
  3. LCD_WR_REG(reg); // Write register ‘index’
  4. LCD_WR_DATA(data); // Write register ‘data’
  5. }
复制代码
读函数代码:
  1. uint16_t LCD_RD_REG_DATA (uint16_t reg)
  2. {
  3. uint16_t value;
  4. Clr_Cs;
  5. LCD_WR_REG(reg); // Write register ‘index’
  6. Clr_Cs; <FONT color=red>//后加的!!</FONT>
  7. value = LCD_RD_DATA(); // Read register ‘data’
  8. Set_Cs;
  9. return value;
  10. }
复制代码
这里我觉得有一个问题,在执行LCD_WR_REG(reg); 后Cs已经被置位,因此应该在该语句后加上Clr_Cs;这样才和datasheet里面的时序对应。
有了以上的代码,就完成了对tft屏的读/写操作。这是后续各种复杂操作的基础,因为后面各种复杂函数的操作都是利用这些读/写函数来完成相关配置的。在研究后面各类复杂函数之前,先搞一个简单的——读出tft屏主控芯片的型号。其实这个是最最简单的,因为只需要向寄存器0x0000写入值0x0001,然后再读该寄存器就可以得到主控芯片的型号了。相关代码如下:
  1. uint16_t id=0;
  2. int main()
  3. {
  4.   LCD_WR_REG_DATA(0x0000,0x0001);
  5.   id=LCD_RD_REG_DATA(0x0000);
  6.   while (1)
  7.   {
  8.   }
  9. }
复制代码
我的开发板读出主控芯片型号为9325
    接下来就是使用读/写函数为基础的各类“上层”函数,就不做进一步的总结了。


分享到:
回复

使用道具 举报

回答|共 12 个

倒序浏览

沙发

小菜儿

发表于 2013-1-5 08:32:55 | 只看该作者

沙发!!!顶~~~多谢楼主分享~~~
板凳

kk5290122

发表于 2013-1-5 08:33:09 | 只看该作者

我用来显示过图片……
地板

zndz410

发表于 2013-1-5 08:33:45 | 只看该作者

抢沙发学习学习。
5#

GY@艳

发表于 2013-1-5 08:38:20 | 只看该作者

楼主辛苦了
爱板  爱板  爱板     https://www.cirmall.com
6#

swustlx86

发表于 2013-1-5 08:46:32 | 只看该作者

谢谢分享  学习了
7#

littleway_3007505

发表于 2013-1-5 09:14:37 | 只看该作者

各位不用客气,我也是刚接触的菜鸟一只。只是记录下学习过程中的一些收获,希望大家相互帮助、共同进步!
8#

liuyu-419812

发表于 2013-1-5 10:04:14 | 只看该作者

学习一下,顶一个
9#

噗噗熊

发表于 2013-1-5 10:36:07 | 只看该作者

很好,这样的经验对很多学习者很有用的,支持个!
10#

青风

发表于 2013-1-5 11:01:14 | 只看该作者

这样才能进步呀,以前都是这样走过来的
我的淘宝店:http://qfv5.taobao.com/
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条