STM32 FSMC 接口
什么是 FSMC 接口?
FSMC(Flexible Static Memory Controller,灵活静态存储控制器)是 STM32 微控制器中的一个外设接口,用于连接外部存储器设备,如 SRAM、NOR Flash、NAND Flash 和 LCD 显示屏等。FSMC 接口通过灵活的时序配置,能够支持多种存储器和外设的访问需求,特别适用于需要高速数据传输的场景。
备注
FSMC 接口在 STM32F1、STM32F4 等系列中广泛使用,但在某些新系列(如 STM32H7)中已被 FMC(Flexible Memory Controller)取代。
FSMC 的工作原理
FSMC 接口通过多个信号线(如地址线、数据线、控制信号等)与外部设备通信。它支持多种存储类型和访问模式,并允许用户配置时序参数以满足不同设备的需求。
主要信号线
- 地址线(A[25:0]):用于指定外部存储器的地址。
- 数据线(D[15:0] 或 D[31:0]):用于传输数据。
- 控制信号:包括片选(NE)、写使能(NWE)、读使能(NOE)等。
时序配置
FSMC 的时序配置非常灵活,用户可以根据外部设备的需求调整以下参数:
- 地址建立时间(ADDSET)
- 数据建立时间(DATAST)
- 总线周转时间(BUSTURN)
配置 FSMC 接口
以下是一个配置 FSMC 接口以连接外部 SRAM 的示例代码:
c
#include "stm32f4xx.h"
void FSMC_SRAM_Init(void) {
// 启用 GPIO 和 FSMC 时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE, ENABLE);
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
// 配置 GPIO 引脚为 FSMC 功能
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | 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_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_Init(GPIOE, &GPIO_InitStruct);
// 配置 FSMC 参数
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStruct;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStruct;
FSMC_NORSRAMTimingInitStruct.FSMC_AddressSetupTime = 1;
FSMC_NORSRAMTimingInitStruct.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStruct.FSMC_DataSetupTime = 2;
FSMC_NORSRAMTimingInitStruct.FSMC_BusTurnAroundDuration = 0;
FSMC_NORSRAMTimingInitStruct.FSMC_CLKDivision = 0;
FSMC_NORSRAMTimingInitStruct.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStruct.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStruct.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStruct.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStruct.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStruct.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStruct.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStruct.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStruct.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStruct.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStruct.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStruct.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStruct.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStruct.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStruct;
FSMC_NORSRAMInitStruct.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStruct;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStruct);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}
提示
在实际项目中,时序参数需要根据外部存储器的数据手册进行调整,以确保通信的可靠性。
实际应用场景
连接外部 SRAM
在需要扩展内存的应用中,FSMC 接口可以用于连接外部 SRAM。例如,在图像处理或数据采集系统中,外部 SRAM 可以提供更大的存储空间和更快的数据访问速度。
驱动 LCD 显示屏
FSMC 接口也常用于驱动 TFT LCD 显示屏。通过 FSMC 接口,STM32 可以直接向 LCD 控制器发送命令和数据,从而实现高效的图形显示。
c
#define LCD_BASE_ADDRESS 0x60000000
void LCD_WriteCommand(uint16_t command) {
*(volatile uint16_t *)(LCD_BASE_ADDRESS) = command;
}
void LCD_WriteData(uint16_t data) {
*(volatile uint16_t *)(LCD_BASE_ADDRESS + 0x20000) = data;
}
总结
FSMC 接口是 STM32 微控制器中一个强大的外设接口,能够灵活地连接多种外部存储器和设备。通过合理的配置,FSMC 可以满足高速数据传输的需求,适用于多种应用场景。
附加资源与练习
- 练习:尝试配置 FSMC 接口以连接一个 NOR Flash 存储器,并实现数据的读写操作。
- 资源:参考 STM32 参考手册中的 FSMC 章节,了解更多关于时序配置和信号线的详细信息。
警告
在实际开发中,务必仔细阅读外部设备的数据手册,以确保 FSMC 的配置与设备的要求匹配。