工作中使用到100PIN的STM32和拓普微LM6029液晶模组,在需要读液晶内存的情况时,屏幕会出现麻点(即在文字周围随机的生成点),此问题苦恼了很久,降频,调整时序,改模拟总线,与同事前往拓普微公司都无法解决,而且也不是每块屏都会出现.
TODAY,问题终于得到解决,总结造成问题的原因:
1.由于此液晶模组属于黑白屏,其内部控制器不适合被高速的STM32所驱动,需要较大的降频与分频,以及时序也需要加大调整;
2.由于100PIN的STM32的A0~A15地址线是与D0~D15复用的,较常用的将A0作RS控制线的方法不可行,所以使用了模拟IO的方法来生成RS信号,所以造成了STM32的FSMC信号的不完整,而此前这种方法应用到TFT彩屏上是没有问题的,但在拓普微的屏上就反应出问题了.
解决方法:
step1.将MCU倍频降到40M,并修改FSMC的时序如下:
p.FSMC_AddressSetupTime = 5;
p.FSMC_AddressHoldTime = 5;
p.FSMC_DataSetupTime = 50;
p.FSMC_BusTurnAroundDuration = 16;
p.FSMC_CLKDivision = 16;
p.FSMC_DataLatency = 17;
p.FSMC_AccessMode = FSMC_AccessMode_A;
step2.用FSMC的A16地址线自动生成液晶模组所需的RS信号,即往A16的地址分别写入命令值或数据值,代码如下:
#define LCD_WR_REG(a) {(*((volatile unsigned char *) 0x60000000)) = (a);}
#define LCD_WR_RAM(a) {(*((volatile unsigned char *) 0x60010000)) = (a);}
u8 LCD_RD_RAM(void)
{
return (*((volatile unsigned char *) 0x60010000));
}
对比之前使用模拟RS信号的代码:
#define SET_RS GPIO_SetBits(GPIOD,GPIO_Pin_11);
#define CLR_RS GPIO_ResetBits(GPIOD,GPIO_Pin_11);
/* Note: LCD /CS is CE1 - Bank 4 of NOR/SRAM Bank 1~4 */
#define LCD_BASE ((u32)(0x60000000 | 0x0000000))
#define LCD ((LCD_TypeDef *) LCD_BASE)
#define LCD_WR_REG(a) {CLR_RS;LCD->LCD_REG = (a);}
#define LCD_WR_RAM(a) {SET_RS;LCD->LCD_RAM = (a);}
typedef struct
{
vu8 LCD_REG;
vu8 LCD_RAM;
} LCD_TypeDef;
u8 LCD_RD_RAM(void) {SET_RS;return LCD->LCD_RAM;}
附图,所使用到的拓模组:
4/29/2010更新: 以上都未真正解决问题,只是最大程度的降低了再现机率,但经过长时间验证,问题同样存在,真正解决问题的方法是弃用FSMC总线,用IO模拟并口,并在读数据前加入延时,底层代码如下:#define SET_RS() GPIOD->BSRR |= 0x00000800;#define CLR_RS() GPIOD->BSRR |= 0x08000000;#define SET_nRD() GPIOD->BSRR |= 0x00000010;#define CLR_nRD() GPIOD->BSRR |= 0x00100000;#define SET_nWR() GPIOD->BSRR |= 0x00000020;#define CLR_nWR() GPIOD->BSRR |= 0x00200000;#define SET_nCS() GPIOD->BSRR |= 0x00000080;#define CLR_nCS() GPIOD->BSRR |= 0x00800000;#define SET_nRST() GPIOD->BSRR |= 0x00001000;#define CLR_nRST() GPIOD->BSRR |= 0x10000000;#define set_lcdbus(data) {GPIOE->CRL = 0x33333333; GPIOE->BSRR = (data & 0xff) | (~data & 0xff)<<16;}u8 read_lcdbus(void){ u8 data=0; GPIOE->CRL = 0x44444444; //浮空输入 //GPIOE->CRL = 0x88888888; //x拉输入 //GPIOE->CRL = 0xcccccccc; //reserved for(u8 i=0;i<5;i++); data = GPIOE->IDR & 0xff; return data;}//--------指令代码写入函数------------------void LCD_WR_REG(u8 Command){ CLR_RS(); SET_nRD(); CLR_nCS(); set_lcdbus(Command); CLR_nWR(); SET_nWR(); SET_nCS();}//-----显示数据写入函数----------------------void LCD_WR_RAM(u8 DData){ SET_RS(); SET_nRD(); CLR_nCS(); set_lcdbus(DData); CLR_nWR(); SET_nWR(); SET_nCS();}//-------显示数据读取函数---------------------u8 LCD_RD_RAM(){ u8 DData; SET_RS(); SET_nWR(); CLR_nCS(); set_lcdbus(0xff); CLR_nRD(); DData=read_lcdbus(); SET_nRD(); SET_nCS(); return(DData); // 返回数据值} 总结原因,STM32太快了也不是好事(PLL降低倍频,FSMC增大分频也是同样效果),很多外设跟芯片走的不是一个发展步伐。
文章评论(0条评论)
登录后参与讨论