打印
[应用相关]

STM32关于LCD 例程的一些疑惑

[复制链接]
14777|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
在水一飞|  楼主 | 2009-1-6 20:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
* Description        : This file includes the LCD driver for AM-240320L8TNQW00H
*                     (LCD_ILI9320) Liquid Crystal Display Module of STM3210E-EVAL
*                      board.
//////////////////////////////////////////////////////////////////////////////////////
/* Private typedef -----------------------------------------------------------*/
typedef struct
{
  vu16 LCD_REG;
  vu16 LCD_RAM;
} LCD_TypeDef;

/* LCD is connected to the FSMC_Bank1_NOR/SRAM4 and NE4 is used as ship select signal */
#define LCD_BASE    ((u32)(0x60000000 | 0x0C000000))
#define LCD         ((LCD_TypeDef *) LCD_BASE)
////////////////////////////////////////////////////////////////////////////////////////
 void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{
  /* Write 16-bit Index, then Write Reg */
  LCD->LCD_REG = LCD_Reg;
  /* Write 16-bit Reg */
  LCD->LCD_RAM = LCD_RegValue;
}
/////////////////////////////////////////////////////////////////////////////////////////
u16 LCD_ReadReg(u8 LCD_Reg)
{
  /* Write 16-bit Index (then Read Reg) */
  LCD->LCD_REG = LCD_Reg;
  /* Read 16-bit Reg */
  return (LCD->LCD_RAM);
}
/////////////////////////////////////////////////////////////////////////////////////////
void LCD_WriteRAM_Prepare(void)
{
  LCD->LCD_REG = R34;
}
/////////////////////////////////////////////////////////////////////////////////////////
void LCD_WriteRAM(u16 RGB_Code)
{
  /* Write 16-bit GRAM Reg */
  LCD->LCD_RAM = RGB_Code;
}

 这是例程里lcd.c里的一下底层函数的实现。在结构体里的定义:LCD_REG变量地址:0x6c000000;
LCD_RAM变量地址:0x6c000001,STM32的FSMC的地址引脚A0接LCD_ILI9320的RS(L:访问reg;H:访问ram) ,
通过给LCD_REG变量或LCD_RAM变量写数据来实现访问reg和ram,是这样理解的吗?
那么为什么在写LCD_ILI9320的寄存器时,函数 LCD_WriteReg(,)里对reg写操作:LCD->LCD_REG = LCD_Reg;先发送reg的编号,
再 LCD->LCD_RAM = LCD_RegValue; 为什么是对LCD_RAM赋值来实现发送reg需要修改的数据啊?不懂。
还有 LCD_ReadReg(u8 LCD_Reg)的读操作,
也不大明白,怎么实现的啊?

对LCD_ILI932里的reg,ram读写操作时,要给/WR(写入),/RD(读入) 信号的,在用FSMC模块时,程序里没涉及到这些读写信号啊?
高手指点下在下啊?FSMC控制LCD_ILI9320是个什么过程啊?小弟不胜感激!
沙发
amingriyue| | 2009-1-6 20:31 | 只看该作者

回答

1、reg呢,是LCD寄存器的地址,ram呢,是要向寄存器里写的值
2、读写过程呢,是FSMC自动完成的,只需你配置好,对对应的地址操作读写即可

使用特权

评论回复
板凳
在水一飞|  楼主 | 2009-1-6 20:37 | 只看该作者

回复

是的,之前我用PIC单片机做过LCD屏的程序,并口线(inter8080)有:数据线D0-D15,WR(写入),RD(读入),RS(H电平时访问reg;L电平时访问RAM)。

在这个例程里,STM32的A0接LCD的RS脚信号,通过STM32地址线A0的0,1变换,来实现访问LCD_ILI9320里的reg和RAM。我想应该是这么实现的。但是,写reg的函数void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)里,怎么是 LCD->LCD_RAM = LCD_RegValue;给RAM赋值呢?

使用特权

评论回复
地板
在水一飞|  楼主 | 2009-1-7 10:23 | 只看该作者

回复

