在stm32f407 fsmc 速度 fsmc中把数据写到0x6000 0000之后数据是给谁了

查看: 3351|回复: 38
讲fsmc的非常好,贴出来给大家分享
主题帖子精华
新手上路, 积分 9, 距离下一级还需 41 积分
在线时间52 小时
这个是从网上找到的,内容如下:
STM32 FMSC&&LCD难点解析:
以下是网上和自己整理的:感觉应该可以把STM32 ----FSMC LCD中的关键RS说清楚~
----------------------------------------------------------------------------------------------------------------------
第一个角度理解STM32有FSMC(其实其他芯片基本都有类似的总线功能),FSMC的好处就是你一旦设置好之后,WR(写)、RD(读)、DB0-DB15这些控制线和数据线,
都是FSMC自动控制的。打个比方,当你在程序中写到:
*(volatile unsigned short int *)(0x)=
那么FSMC就会自动执行一个写的操作,其对应的主控芯片的WE、RD这些脚,就会呈现出写的时序出来(即WE=0,RD=1),数据val的值也
会通过DB0-15自动呈现出来(即FSMC-D0:FSMC-D15=val&&)。地址0x会被呈现在数据线上(即A0-A25=0,地址线的对应最麻烦,要根据具体情况来,好好看看FSMC手册)。
那么在硬件上面,我们需要做的,仅仅是MCU和LCD控制芯片的连接关系:
WE-WR,均为低电平有效
RD-RD,均为低电平有效
FSMC-D0-15接LCD DB0-15
FSMC_NE1--CS接PD7
连接好之后,读写时序都会被FSMC自动完成。但是还有一个很关键的问题,就是RS没有接因为在FSMC里面,根本就没有对应RS。怎么办呢?这个时候,有一个好方法,就是用某一根地址线来接RS。比如我们选择了A16这根地址线来接,那么当我们要写寄
存器的时候,我们需要RS,也就是A16(RS为高)置高。软件中怎么做呢?也就是将FSMC要写的地址改成0x,如下:
*(volatile unsigned short int *)(0x)=
这个时候,A16在执行其他FSMC的同时会被拉高,因为A0-A18要呈现出地址0x。0x里面的Bit17=1,就会导致A16为1。
当要读数据时,地址由0x改为了0x,这个时候A16就为0了。
那么有朋友就会有疑问,第一,为什么地址是0x6xxxxxxx而不是0x0xxxxxxx;第二,CS怎么接;第三,为什么Bit17对应A16?
RS问题:RS为0表示;读写寄存器;RS为1,读写数据RAM;
先来看前两个问题,大家找到STM32的FSMC手册,在FSMC手册里面,我们很容易找到,FSMC将0xx6fffffff的地址用作NOR/PRAM(
共256M地址范围)。而这个存储块,又被分成了四部分,每部分64M地址范围。当对其中某个存储块进行读写时,对应的NEx就会置低。这里,
就解决了我们两个问题,第一,LCD的操作时序,和NOR/PRAM是一样的(为什么一样自己找找NOR/PRAM的时序看看),所以我们选择0x6xxxxxxx
这个地址范围(选择这个地址范围,操作这个地址时,FSMC就会呈现出NOR/PRAM的时序)。第二,我们可以将NEx连接到LCD的CS,只要我们操作
的地址是第一个存储块内即可(即0-0x3ffffff地址范围)。&
第三个问题再来看一看FSMC手册关于存储器字宽的描述,我们发现,当外部存储器是16位时,硬件管脚A0-A24表示的是地址线A1-A25的值,所以
我们要位移一下,Bit17的值,实际会被反应到A16这根IO来。关于数据宽度及位移的问题,初学的朋友可能会比较疑惑,当你接触了多NOR/PRAM
这样的器件后,你会发现,很多芯片的总线,都是这样设计的,为的是节省地址线。
第二个角度理解:
FSMC总线上看,LCD只有2个地址.
Bank1_LCD_C是写寄存器,此时RS=1,告诉LCD我在总线上输出数据的是寄存器的地址
Bank1_LCD_D是写数据,此时RS=0,告诉LCD我在总线上输出地数据是寄存器的数据或者GRAM的数据.
写寄存器数据按2步来:
第一步先往Bank1_LCD_C (对应RS=1),送寄存器的地址:*(__IO uint16_t *) (Bank1_LCD_C)=&&接着在Bank1_LCD_D这个地址(对应RS=0),写入刚指向的寄存器的数据: *(__IO uint16_t *) (Bank1_LCD_D)=
为什么*(__IO uint16_t *) (Bank1_LCD_C)=&就是往&LCD&写寄存器呢?
这是一个16位的IO赋值操作,地址是Bank1_LCD_C,这个地址就是指向FSMC的&Bank1的NE1对应的地址空间。而LCD片选正是连接到NE1,具体地址要看RS接到哪一根地址线上。当CPU执行到这一条的时候,就会通过FSMC总线控制器在数据总线上进行一个地址为&Bank1_LCD_C的数据写操作,此操作自动完成CS信号,
RD信号,WR信号,以及地址总线数据(RS信号)的输出以及数据总线数据的输出.
其他的操作都是这两个操作组合完成。也就是我上面所说的,
"所有的寄存器地址和寄存器数据,以及&GRAM数据都是通过&IO0-IO15完成传输的,而不是FSMC的地址.这是容易搞混的一个地方.LCD的FSMC地址只有一根&,就是RS."
----------------------------------------------------------------------------------------------------------------------第三个角度理解:
把TFT看做类似SRAM的存储器,只能接在&BANK1上。对应基地址是0x.
而BANK1又有划分为四个片选,分别对应基地址:
NE4 0x6C0000000
所以每个NEx能寻址的空间大小为64M,也就是对应了FSMC的A0到A25&共26根地址线.
假如使用NE4接到为LCD的片选CS上,那么就对应基地址&0x6C000000,
如果RS接到地址线的&A0上,那么当&RS为0时对应的地址就是&LCD_REG = 0x6C000000,(其实你用0x6CFFFFF0是一样的,因为只用到一根地址线).
RS为1时对应的地址就是&LCD_RAM =0x6Cx6CFFFFF1一样对应&LCD_RAM,因为它一样对应&RS=1).
如果&RS接到&其他地址线上,情况是类似的。
比如接到&An上,那么
LCD_REG= 0x6C000000,
LCD_RAM= 0x6C000000 | (1&&n)
注意这个地址不是唯一的,只要这个地址能寻址到&BANK1&的&NE4上而且使&RS=0,那么就是&LCD_REG,使&RS=1,就是LCD_RAM.
----------------------------------------------------------------------------------------------------------------------
对应Bank1_LCD_C&的地址,FSMC总线控制器在RS接的那根地址线输出的是&1,而对应Bank1_LCD_D,输出的0.
RS接的可不是GPIO,是FSMC地址总线的一根.FSMC进行读写操作的时候会在地址总线根据要读写的地址输出电平的.
RS接哪一根地址线虽然没有固定要求,但是一旦你确定要接哪一根,那么Bank_LCD_C和Bank_LCD_D也要随之确定,这可不是“自动的".
虽然没有手动操作GPIO来操作RS,但是你敲代码的时候可是手动指定&Bank1_LCD_C&或者&Bank1_LCD_D&,从而确定&RS的电平.
所谓的“自动”是指:不是通过操作GPIO来操作RS,而是直接根据地址总线地址的不同来完成操作RS,这两种方法的速度差别是非常大的.
如果是GPIO方式,先要通过操作GPIO&分别&输出&RS,CS,等的电平,然后再通过过GPIO操作输出数据,然后还要通过GPIO&再操作RD,WR,CS等的电平。
每操作一个GPIO都要好几个周期,加起来就非常慢了.
而FSMC是在一个FSMC写周期内就完成了这所有的动作。
*******************************************************************************
#define Bank1_LCD_R&&&&((uint32_t)0x)&&&&//disp Reg ADDR
#define Bank1_LCD_D&&&&((uint32_t)0x)&&&//disp Data ADDR
从STM32 FMSC系统手册可以看到:
FSMC其实就相当于外部总线存储器和内部AHB总线的接口:而AHB是32位的,当外接NOR/LCD&时,而外部存储器的数据宽度可以选择8位和16位的,这时候就存在一个地址转换的问题即32位和8位或者16位地址转换的问题。解决这个问题STM32采用的HADDR[25:0],它的作用就是将外部存储器地址转换为AHB地址线。
&并且无论外部存储器的宽度是多少位,FSMC_A[0]始终连接到外部存储器的A[0];
NOR闪存/LCD
&&&&&&&&&&&&&
FSMC核心控制器
(这里就只介绍使用BANK1的块1:这个块1的起始地址为0x)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&FS&&FSMC_NOE(输出使能)
AHB总线&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&FSMC_NE1(片选)
FSMC_NWE(写使能)
①HADDR[25:0]总共26位线,可以寻址64M的地址空间,而AHB总线是32位宽度,所以能寻址0xxFFFF FFFF;在这里我们只是指定了FMSC控制器块1的地址为0x。寻址空间0x ~0x63ff&&
②LCD&手册相关知识:(9320或者hx8312都一样)
RS引脚决定是寄存器命令还是显示RAM数据。寄存器指令的输入数据是16位,前8位是地址,后8位是数据。
不同的MPU类型寄存器命令和数据总线的格式不同。并且对应输入总线:有一下对应关系:
对于SPI方式,则用以下对应关系:
(2)显示RAM数据格式和系统接口输入总线之间的联系
问题:RS如何选择:&
#define Bank1_LCD_R&&&&((uint32_t)0x)&&&&//disp Reg ADDR
#define Bank1_LCD_D&&&&((uint32_t)0x)&&&//disp Data ADDR
这里LCD选取的16位,将RS接在A16,则HADDR[25:1]对应FSMC_A[24:0];关键在于为什么???
从上面可以看出,LCD除了需要数据线之外,额外的地址线是不需要的~~~~~但是在STM32在进行FSMC总线操作时,所有的地址线还是会出现时序的,但是操纵LCD&不需要额外的地址线了,也就是FSMC_A[16:25]可以解放了,但是要注意一旦配置了FSMC,这些管脚还是会出现时序的;
现在我们向0x这个块地址送出数据,当然这些数据肯定是16位的,因为是16位的LCD,由于RS(A16)为0,所以这个读写寄存器的操作;当向0x写数据时,由于总线时序是要有地址写的,这时bit17就为高了,也就是RS为1了,这时所进行的操作就是读写RAM了!!!!
其中RS的选择可以是任意的,但一般还是选择,不用的地址线为好~~~~~
原帖地址:.cn/s/blog_66ffe2770100wabh.html
原子哥是不是又要出黑科技了呀。^_^...
主题帖子精华
在线时间324 小时
写的不错,谢谢分享。
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
中级会员, 积分 435, 距离下一级还需 65 积分
在线时间32 小时
感谢楼主分享!!!
互联网,智能设备爱好者,欢迎讨论任何有意思的想法。
主题帖子精华
在线时间121 小时
谢谢分享!!!
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
主题帖子精华
高级会员, 积分 818, 距离下一级还需 182 积分
在线时间36 小时
markmarkmark
主题帖子精华
中级会员, 积分 285, 距离下一级还需 215 积分
在线时间6 小时
看不明白,谢谢楼主分享,楼主辛苦勒
主题帖子精华
中级会员, 积分 236, 距离下一级还需 264 积分
在线时间17 小时
写的很好嘛,不错。
主题帖子精华
中级会员, 积分 236, 距离下一级还需 264 积分
在线时间17 小时
&因为A0-A18要呈现出地址0xx里面的Bit17=1,就会导致A16为1。
当要读数据时,地址由0x改为了0x,这个时候A16就为0了。
如果RS接到地址线的 A0上,那么当 RS为0时对应的地址就是 LCD_REG = 0x6C000000,(其实你用0x6CFFFFF0是一样的,因为只用到一根地址线).
RS为1时对应的地址就是 LCD_RAM =0x6Cx6CFFFFF1一样对应 LCD_RAM,因为它一样对应 RS=1).
当外部存储器是16位时,硬件管脚A0-A24表示的是地址线A1-A25的值
有点疑问啊,按理说向右移动一位,那么RS接到地址线A0上的时候,RS=1对应的地址线不是LCD_RAM =0x6C000002吗??
主题帖子精华
初级会员, 积分 133, 距离下一级还需 67 积分
在线时间0 小时
很棒啊,帮顶...
行善,持咒
主题帖子精华
中级会员, 积分 252, 距离下一级还需 248 积分
在线时间3 小时
赶紧来学习!
主题帖子精华
中级会员, 积分 236, 距离下一级还需 264 积分
在线时间17 小时
明白了,我理解错了。
主题帖子精华
新手上路, 积分 21, 距离下一级还需 29 积分
在线时间0 小时
哪NE1的基础上再加上NE4,需要加什么配置命令行?
主题帖子精华
中级会员, 积分 480, 距离下一级还需 20 积分
在线时间24 小时
mark,谢谢楼主!!!!!!!!!!
主题帖子精华
初级会员, 积分 71, 距离下一级还需 129 积分
在线时间0 小时
RS问题:RS为0表示;读写寄存器;RS为1,读写数据RAM;
第二个角度理解:
FSMC总线上看,LCD只有2个地址.
Bank1_LCD_C是写寄存器,此时RS=1,告诉LCD我在总线上输出数据的是寄存器的地址
Bank1_LCD_D是写数据,此时RS=0,告诉LCD我在总线上输出地数据是寄存器的数据或者GRAM的数据.
楼主原话,自相矛盾!
主题帖子精华
初级会员, 积分 71, 距离下一级还需 129 积分
在线时间0 小时
看了好几遍,整体上还是对的哈!挺好的。
主题帖子精华
中级会员, 积分 286, 距离下一级还需 214 积分
在线时间0 小时
主题帖子精华
初级会员, 积分 53, 距离下一级还需 147 积分
在线时间2 小时
你好,我想请问下一个问题,可能比较白痴,但还是要问出来,憋着难受。。
就是我不清楚地址线跟数据线之间的关系,LCD是在地址线A10上进行读写,是因为A10连接着RS,用于判断是写命令还是写数据,那当命令或数据写入时,D0~D15的状态是什么呢?是写入数据对应的状态吗?
主要就是不知道D0~D15与地址线的关系,是不是往地址线上写数据,数据就会反映在数据线上吗?
本人愚钝,求各位解答,谢谢!!
最好举个例子,让我理解下,万分感激!!
&//写寄存器函数
//regval:寄存器值
void&LCD_WR_REG(u16&regval)
{&
LCD-&LCD_REG=//写入要写的寄存器序号 &
}
//写LCD数据
//data:要写入的值
void&LCD_WR_DATA(u16&data)
{
LCD-&LCD_RAM=
&
}
如果这里的data=0x50,那么在D0到D15上是什么??
主题帖子精华
在线时间324 小时
回复【17楼】你干嘛:
---------------------------------
此时D15:D0&为:&01&0000
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
初级会员, 积分 53, 距离下一级还需 147 积分
在线时间2 小时
回复【18楼】正点原子:
---------------------------------
哦哦,也就是说,regval或者data为何值,那么D0~D15就为何值,其实也就是往一个地址,写一个数据,恰好的是此时的地址的A10控制着RS,数据位D0~D15也就是数据,可以这样理解吗??
谢谢原子哥,他们都这么叫,跟着叫好了。
//写寄存器函数&
//regval:寄存器值&
void&LCD_WR_REG(u16&regval)&
{&&
LCD-&LCD_REG=//写入要写的寄存器序号 &&
}&
//写LCD数据&
//data:要写入的值&
void&LCD_WR_DATA(u16&data)&
{ &&&& &&&&
LCD-&LCD_RAM= &&
}
主题帖子精华
在线时间324 小时
回复【19楼】你干嘛:
---------------------------------
是的
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
初级会员, 积分 91, 距离下一级还需 109 积分
在线时间0 小时
回复【8楼】apple:
---------------------------------
这是左移一位,我也很纳闷
主题帖子精华
初级会员, 积分 91, 距离下一级还需 109 积分
在线时间0 小时
回复【14楼】wymbsmmh:
---------------------------------
恩,很矛盾
主题帖子精华
新手上路, 积分 33, 距离下一级还需 17 积分
在线时间1 小时
这篇关于FSMC的文章,写得不错,建议不懂FSMC的技术猿可以学一下
主题帖子精华
中级会员, 积分 415, 距离下一级还需 85 积分
在线时间18 小时
谢谢分享!!!
主题帖子精华
在线时间372 小时
fsmc,写的很好,感谢楼主
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
主题帖子精华
新手上路, 积分 9, 距离下一级还需 41 积分
在线时间52 小时
回复【25楼】龙之谷:
---------------------------------
不是我写的啊,我只是复制过来给大家分享的。^_^
原子哥是不是又要出黑科技了呀。^_^...
主题帖子精华
在线时间372 小时
回复【26楼】fanghuiopenedv:
---------------------------------
明白,你楼主位已经注明了,回复的时候一时想不出什么词来表达,刚想了一下,还是词穷,将就补充一下原话
fsmc,写的很好,感谢楼主copy
祝工作顺利
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
主题帖子精华
新手上路, 积分 24, 距离下一级还需 26 积分
在线时间0 小时
主题帖子精华
初级会员, 积分 82, 距离下一级还需 118 积分
在线时间1 小时
FSMC存储控制器(mark)
主题帖子精华
在线时间111 小时
RS是什么?
主题帖子精华
新手上路, 积分 9, 距离下一级还需 41 积分
在线时间52 小时
回复【30楼】jiutianshenjian:
---------------------------------
RS应该是和51单片机的ALE差不多的功能。
原子哥是不是又要出黑科技了呀。^_^...
主题帖子精华
在线时间111 小时
回复【31楼】fanghuiopenedv:
---------------------------------
51没搞过。
我这里有个T6963c的芯片,
我看和这个功能一样,不过是相反的貌似。这个C/D连的FSMC的A18.
C/D#&&&WR#&=&L,C/D#&=&H&时,写命令;C/D#&=&L&时,写数据;&
&&&&&&&&&&&&RD#&=&L,C/D#&=&H&时,读命令;C/D#&=&L&时,读数据;&
然后地址怎么算。FSMC_Bank1_NORSRAM3起始地址0x,这个命令地址该是多少。
写命令对应写寄存器吧,高低电平不是反的吗?
主题帖子精华
新手上路, 积分 9, 距离下一级还需 41 积分
在线时间52 小时
回复【32楼】jiutianshenjian:
---------------------------------
写驱动的话要结合着硬件连接来写的。你要看下连接到那个管脚了,然后在写驱动。这个我转载的帖子应该可以帮到你的。你好好研究下吧。
原子哥是不是又要出黑科技了呀。^_^...
主题帖子精华
在线时间111 小时
回复【33楼】fanghuiopenedv:
---------------------------------
看了好久了,还是搞不懂这点东西。。。
主题帖子精华
初级会员, 积分 114, 距离下一级还需 86 积分
在线时间9 小时
很好的帖子,对于理解FSMC确实有用
主题帖子精华
金牌会员, 积分 1336, 距离下一级还需 1664 积分
在线时间194 小时
标记一下,慢慢学习
我有故事,你有酒吗
主题帖子精华
新手上路, 积分 26, 距离下一级还需 24 积分
在线时间7 小时
感谢分享!!
主题帖子精华
中级会员, 积分 208, 距离下一级还需 292 积分
在线时间18 小时
为什么上面的图片显示不出来
主题帖子精华
新手上路, 积分 9, 距离下一级还需 41 积分
在线时间52 小时
为什么上面的图片显示不出来
你可以去看原帖地址的呀。
原子哥是不是又要出黑科技了呀。^_^...
Powered by文章 - 1&评论 - 7&trackbacks - 0
FSMC全称&静态存储器控制器&。
使用FSMC控制器后,可以把FSMC提供的FSMC_A[25:0]作为地址线,而把FSMC提供的FSMC_D[15:0]作为数据总线。
(1)当存储数据设为8位时,(FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b)
&&& 地址各位对应FSMC_A[25:0],数据位对应FSMC_D[7:0]
(2)当存储数据设为16位时,(FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b)
&&& 地址各位对应FSMC_A[24:0],数据位对应FSMC_D[15:0]
FSMC 包括4个模块:
(1)AHB接口(包括FSMC配置寄存器)
(2)NOR闪存和PSRAM控制器(驱动LCD的时候LCD就好像一个PSRAM的里面只有2个16位的存储空间,一个是DATA RAM 一个是CMD RAM)
(3)NAND闪存和PC卡控制器
(4)外部设备接口
注:FSMC可以请求AHB进行数据宽度的操作。如果AHB操作的数据宽度大于外部设备(NOR或NAND或LCD)的宽度,此时FSMC将AHB操作分割成几个连续的较小的数据宽度,以适应外部设备的数据宽度。
FSMC对外部设备的地址映像从0x开始,到0x9FFF FFFF结束,共分4个地址块,每个地址块256M字节。可以看出,每个地址块又分为4个分地址块,大小64M。对NOR的地址映像来说,我们可以通过选择HADDR[27:26]来确定当前使用的是哪个64M的分地址块,如下页表格。而这四个分存储块的片选,则使用NE[4:1]来选择。数据线/地址线/控制线是共享的。
NE1&-&Bank1&& NE2-&Bank2& NE3-&Bank3& NE4-&Bank4
若&NE1 连接, 则
每小块NOR/PSRAM 64M
&第一块:h--63ff ffffh&(DATA长度为8位情况下,由地址线FSMC_A[25:0]决定;DATA长度为16位情况下,由地址线FSMC_A[24:0]决定)
&第二块:h--67ff ffffh
&第二块:h--6bff ffffh
&第三块:6c00 0000h--6fff ffffh
注:这里的HADDR是需要转换到外部设备的内部AHB地址线,每个地址对应一个字节单元。因此,若外部设备的地址宽度是8位的,则HADDR[25:0]与STM32的CPU引脚FSMC_A[25:0]一一对应,最大可以访问64M字节的空间。若外部设备的地址宽度是16位的,则是HADDR[25:1]与STM32的CPU引脚FSMC_A[24:0]一一对应。在应用的时候,可以将FSMC_A总线连接到存储器或其他外设的地址总线引脚上。
例:STM32F10XX FCMS控制LCD的驱动
&FSMC提供了所有的LCD控制器的信号:FSMC_D[16:0] ? 16bit的数据总线FSMC NEx:分配给NOR的256M,再分为4个区,每个区用来分配一个外设,这四个外设的片选分为是NE1-NE4,对应的引脚为:PD7&NE1,PG9&NE2,PG10-NE3,PG12&NE4FSMC NOE:输出使能,连接LCD的RD脚。FSMC NWE:写使能,连接LCD的RW脚。FSMC Ax:用在LCD显示RAM和寄存器之间进行选择的地址线,即该线用于选择LCD的RS脚,该线可用地址线的任意一根线,范围:FSMC_A[25:0]。注:RS = 0时,表示读写寄存器;RS = 1表示读写数据RAM。举例1:选择NOR的第一个存储区,并且使用FSMC_A16来控制LCD的RS引脚,则我们访问LCD显示RAM的基址为0x,访问LCD寄存器的地址为:0x。因为数据长度为16bit ,所以FSMC_A[24:0]对应HADDR[25:1]& 所以显示RAM的基址=0x^16*2=0xx2 20000举例2:选择NOR的第四个存储区,使用FSMC_A0控制LCD的RS脚,则访问LCD显示RAM的基址为0x6c00 0002,访问LCD寄存器的地址为:0x6c00 0000。
FSMC_D[15:0],连16bit数据线;FSMC_NE1,连片选:只有bank1可用FSMC NOE:输出使能FSMC NEW:FSMC写使能FSMC Ax:连接RS,可用范围FSMC_A[24:0]
一般使用模式B来做LCD的接口控制,不适用外扩模式。并且读写操作的时序一样。此种情况下,我们需要使用三个参数:ADDSET,DATAST,ADDHOLD。这三个参数在位域FSMC_TCRx中设置。当HCLK的频率是72MHZ,使用模式B,则有如下时序:地址建立时间:0x1地址保持时间:0x0数据建立时间:0x2注:这里地址建立 地址保持 数据建立三个时间不知道怎么设出来的。。。。。我是根据别人的经验来设定的。高手知道这个设置不同有什么区别的话,请指教,谢谢:)
/********************************************************************************
函数名: LCD_CtrlLinesConfig*
能: 配置LCD控制口线,FSMC管脚设置为复用功能*/static void LCD_CtrlLinesConfig(void){
GPIO_InitTypeDef GPIO_InitS
/* 使能 FSMC, GPIOD, GPIOE, GPIOF, GPIOG 和 AFIO 时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG |
RCC_APB2Periph_AFIO, ENABLE);
/* 设置 PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14),
PD.10(D15), PD.14(D0), PD.15(D1) 为复用推挽输出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
GPIO_Pin_15; // | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* 设置 PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10),
PE.14(D11), PE.15(D12) 为复用推挽输出 */
/* PE3,PE4 用于A19, A20, STM32F103ZE-EK(REV 2.0)必须使能 */
/* PE5,PE6 用于A19, A20, STM32F103ZE-EK(REV 2.0)必须使能 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* 设置 PF.00(A0 (RS))
为复用推挽输出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOF, &GPIO_InitStructure);
/* 设置 PG.12(NE4 (LCD/CS)) 为复用推挽输出 - CE3(LCD /CS) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_1);}
static void LCD_FSMCConfig(void){
FSMC_NORSRAMInitTypeDef
FSMC_NORSRAMInitS
FSMC_NORSRAMTimingInitTypeDef
FSMC_NORSRAMTimingInitS
/*-- FSMC Configuration ------------------------------------------------------*/
/*----------------------- SRAM Bank 4 ----------------------------------------*/
/* FSMC_Bank1_NORSRAM4 configuration */
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 1;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 2;
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_B;
/* Color LCD configuration ------------------------------------
LCD configured as follow:
- Data/Address MUX = Disable
- Memory Type = SRAM
- Data Width = 16bit
- Write Operation = Enable
- Extended Mode = Enable
- Asynchronous Wait = Disable */
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_D
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_D
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_L
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_D
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitS
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_E
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_D
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_D
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_D
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitS
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitS
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* - BANK 3 (of NOR/SRAM Bank 0~3) is enabled */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);}
小结:这里使用的地址映射属于BANK1 NOR/PSRAM1& 所以DATA数据基址为0x6c000000 又因为LCD的RS连接在FSMC_A0上 所以CMD地址为0x6c000002。配置好FSMC后,要写DATA或CMD时只要对这两个地址操作就可以了。
阅读(...) 评论()

我要回帖

更多关于 stm32f4 fsmc 的文章

 

随机推荐