OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7012|回复: 4

对FSMC驱动LCD的一点小见解

[复制链接]

37

主题

477

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2285
金钱
2285
注册时间
2017-8-24
在线时间
375 小时
发表于 2019-1-12 00:01:55 | 显示全部楼层 |阅读模式
本帖最后由 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\r\n”,(int)(&(LCD->LCD_REG)));
Printf(“LCD_RAM:0x%08X\r\n”,(int)(&(LCD->LCD_RAM)));
得到的结果是:LCD_REG:0x6C0007FE
LCD_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
数据读写好了,其他的再修改一下接口,然后试了一下刷屏程序可以的,起码不像之前那样背光点亮之后不是白屏就是灰彩色一样没有动静,然后接着显示图形文字也都是可以的,很是开心总算是对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, 下载次数: 328)
IMG_20180922_181224.jpg
IMG_20180922_175405.jpg
天然懒,天然呆
能吃会睡,未来可期
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14424
金钱
14424
注册时间
2018-8-3
在线时间
1157 小时
发表于 2019-8-21 20:07:31 | 显示全部楼层
回复 支持 反对

使用道具 举报

5

主题

152

帖子

0

精华

高级会员

Rank: 4

积分
777
金钱
777
注册时间
2016-7-15
在线时间
119 小时
发表于 2021-2-24 14:45:12 | 显示全部楼层
有东西的
回复 支持 反对

使用道具 举报

16

主题

103

帖子

0

精华

高级会员

Rank: 4

积分
830
金钱
830
注册时间
2020-7-1
在线时间
110 小时
发表于 2021-9-15 16:11:15 | 显示全部楼层
我想用DMA 提高刷屏的速度 这个FSMC驱动LCD 能用DMA 嘛
刚跨过大门,入眼是海洋
回复 支持 反对

使用道具 举报

56

主题

343

帖子

0

精华

高级会员

Rank: 4

积分
977
金钱
977
注册时间
2016-3-8
在线时间
267 小时
发表于 2021-10-28 23:18:40 | 显示全部楼层
q879524825 发表于 2021-9-15 16:11
我想用DMA 提高刷屏的速度 这个FSMC驱动LCD 能用DMA 嘛

用DMA的M2M模式应该可以吧,DMA一次传1帧。就是有点废RAM。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 15:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表