LCD->REG地址为0x6c000000
LCD->RAM地址为0x6c000001
末尾的0和1对应了A0的0和1,是的,我是这么想的,但是,写reg的函数:void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)里,先写reg的ID,然后怎么是 LCD->LCD_RAM = LCD_RegValue;这不是给RAM赋值了吗?,LCD->RAM地址为0x6c000001,这时A0脚变为1,选中了LCD的RAM啊,是给RAM里赋值了啊,怎么回实现写reg呢?

使用特权

评论回复
5
在水一飞|  楼主 | 2009-1-7 13:14 | 只看该作者

回复

A0为0时传输的是地址,为1时,传输的数据  ?
根据LCD应用笔记里的电路图,STM32的FSMC的A0引脚是接在 LCD_ILI9320的RS管脚上啊,RS接H电平时访问reg;接L电平时访问RAM,A0为1时,即RS脚H电平,LCD_ILI9320认为要进行RAM访问,不是往reg里写数据啊

使用特权

评论回复
6
zyok| | 2009-1-7 22:33 | 只看该作者

给你奖励,以后继续努力,呵呵~

使用特权

评论回复
7
在水一飞|  楼主 | 2009-1-8 09:10 | 只看该作者

回复

底层每个函数是要实现什么功能的我清楚,毕竟,我以前用PIC写过LCD屏的驱动程序。我想讨论的是函数工作的实现过程,STM32的FSMC控制LCD的原理和过程。
写RAM用函数:
void LCD_WriteRAM_Prepare(void)
{
  LCD->LCD_REG = R34;
}

void LCD_WriteRAM(u16 RGB_Code)
{
  LCD->LCD_RAM = RGB_Code;
}
写REG用函数:
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{
  LCD->LCD_REG = LCD_Reg;
  LCD->LCD_RAM = LCD_RegValue;
}
两赋值语句放在一个 和放在两含函数里,在FSMC控制LCD时,有什么不同呢?



使用特权

评论回复
8
alien2006| | 2009-1-8 10:43 | 只看该作者

呵呵上个礼拜正好也在学习用FSMC控制LCD,正好一起学习

    11楼的问题,按我的理解,当写控制寄存器数值为R34的时候,就告诉ILI9320,我接下来准备是大批量的数据传输是直接依次写到控制器显存里面的,而不是void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)这样是写内容到指定地址的控制寄存器上。不知道这样理解对否,具体这些都是要参考ILI9320控制器的功能定义来操作了

使用特权

评论回复
9
kgp0213| | 2009-1-8 10:48 | 只看该作者

来,给你一个专业的解释

看得出,你原来用pic写lcd的驱动也是2把刀^o^
请看注释:
void LCD_WriteRAM_Prepare(void)  //向lcd控制器送指令,选中r32寄存器
{    //为什么要选中r32?你若这样问的话那么你肯定没有看lcd控制器的spec
    //告诉你,选中R32后即意味着mcu通知lcd控制器:接下来的数据要送
   //到显示ram啦,此后mcu通过“LCD_WriteRAM”源源不断丢过来  的显示数据就会被送到RAM了
  LCD->LCD_REG = R34;
}

void LCD_WriteRAM(u16 RGB_Code)
{
  LCD->LCD_RAM = RGB_Code;
}
写REG用函数:
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{
  LCD->LCD_REG = LCD_Reg;
  LCD->LCD_RAM = LCD_RegValue;
}
两赋值语句放在一个 和放在两含函数里,在FSMC控制LCD时,有什么不同呢?
对呀,有什么不同,从功能上来说没有什么不同。但为什么要多此一举多写了一个函数呢?
纯粹速度上的考虑而已.....
还不明白?
再说细一点:
lcd要显示图像出来,则需要mcu开始的时候通过LCD_WriteReg对lcd控制器进行初始化,初始化之后lcd控制器就会把其内部ram中的数据自动显示于lcd上。我们要在lcd显示图像文字的话,只要改变其内部ram值就可以了,而r32寄存器就是指向了lcd控制器的ram的,后面再(LCD_WriteRAM)跟过来的数据的话就会直接被打入lcd控制器的ram,从以上说明可知上述过程可以通过LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)来完成,但是每次都要执行一次“LCD->LCD_REG = LCD_Reg”,累啊
所以多写一个函数,节省了n个“LCD->LCD_REG = LCD_Reg”,多划算啊.....
..
...

 

