本帖最后由 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中)
- #define Set_Cs GPIOC->BSRR = 0x00000800;
- #define Clr_Cs GPIOC->BRR = 0x00000800;
- #define Set_Rs GPIOC->BSRR = 0x00000400;
- #define Clr_Rs GPIOC->BRR = 0x00000400;
- #define Set_nWr GPIOD->BSRR = 0x00000004;
- #define Clr_nWr GPIOD->BRR = 0x00000004;
- #define Set_nRd GPIOC->BSRR = 0x00001000;
- #define Clr_nRd GPIOC->BRR = 0x00001000;
复制代码
有了上述的宏定义,我们就可以使用Set_Cs来执行Cs的置位操作了,其余类似。 再接下来,要来写对于 TFT屏的读/写操作的代码了,先来看时序图,如下:
写操作分为两部分,第一部分是写寄存器索引(Write register ‘index’),也就是通常所说的写命令,第二部分是写寄存器数据(Write register ‘data’),也就是通常所说的写数据。相关代码如下: 写命令函数代码:
- void LCD_WR_REG(uint16_t cmd)
- {
- Clr_Rs; //RS=0,写命令
- Clr_Cs; //片选有效
- GPIOB->ODR &= 0xff00;
- GPIOC->ODR &= 0xff00;
- GPIOB->ODR |=((cmd)&(0x00ff));
- GPIOC->ODR|=(cmd>>8);
- Clr_nWr; //写操作有效
- Set_nWr; //写操作失效
- Set_Cs; //片选无效
- }
复制代码写数据函数代码:
- void LCD_WR_DATA(uint16_t val)
- {
- Set_Rs; //RS=1,写数据
- Clr_Cs; //片选有效
- GPIOB->ODR &= 0xff00;
- GPIOC->ODR &= 0xff00;
- GPIOB->ODR|=((val)&(0x00ff));
- GPIOC->ODR|=(val>>8);
- Clr_nWr; //写操作有效
- Set_nWr; //写操作失效
- Set_Cs; //片选无效
- }
复制代码读操作也分为两部分,第一部分是写寄存器索引(Write register ‘index’),也就是通常所说的写命令,第二部分是读寄存器数据(Read register ‘data’),也就是通常所说的读数据。(这也比较好理解,第一步通过写命令操作确定要访问的寄存器id,第二步通过读数据操作将对应寄存器里的数据读出。) 相关代码如下: 读数据函数代码:
- uint16_t LCD_RD_DATA(void)
- {
- unsigned short val,val1,val2;
- Set_Rs; //RS=1,读数据
- Set_nWr; //写操作失效
- Clr_nRd; //读操作有效
- GPIOB->MODER&=0xffff0000; //将GPIO设置为输入
- GPIOC->MODER&=0xffff0000;
-
- val1 = GPIOB->IDR;
- val2 = GPIOC->IDR;
- val=((val1)&(0x00ff))+((val2<<8)&(0xff00));
- GPIOB->MODER|=0x00005555; //输入完了后重新设置为输出
- GPIOC->MODER|=0x00005555;
- Set_nRd; //读操作失效
- return val;
- }
复制代码然后分别将读/写操作的代码整合成一个函数,如下: 写函数代码: - void LCD_WR_REG_DATA(uint16_t reg, uint16_t data)
- {
- LCD_WR_REG(reg); // Write register ‘index’
- LCD_WR_DATA(data); // Write register ‘data’
- }
复制代码读函数代码: - uint16_t LCD_RD_REG_DATA (uint16_t reg)
- {
- uint16_t value;
- Clr_Cs;
- LCD_WR_REG(reg); // Write register ‘index’
- Clr_Cs; <FONT color=red>//后加的!!</FONT>
- value = LCD_RD_DATA(); // Read register ‘data’
- Set_Cs;
- return value;
- }
复制代码这里我觉得有一个问题,在执行LCD_WR_REG(reg); 后Cs已经被置位,因此应该在该语句后加上Clr_Cs;这样才和datasheet里面的时序对应。
有了以上的代码,就完成了对tft屏的读/写操作。这是后续各种复杂操作的基础,因为后面各种复杂函数的操作都是利用这些读/写函数来完成相关配置的。在研究后面各类复杂函数之前,先搞一个简单的——读出tft屏主控芯片的型号。其实这个是最最简单的,因为只需要向寄存器0x0000写入值0x0001,然后再读该寄存器就可以得到主控芯片的型号了。相关代码如下:
- uint16_t id=0;
- int main()
- {
- LCD_WR_REG_DATA(0x0000,0x0001);
- id=LCD_RD_REG_DATA(0x0000);
- while (1)
- {
- }
- }
复制代码我的开发板读出主控芯片型号为9325。 接下来就是使用读/写函数为基础的各类“上层”函数,就不做进一步的总结了。
|