STM32F407外挂SRAM应用
程序员文章站
2022-04-01 16:45:02
...
硬件方面:IS62WV51216(具体硬件连接请看原子哥的原理图,这里不做描述)
软件方面:MDK
主要两件事
- 修改startup_xxx.s 堆栈地址并在__main函数前初始化FSMC
- 修改.sct文件(分散加载),添加外部SRAM的使用空间及大小。
具体步骤如下:
//startup_stm32f407xx.s部分
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD 0x20000100 ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
...
...
...
IMPORT SystemInit
IMPORT FSMC_SRAM_Init
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =FSMC_SRAM_Init
BLX R0
LDR R0, =__main
BX R0
ENDP
0x20000100 替换 __initial_sp
添加IMPORT FSMC_SRAM_Init
添加LDR R0, =FSMC_SRAM_Init和LX R0。敲黑板这两句必须在__main前面
这里的FSMC_SRAM_Init函数是使用正点原子探索者407寄存器版本的,里面所使用的变量只能是创建在内部SRAM哦,一旦用了外部SRAM就会触发HardFault,后果你懂的。所以尽量使用寄存器来初始化配置FSMC。
接下来就是第二部分,配置内存分配空间
按上图配置,要注意的是default一定要勾选,不然内存是不会分配到外部SRAM的。当然了你用__atrribute__来指定分配也是可以用的,但是有一个问题就是你不能初始化赋值,管你是非零还是零赋值,通通没用,原因何在,我也不知道。希望高人指点一二
之后就可以愉快的使用外部SRAM啦。
编写代码的时候使用方式与内部SRAM无异。
不过速度嘛…肯定比使用内部SRAM要慢的,毕竟FSMC操作外部SRAM的速度就那么大。
最后附上我改写后的纯寄存器版本的FSMC_SRAM_Init
经测试能用在STM32F407上,其他芯片请自行修改。
void FSMC_SRAM_Init(void)
{
/*-- GPIOs Configuration -----------------------------------------------------*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
//PD0,1,4,5,8~15 100M AF OUT_PP UP
//PE0,1,7~15 100M AF OUT_PP UP
//PF0~5,12~15 100M AF OUT_PP UP
//PG0~5,10 100M AF OUT_PP UP
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CC00CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A0A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0F0F;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* pull-up for PDx pins */
GPIOD->PUPDR = 0x55550505;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00000CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC00F;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* pull-up for PEx pins */
GPIOE->PUPDR = 0x55554005;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0x00CCCCCC;
GPIOF->AFR[1] = 0xCCCC0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA000AAA;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xFF000FFF;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* pull-up for PFx pins */
GPIOF->PUPDR = 0x55000555;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0x00CCCCCC;
GPIOG->AFR[1] = 0x00000C00;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00200AAA;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x00300FFF;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* pull-up for PGx pins */
GPIOG->PUPDR = 0x00100555;
/*-- FMC/FSMC Configuration --------------------------------------------------*/
/* Enable the FMC/FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
//寄存器清零
//bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
//这里我们使用NE3 ,也就对应BTCR[4],[5]。
FSMC_Bank1->BTCR[4]=0X00000000;
FSMC_Bank1->BTCR[5]=0X00000000;
FSMC_Bank1E->BWTR[4]=0X00000000;
//操作BCR寄存器 使用异步模式,模式A(读写共用一个时序寄存器)
//BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器
FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能
FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit
//操作BTR寄存器 (HCLK=168M, 1个HCLK=6ns
FSMC_Bank1->BTCR[5]|=8<<8; //数据保持时间(DATAST)为9个HCLK 6*9=54ns
FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到
FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns
//闪存写时序寄存器
FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值
//使能BANK1区域3
FSMC_Bank1->BTCR[4]|=1<<0;
}