使用特权

评论回复
10
alien2006| | 2009-1-8 10:55 | 只看该作者

另外我也有个问题

上个礼拜试验FSMC来控制一块液晶,也是8080 8位并行接口的,之前用GPIO方式来驱动都成功了,不过FSMC方式一直没成功。
    我用的是STM32F103VET6的芯片,跟ZE的芯片不同,VE的芯片只有NE1和A16~A23的引脚可用,因此我按照AN2790 TFT LCD (thin-film-transistor liquid crystal display) interfacing with FSMC的资料第13页那张图连接NE1到CS,A16到RS,区别与评估版上NE4到CS,A0到RS,我的相应寄存器的地址修改成
//LCD的命令寄存器
#define LCD_REG    (*(u16*)((u32)0x60000000))
//LCD的数据寄存器
#define LCD_RAM    (*(u16*)((u32)0x60020000))
    不知道对否?

使用特权

评论回复
11
kgp0213| | 2009-1-8 11:01 | 只看该作者

回12楼

修正一下:当写控制寄存器数值为R34的时候,就告诉ILI9320,我接下来准备是(显示数据,无论多少)的数据传输。
传输的数据将会被lcd控制器依次写到控制器显存里面的。
通过 LCD_WriteReg(0x32,0x显示数据)这样写也是可以的。只不过每次都要写一次0x32太麻烦了而已

其实无论对lcd的初始化还是对lcd送显示数据都是向lcd控制器的特定寄存器写入数据而已,只是不同的寄存器对应不同的功能。
有的寄存器对应到lcd 控制器的DA电路,有的则对应到ram...

使用特权

评论回复
12
kgp0213| | 2009-1-8 11:43 | 只看该作者

回5楼,请略过6、7楼

每种的lcd driver都是不一样的,基本的操作也是不同的。
从lz的发言来看,lz之前写的lcd驱动应该是黑白的。
黑白的lcd driver内置的reg比较少,所以直接使rs=0,通过一条指令即可完成reg的设置。
但对于彩色或tft的lcd driver(黑白的也有,数量极少)来说,reg较多,rs=0是的reg的赋值类似于门牌号,只是决定选择具体的reg而已,但是reg的值也就是具体门里面放什么东西要由后续rs=1时传递过来的数据来决定。这点与计算机系统的memory相似,memory的地址和该地址对应的数据可是两回事啊。

楼主好好看看lcd driver 的spec吧,不要想当然了
 ps,6楼 的 amingriyue 兄弟难道没看出lz根本没理解9320的基本操作吗?

 

使用特权

评论回复
13
kgp0213| | 2009-1-8 11:43 | 只看该作者

可以结贴了

使用特权

评论回复
14
在水一飞|  楼主 | 2009-1-8 14:29 | 只看该作者

回复

感谢16楼,确实,我以前写的是黑白屏.我一直按黑白屏的资料在考虑RS脚与FSMC的AO脚的问题。再次感谢!!!

使用特权

评论回复
15
在水一飞|  楼主 | 2009-1-8 14:43 | 只看该作者

补充一句

16楼主,如果是黑白屏,RS=0,先送REG的8位ID,再送REG需要的数据,用FSMC这种方法,岂不不能控制?

使用特权

评论回复
16
kgp0213| | 2009-1-9 08:20 | 只看该作者

回 19楼

如果是黑白屏,RS=0,先送REG的8位ID,再送REG需要的数据,用FSMC这种方法,岂不不能控制?
 
没看懂你的意思,或许你的理解与我的偏差太大。黑白屏的话只要rs=0时给lcd控制器送数据就可以设定寄存器的值了,不需要再送什么数据了,否则之前的数据会被冲掉。

使用特权

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

本版积分规则

3

主题

19

帖子

0

粉丝