打印
[STM32]

STM32f4 TFTLCD显示实验代码(01)

[复制链接]
1332|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小乐Tzz|  楼主 | 2018-9-11 13:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32f4————TFTLCD显示实验代码(01)
/*******************************************************/
本实验,我们用到FSMC驱动 LCD,通过前面的介绍,我们知道TFTLCD 的RS接在FSMC的 A6上面,CS 接在 FSMC_NE4 上,并且是16位数据总线。即我们使用的是FSMC 存储器1的第 4区,我们定义如下LCD 操作结构体(在lcd.h 里面定义):
//LCD 操作结构体
typedef struct
{
  vu16 LCD_REG;
  vu16 LCD_RAM;
} LCD_TypeDef;
//使用NOR/SRAM的  Bank1.sector4,地址位 HADDR[27,26]=11 A6作为数据命令区分线
//注意16位数据总线时,STM32内部地址会右移一位对齐!        
#define LCD_BASE        ((u32)(0x6C000000 | 0x0000007E))
#define LCD             ((LCD_TypeDef *) LCD_BASE)
其中 LCD_BASE,必须根据我们外部电路的连接来确定,我们使用 Bank1.sector4 就是从地址 0X6C000000开始,而 0X0000007E,则是A6的偏移量,这里很多朋友不理解这个偏移量的概念,简单说明下:以 A6 为例,7E 转换成二进制就是:1111110,而 16 位数据时,地址右移一位对齐,那么实际对应到地址引脚的时候,就是:A6:A0=0111111,此时 A6 是0,但是如果16位地址再加1(注意:对应到8 位地址是加2,即 7E+0X02), 那 么 :A6:A0=1000000,此时 A6 就是1了,即实现了对RS的 0和1的控制。
我们将这个地址强制转换为LCD_TypeDef结构体地址,那么可以得到LCD->LCD_REG 的地址就是 0X6C00,007E,对应 A6 的状态为 0(即 RS=0),而 LCD->  LCD_RAM 的地址就是0X6C00,0080(结构体地址自增),对应A6的状态为1(即RS=1)。
所以,有了这个定义,当我们要往 LCD写命令/数据的时候,可以这样写:
LCD->LCD_REG=CMD;  //写命令
LCD->LCD_RAM=DATA; //写数据
而读的时候反过来操作就可以了,如下所示:
CMD= LCD->LCD_REG;//读LCD 寄存器
  DATA = LCD->LCD_RAM;//读 LCD 数据
这其中,CS、 WR、RD和IO 口方向都是由FSMC 控制,不需要我们手动设置了。接下来,我们先介绍一下lcd.h里面的另一个重要结构体:
//LCD 重要参数集
typedef struct   
{                          
  u16 width;      //LCD 宽度
  u16 height;      //LCD 高度
  u16 id;        //LCD ID
  u8  dir;        //横屏还是竖屏控制:0,竖屏;1,横屏。   
  u16  wramcmd;    //开始写 gram指令
  u16  setxcmd;    //设置 x坐标指令
  u16  setycmd;    //设置 y坐标指令   
}_lcd_dev;
//LCD 参数
extern _lcd_dev lcddev;  //管理LCD 重要参数
该结构体用于保存一些 LCD 重要参数信息,比如LCD 的长宽、LCD ID(驱动IC 型号)、LCD 横竖屏状态等,这个结构体虽然占用了十几个字节的内存,但是却可以让我们的驱动函数支持不同尺寸的 LCD,同时可以实现 LCD 横竖屏切换等重要功能,所以还是利大于弊的。有了以上了解,下面我们开始介绍 lcd.c里面的一些重要函数。
先看 7个简单,但是很重要的函数:
//写寄存器函数
//regval:寄存器值
void LCD_WR_REG(vu16 regval)
{    regval=regval;    //使用-O2优化的时候,必须插入的延时
  LCD->LCD_REG=regval;//写入要写的寄存器序号     
}
//写 LCD 数据
//data:要写入的值
void LCD_WR_DATA(vu16 data)
{  data=data;      //使用-O2优化的时候,必须插入的延时
  LCD->LCD_RAM=data;      
}
//读 LCD 数据
//返回值:读到的值
u16 LCD_RD_DATA(void)
{  vu16 ram;      //防止被优化
  ram=LCD->LCD_RAM;
  return ram;      
}               
//写寄存器
//LCD_Reg:寄存器地址
//LCD_RegValue:要写入的数据
void LCD_WriteReg(vu16 LCD_Reg, vu16 LCD_RegValue)
{  LCD->LCD_REG = LCD_Reg;    //写入要写的寄存器序号     
  LCD->LCD_RAM = LCD_RegValue;  //写入数据              
}      
//读寄存器
//LCD_Reg:寄存器地址
//返回值:读到的数据
u16 LCD_ReadReg(vu16 LCD_Reg)
{  LCD_WR_REG(LCD_Reg);    //写入要读的寄存器序号
  delay_us(5);        
  return LCD_RD_DATA();    //返回读到的值
}     
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{   LCD->LCD_REG=lcddev.wramcmd;      
}     
//LCD 写GRAM
//RGB_Code:颜色值
void LCD_WriteRAM(u16 RGB_Code)
{   LCD->LCD_RAM = RGB_Code;//写十六位GRAM
}
因为FSMC 自动控制了WR/RD/CS 等这些信号,所以这7个函数实现起来都非常简单,我们就不多说,注意,上面有几个函数,我们添加了一些对MDK –O2优化的支持,去掉的话,在-O2 优化的时候会出问题。这些函数实现功能见函数前面的备注,通过这几个简单函数的组合,我们就可以对 LCD进行各种操作了。
/*******************************************************/



相关帖子

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

本版积分规则

70

主题

70

帖子

0

粉丝