对FSMC驱动LCD的一点小见解

2019-07-21 05:58发布

本帖最后由 xcc521 于 2019-1-14 16:14 编辑

经过一段时间的狂看屏幕驱动代码了解了一下FSMC大概明白了就是FSMC操作的是地址和数据,数据是16位的,但是我们也可以只用到其中的一部分,比如说8位数据,这就相当于我们直接一排端口同时输出数据或者读入数据,说到这想起来之前接手的个板子,8位的数据线不是连续的就算了,竟然还不在同一IO组,最后优化尽了程序用寄存器直接读入组合成数据也还是比较慢,所以这就是连续性的好处,可以很快的一次性读入或者写数据,既然数据的操作是控制高低电平输入和读入高低电平,那地址的也是,举个例子,一个8X8的点阵屏,我们每写的一行8位就是数据,而其中哪一列被选中就是这个选中有效了(是高电平或者低电平有效),那么如果我们想给屏幕写个指令就是首先选中命令,也就是那个接地址的线为0就是低电平,然后数据口发出来数据,如果写的数据,相同的步骤,这次那个地址线给高电平就行了,这么看来还是那些数据口,只不过是FSMC的其中一个地址线帮我们控制了到底写的是指令还是数据,也就是取决于这根地址线的电平,那么怎么控制这个地址线的高低电平呢?138来说吧,译码器,就是帮我们选地址线的,通常它用来位选,也就是具体哪一个有效,为什么用它,因为不然的话我们就要自己用那么多IO口了,而且选择变化的时候,还要咱们自己组织好电平,只有哪一个是有效电平,还要列表查询,还要一个个管脚的设置比较麻烦,所以才用它,那么你看它工作的结果,就是需要选择哪一行有效就输出低电平,比如第一个脚,咱们选中1的时候它就是低电平,反之选中其他的就是不选1,那么其他的就都可能为低电平,但就是1这个为高电平,所以现在看来就是选1这个地址和不选1这个地址就可以控制这个地址线的电平了,那在FSMC上呢?一样的,比如说A0,就是最最低位那个地址线,比如我们选地址是1,那么最低的位就有效了,它就是低电平,如果不选1呢,比如2或者4或者8,那么是不是A1A2A3就是低电平了,如果我们屏幕这个就是接的A0,那地址只要是1,2就可以控制写入的是命令还是数据了,因为选1地址,A0是低电平,A1A2,。。。等等都是高电平,如果选2,那A0是高电平,这就是我们想要的结果,A1是低电平,我们没接这里不用管,A2A3。。。等等这些更不用管,所以就是通过改变了地址来改变了高低电平,如果我们接在这里,就可以通过不同的地址来写命令或者数据了。这里只是简单的分析了解一下大概的工作原理,实际上要稍微复杂一点点,比如16个数据位的时候要左移一位对齐,再加上我们用的这块管理片的内存基地址等等,还要再考虑时序是要多快的等等,这就是这段时间思考的一点点结果开始验证便是在数个月前,但是尝试都失败了,2019,01,11今天又尝试了一下,开始依然是失败的,然后我尝试把寄存器的地址打印出来看看就是这里 //LCD地址结构体typedef struct{      vu16 LCD_REG;      vu16 LCD_RAM;} LCD_TypeDef;//使用NOR/SRAM Bank1.sector4,地址位HADDR[27,26]=11 A10作为数据命令区分线//注意设置时STM32内部会右移一位对其!                  #define LCD_BASE       ((u32)(0x6C000000 | 0x000007FE))#define LCD            ((LCD_TypeDef *) LCD_BASE)我做了这么一件事Printf(“LCD_REG:0x%08X ”,(int)(&(LCD->LCD_REG)));Printf(“LCD_RAM:0x%08X ”,(int)(&(LCD->LCD_RAM)));得到的结果是:LCD_REG:0x6C0007FELCD_RAM:0x6C000800验证之前觉得它俩一个是0X6C000000,一个是0X6C0007FE这也就是一直觉得的地址设不设置就是和A10的偏移量0x7FE有关系,现在看来这是不是对的然后发现了这点就改吧#define FSMC_LCD_CMD                  ((uint32_t)0x6C0007FE)         // LCD命令操作的地址#define FSMC_LCD_DATA                 ((uint32_t)0x6C000800)      // LCD数据操作的地址      #define LCD_WRITE_CMD(x)              *(__IO uint16_t *)FSMC_LCD_CMD  =x #define LCD_WRITE_DATA(x)             *(__IO uint16_t *)FSMC_LCD_DATA = x#define LCD_READ_DATA()               *(__IO uint16_t *)FSMC_LCD_DATA数据读写好了,其他的再修改一下接口,然后试了一下刷屏程序可以的,起码不像之前那样背光点亮之后不是白屏就是灰彩 {MOD}一样没有动静,然后接着显示图形文字也都是可以的,很是开心总算是对FSMC了解点了,再仔细看一下地址0x6C0007FE 0x6C000800好像,好像命令选了好多根地址线,你看数据就只有0800一根线,嗯,要不试一下0X6C000700,欸,好像屏幕也可以正常驱动欸,嗯,图形文字也可以哦对,700也是三位有效选中地址,那试试0x6C000400,哇居然也可以哎,神奇了再想想,是不是0800只选中了00001000   0000000010位地址,那是不是只要第10位不是选中都可以呢,比如0200,0300,我们分别来试一下果然,真的都可以哎,那说明我们之前的推断是对的,真的就是只要哪一个位有不有效就可以了,其他的那16个数据线,NOENEW什么的都是固定的,我们不用管,只用管我们接的哪一个地址线就行了,还有用的哪一个大块,也就是NE1还是NE2,或者NE3NE4.当然了,我们用到的地址线选好,不用时最好都选其他的一个没用的地址线,比如还有其他器件接了那个地址线,那么我们不用时再写数据,它也会跟着选中写进来东西就会有干扰,当然一般我们用不了那么多线,但是最好还是要注意一下关于FSMC控制屏幕大概就这些要说的,再配上一个例程,大家也理解一下,在此都是本人一点点小见解,还望大家多多指导
说明一下为了简化,把程序做的只能驱动NT35510的4.3寸电容屏了,大伙可以看着再把需要的加回来
FSMC_LCD.zip (1.39 MB, 下载次数: 7) 2019-1-11 23:57 上传 点击文件名下载附件
程序



0条回答

一周热门 更多>