STM32 FSMC学习笔记
时间:11-27
来源:互联网
点击:
FSMC全称“灵活静态存储器控制器”。
FSMC 包括4个模块:
![](../img/eep/emb/emb-61637pv0n5p3iqxp.jpg)
(1)AHB接口(包括FSMC配置寄存器)
(2)NOR闪存和PSRAM控制器(驱动LCD的时候LCD就好像一个PSRAM的里面只有2个16位的存储空间,一个是DATA RAM 一个是CMD RAM)
(3)NAND闪存和PC卡控制器
(4)外部设备接口
每个模块通过片选信号控制
--------------------------------------------------------------------------------------------------
硬件电路(这里给出的是非复用连接)
![](../img/eep/emb/emb-61638cpcvxzpqcxf.jpg)
可以这样接
地址线A0 接 RS
NE接 CS
NEW –WR
NOE –RD
FSMC与外设连接好以后,就等于对于使用者屏蔽了对外设备的具体操作,只要对应类型的映射地址空间写入数据,这些数据+地址就会被自动翻译,并写入外围存储设备。
对于写LCD来说,STM官方库里有一些常用写法:
#define LCD_BASE ((u32)(0x60000000 | 0x0C000000))//我解释一下,地址是BANK1 的 第四块
#define LCD ((LCD_TypeDef *) LCD_BASE)
void LCD_WriteReg(u8 LCD_Reg,u16 LCD_RegValue)
{
LCD->LCD_REG = LCD_Reg;
LCD->LCD_RAM = LCD_RegValue;
}
u16 LCD_ReadReg(u8 LCD_Reg)
{
LCD->LCD_REG = LCD_Reg;
return (LCD->LCD_RAM);
}
当然也可以自己操作,完全在于自己。
--------------------------------------------------------------------------------------------------
初始化问题:
1位宽:
主要是AHB到NOR/PSRAM位宽的,比如如果AHB设为32位,NOR为16位,他会分两次传输
![](../img/eep/emb/emb-616392fp3xzr5rn3.jpg)
2:设置地址
手册是这样写的:在NOR/PSRAM模式下HADDR[27:26](HADDR are internal AHB address lines that are translated to external memory)用来片选NOR/PSRAM的四个分区。A[25:0]是地址线,因为HADDR是字节地址但是存取其按字编址,所以根据位宽的不同由以下情况。
(1)当存储数据设为8位时, 地址各位对应FSMC_A[25:0],数据位对应FSMC_D[7:0](存储大小64MB * 8 = 512MB)
(2)当存储数据设为16位时, 地址各位对应FSMC_A[25:1]>>1(即FSMC_A[24:0]),数据位对应FSMC_D[15:0]
(存储大小 (64MB / 2) * 16 = 512MB)
注意:在16位外部存储宽度下,FSMC内部会用A[25:1]去生成A[24:0]。不论8位或16位的情况,FSMC_A[0]必需连接外部存储的A[0]。
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
FSMC的好处就是你一旦设置好之后,WR、RD、DB0-DB15这些控制线和数据线,都是FSMC自动控制的。打个比方,当你在程序中写到:
(volatile unsigned short int*)(0x60000000)=val;
那么FSMC就会自动执行一个写的操作,其对应的主控芯片的WE、RD这些脚,就会呈现出写的时序出来(即WE=0,RD=1),数据val的值也会通过 DB0-15自动呈现出来(即FSMC-D0:FSMC-D15=val)。地址0x60000000会被呈现在数据线上(即A0-A25=0,地址线的对应最麻烦,要根据具体情况来,好好看看FSMC手册)。
连接好之后,读写时序都会被FSMC自动完成。但是还有一个很关键的问题,就是RS没有接,CS没有接。因为在FSMC里面,根本就没有对应RS和CS的脚。怎么办呢?这个时候,有一个好方法,就是用某一根地址线来接RS。比如我们选择了A16这根地址线来接,那么当我们要写寄存器的时候,我们需要RS,也就是A16置高。软件中怎么做呢?也就是将FSMC要写的地址改成0x60020000,如下:
(volatile unsigned short int*)(0x60020000)=val;
这个时候,A16在执行其他FSMC的同时会被拉高,因为A0-A18要呈现出地址0x60020000。0x60020000里面的Bit17=1,就会导致A16为1。
当要读数据时,地址由0x60020000改为了0x60000000,这个时候A16就为0了。--------------------------------------------------------------------------------------------------
下来就是关于 FSCM时序问题,大家都有讨论:
一.当FSMC选择NOR和PSRAM模块时:
分为两种:1.异步事务2.同步突发事务
异步事务分为普通模式(mode 1,mode 2)和模式1与模式2的4种扩展模式(mode A,B,C,D);
二.General timing rules(通用时序规则):
1.All controller output signals change on the rising edge of the internal clock (HCLK)
(所有输出控制信号在内部时钟(HCLK)的上升沿改变)
2.In synchronous read and write mode, the output data changes on the falling edge of the
memory clock (FSMC_CLK).
(在同步读和写模式下,输出信号在存储器CLK的下降沿改变)
三.采样规则
The FSMC always samples the data before de-asserting the chip select signal NE. This
guarantees that the memory data-hold timing constraint is met (chip enable high to
data transition, usually 0 ns min.)
(FSMC总是在撤销片选信号NE前采样数据,这保证了了储存器数据保持时间的约束能够满足。)
四:时序计算
设定值都是以Hclk为基本单位的
公式:
![](../img/eep/emb/emb-61640z1ptax2uu01.jpg)
![](../img/eep/emb/emb-61641vszcfzxmsex.jpg)
![](../img/eep/emb/emb-61642fduxjsqwr5w.jpg)
![](../img/eep/emb/emb-616435mkoxlkwz5a.jpg)
现在没有完全弄明白的是,因为是异步模式,数据通过延迟一个HCLK通知给了对端,地址线上的信号怎么通知对端有效呢?
![](../img/eep/emb/emb-61644l2nri5trn1h.jpg)
![](../img/eep/emb/emb-61645fgaevso2ioz.jpg)
--------------------------------------------------------------------------------------------------
一些常见问题的FAQ:
FSMC 包括4个模块:
![](../img/eep/emb/emb-61637pv0n5p3iqxp.jpg)
(1)AHB接口(包括FSMC配置寄存器)
(2)NOR闪存和PSRAM控制器(驱动LCD的时候LCD就好像一个PSRAM的里面只有2个16位的存储空间,一个是DATA RAM 一个是CMD RAM)
(3)NAND闪存和PC卡控制器
(4)外部设备接口
每个模块通过片选信号控制
--------------------------------------------------------------------------------------------------
硬件电路(这里给出的是非复用连接)
![](../img/eep/emb/emb-61638cpcvxzpqcxf.jpg)
可以这样接
地址线A0 接 RS
NE接 CS
NEW –WR
NOE –RD
FSMC与外设连接好以后,就等于对于使用者屏蔽了对外设备的具体操作,只要对应类型的映射地址空间写入数据,这些数据+地址就会被自动翻译,并写入外围存储设备。
对于写LCD来说,STM官方库里有一些常用写法:
#define LCD_BASE
#define LCD
void LCD_WriteReg(u8 LCD_Reg,u16 LCD_RegValue)
{
}
u16 LCD_ReadReg(u8 LCD_Reg)
{
}
当然也可以自己操作,完全在于自己。
--------------------------------------------------------------------------------------------------
1位宽:
主要是AHB到NOR/PSRAM位宽的,比如如果AHB设为32位,NOR为16位,他会分两次传输
![](../img/eep/emb/emb-616392fp3xzr5rn3.jpg)
2:设置地址
手册是这样写的:在NOR/PSRAM模式下HADDR[27:26](HADDR are internal AHB address lines that are translated to external memory)用来片选NOR/PSRAM的四个分区。A[25:0]是地址线,因为HADDR是字节地址但是存取其按字编址,所以根据位宽的不同由以下情况。
(1)当存储数据设为8位时,
(2)当存储数据设为16位时,
(存储大小 (64MB / 2) * 16 = 512MB)
注意:在16位外部存储宽度下,FSMC内部会用A[25:1]去生成A[24:0]。不论8位或16位的情况,FSMC_A[0]必需连接外部存储的A[0]。
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
FSMC的好处就是你一旦设置好之后,WR、RD、DB0-DB15这些控制线和数据线,都是FSMC自动控制的。打个比方,当你在程序中写到:
(volatile unsigned short int*)(0x60000000)=val;
那么FSMC就会自动执行一个写的操作,其对应的主控芯片的WE、RD这些脚,就会呈现出写的时序出来(即WE=0,RD=1),数据val的值也会通过 DB0-15自动呈现出来(即FSMC-D0:FSMC-D15=val)。地址0x60000000会被呈现在数据线上(即A0-A25=0,地址线的对应最麻烦,要根据具体情况来,好好看看FSMC手册)。
(volatile unsigned short int*)(0x60020000)=val;
这个时候,A16在执行其他FSMC的同时会被拉高,因为A0-A18要呈现出地址0x60020000。0x60020000里面的Bit17=1,就会导致A16为1。
当要读数据时,地址由0x60020000改为了0x60000000,这个时候A16就为0了。--------------------------------------------------------------------------------------------------
下来就是关于 FSCM时序问题,大家都有讨论:
一.当FSMC选择NOR和PSRAM模块时:
分为两种:1.异步事务2.同步突发事务
异步事务分为普通模式(mode 1,mode 2)和模式1与模式2的4种扩展模式(mode A,B,C,D);
二.General timing rules(通用时序规则):
(所有输出控制信号在内部时钟(HCLK)的上升沿改变)
2.In synchronous read and write mode, the output data changes on the falling edge of the
memory clock (FSMC_CLK).
(在同步读和写模式下,输出信号在存储器CLK的下降沿改变)
三.采样规则
The FSMC always samples the data before de-asserting the chip select signal NE. This
guarantees that the memory data-hold timing constraint is met (chip enable high to
data transition, usually 0 ns min.)
(FSMC总是在撤销片选信号NE前采样数据,这保证了了储存器数据保持时间的约束能够满足。)
四:时序计算
设定值都是以Hclk为基本单位的
公式:
![](../img/eep/emb/emb-61640z1ptax2uu01.jpg)
![](../img/eep/emb/emb-61641vszcfzxmsex.jpg)
![](../img/eep/emb/emb-61642fduxjsqwr5w.jpg)
![](../img/eep/emb/emb-616435mkoxlkwz5a.jpg)
现在没有完全弄明白的是,因为是异步模式,数据通过延迟一个HCLK通知给了对端,地址线上的信号怎么通知对端有效呢?
![](../img/eep/emb/emb-61644l2nri5trn1h.jpg)
![](../img/eep/emb/emb-61645fgaevso2ioz.jpg)
--------------------------------------------------------------------------------------------------
一些常见问题的FAQ:
STM32FSMC学习笔 相关文章:
- STM32 FSMC 学习笔记(11-25)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)