百为STM32开发板教程之四——9320 LCD显示
以下内容都是来自STM32数据手册,9320数据手册,和百为STM3210E-EVAL电路图,和测试程序,大家可以翻阅看下。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1、先了解STM32 FSMC接口连接LCD的电路图:
LCD部分
2013-5-31 03:48 上传
下载附件 (139.12 KB)
STM32数据线部分,FSMC_NE4、FSMC_NWE和FSMC_NOE部分未画出,可参看百为STM32开发板原理图
2013-5-31 03:49 上传
下载附件 (62.97 KB)
暂时撇开触摸电路不讲,这里LCD和STM32连接的主要有A0(寄存器或数据选择),D0~D15(数据线),FSMC_NE4(FSMC片选),FSMC_NWE(FSMC读使能),FSMC_NOE(FSMC写使能)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
二、FSMC是什么?
FSMC可以理解为一个自动控制的接口,它可以自动输出读、写信号等。
如果不用FSMC,我们控制一个LCD时,需要手动输出RS,RO,RW这些信号
以读LCD数据为例,传统的控制方法:
RS = 1;
RO = 0;
RW = 1;
lcd_data = Pxxx;
若采用FSMC则很简单,只要读一个地址的值读出即可,FSMC系统会自动输出RO,RW这些控制信号:
lcd_data = *(U32)0x60000002;
这个0x60000002是怎么来的呢,这个要看下数据手册里FSMC的功能模块了
2013-5-31 03:49 上传
下载附件 (57.48 KB)
FSMC支持多种储存器件,我们把LCD当作NOR或PSRAM类型来控制,即属于块1,地址在0x60000000~0x6FFFFFFF范围内
这个范围又可以分为4个小范围 ,每个小范围对应STM32的一个管脚/片选,FSMC_NEx(x=1,2,3,4)
2013-5-31 03:49 上传
下载附件 (58.97 KB)
我们百为STM3210E-EVAL开发板的LCD用的是FSMC_NE4
所以地址为0x60000000 | 0x3<<26 = 0x6C000000, 其中0x3就是内部的地址线HADDR[27:26]的值。
2013-7-6 19:02 上传
下载附件 (137.7 KB)
这里采用的是FSMC的16位接口,RS接的是A0地址线,所以当要输出A0为1时,FSMC_A[0] = 1,即,HADDR[1] = 1
所以得出HADDR[27:0] = 0x6C000002
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
三、9320 LCD是怎么控制的?
9320的LCD控制分为寄存器控制和数据读写,所以首先定义9320的寄存器地址和数据地址
typedef struct
{
vu16 LCD_REG;
vu16 LCD_RAM;
} LCD_TypeDef;
/* Note: LCD /CS is CE4 - Bank 4 of NOR/SRAM Bank 1~4 */
#define LCD_BASE ((u32)(0x60000000 | 0x0C000000))
#define LCD ((LCD_TypeDef *) LCD_BASE)
经过上面这样定义之后,LCD->LCD_REG 就相当于 *(u32)0x6c000000,LCD->LCD_RAM相当于*(u32)0x6c000002
/************************************************************************/
然后可以通过下面的函数写寄存器:
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{
LCD->LCD_REG = LCD_Reg; //写命令寄存器
LCD->LCD_RAM = LCD_RegValue; //写GRAM数据
}
例如我们写寄存器R3,可以调用上面的函数
LCD_WriteReg(R3, 0x1030);
通过下面的函数读寄存器:
u16 LCD_ReadReg(u8 LCD_Reg)
{
LCD->LCD_REG = LCD_Reg; //写命令寄存器
return (LCD->LCD_RAM);//读GRAM数据
}
/************************************************************************/
写LCD GARM数据之前,可以设置一下坐标位置:
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
LCD_WriteReg(R32, Xpos); //写命令寄存器R32
LCD_WriteReg(R33, Ypos); //写命令寄存器R33
}
设置R34寄存器准备写GRAM数据,(写多个数据时只需设置一次)
void LCD_WriteRAM_Prepare(void)
{
LCD->LCD_REG = R34; //准备读写GRAM数据
}
然后通过下面的函数写LCD GARM数据:
void LCD_WriteRAM(u16 RGB_Code)
{
LCD->LCD_RAM = RGB_Code;//写GRAM数据到当前地址
}
/************************************************************************/
然后通过下面的函数读LCD GARM数据,根据9320数据手册,读GRAM数据需要读两次,第一次为无效数据,第二次才是实际数据
u16 LCD_ReadRAM(void)
{
vu16 dummy;
LCD->LCD_REG = R34;//准备读GRAM数据
dummy = LCD->LCD_RAM;//第一次返回无效数据,丢弃
return LCD->LCD_RAM; //第二次返回真实的数据
}
/************************************************************************/
四、程序是怎么控制LCD的
先用下面的函数初始化
STM3210E_LCD_Init();
LCD_Clear(White);
然后就可以调用刚才介绍的函数读写LCD GRAM了
如画一个蓝色的点:
LCD_SetCursor(50, 100);
LCD_WriteRAM_Prepare();
LCD_WriteRAM(Blue);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|