STM32F1和STM32F4在配置硬件SPI1时有什么不同?
以下是 STM32F1 和 STM32F4 在配置 硬件SPI1 时的关键差异对比,涵盖时钟、GPIO、外设配置和性能优化等方面:
一、时钟配置差异
特性 | STM32F1 | STM32F4 |
---|---|---|
SPI1时钟总线 | APB2 (最高72MHz) | APB2 (最高84MHz/90MHz) |
时钟使能函数 | RCC_APB2PeriphClockCmd() | RCC_APB2PeriphClockCmd() |
GPIO时钟总线 | APB2 | AHB1 (速度更快) |
F4示例代码:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1时钟
二、GPIO配置差异
特性 | STM32F1 | STM32F4 |
---|---|---|
复用功能配置 | GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP | GPIO_Mode_AF + GPIO_PinAFConfig() |
引脚复用映射 | 无独立函数,直接配置复用模式 | 需调用GPIO_PinAFConfig() |
速度设置 | 无明确速度配置 | 支持GPIO_Speed_50MHz/100MHz |
F1配置示例:
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; // SCK, MOSI
GPIO_Init(GPIOA, &GPIO_InitStruct);
F1系列MISO直接配置成上拉输入模式即可
F4系列MISO必须配置成复用+上拉
F4配置示例:
GPIO_InitTypeDef GPIO_InitStruct = {.GPIO_Mode = GPIO_Mode_AF,.GPIO_OType = GPIO_OType_PP,.GPIO_Speed = GPIO_Speed_100MHz,.GPIO_PuPd = GPIO_PuPd_NOPULL,.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7
};
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); // SCK
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); // MOSI
三、SPI外设配置差异
特性 | STM32F1 | STM32F4 |
---|---|---|
SPI结构体成员 | 较简单,无独立CRCPolynomial字段 | 支持更复杂的CRC和DMA配置 |
波特率分频系数 | 固定分频值(如2,4,8,…) | 支持更灵活的分频(如2,4,8,…,256) |
数据位宽 | 仅支持8位/16位 | 支持8位/16位,部分型号支持32位 |
F1 SPI初始化:
SPI_InitTypeDef SPI_InitStruct = {.SPI_Direction = SPI_Direction_2Lines_FullDuplex,.SPI_Mode = SPI_Mode_Master,.SPI_DataSize = SPI_DataSize_8b,.SPI_CPOL = SPI_CPOL_Low,.SPI_CPHA = SPI_CPHA_1Edge,.SPI_NSS = SPI_NSS_Soft,.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8,.SPI_FirstBit = SPI_FirstBit_MSB
};
SPI_Init(SPI1, &SPI_InitStruct);
F4 SPI初始化(支持CRC):
SPI_InitTypeDef SPI_InitStruct = {.SPI_Direction = SPI_Direction_2Lines_FullDuplex,.SPI_Mode = SPI_Mode_Master,.SPI_DataSize = SPI_DataSize_8b,.SPI_CPOL = SPI_CPOL_Low,.SPI_CPHA = SPI_CPHA_1Edge,.SPI_NSS = SPI_NSS_Soft,.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4,.SPI_FirstBit = SPI_FirstBit_MSB,.SPI_CRCPolynomial = 7 // F4特有
};
SPI_Init(SPI1, &SPI_InitStruct);
四、DMA配置差异
特性 | STM32F1 | STM32F4 |
---|---|---|
DMA控制器 | 1个DMA控制器(DMA1) | 2个DMA控制器(DMA1/DMA2) |
流(Stream)概念 | 无 | 支持流(Stream)和通道(Channel) |
触发源选择 | 固定映射 | 灵活配置(通过DMA_InitStruct.DMA_Channel ) |
F4 DMA配置示例:
DMA_InitTypeDef DMA_InitStruct = {.DMA_Channel = DMA_Channel_3,.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR,.DMA_Memory0BaseAddr = (uint32_t)tx_buffer,.DMA_DIR = DMA_DIR_MemoryToPeripheral,.DMA_BufferSize = BUFFER_SIZE,.DMA_PeripheralInc = DMA_PeripheralInc_Disable,.DMA_MemoryInc = DMA_MemoryInc_Enable,.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,.DMA_Mode = DMA_Mode_Normal,.DMA_Priority = DMA_Priority_High,.DMA_FIFOMode = DMA_FIFOMode_Enable,.DMA_FIFOThreshold = DMA_FIFOThreshold_Full,.DMA_MemoryBurst = DMA_MemoryBurst_INC4,.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4
};
DMA_Init(DMA2_Stream3, &DMA_InitStruct);
五、中断与性能优化
特性 | STM32F1 | STM32F4 |
---|---|---|
中断优先级配置 | 仅4位抢占优先级 | 支持4位抢占优先级+4位子优先级 |
最大SPI时钟 | 18MHz (APB2=72MHz, 分频4) | 21MHz (APB2=84MHz, 分频4) |
硬件CRC | 不支持 | 支持硬件CRC计算 |
F4中断配置示例:
NVIC_InitTypeDef NVIC_InitStruct = {.NVIC_IRQChannel = SPI1_IRQn,.NVIC_IRQChannelPreemptionPriority = 1,.NVIC_IRQChannelSubPriority = 0, // F4特有子优先级.NVIC_IRQChannelCmd = ENABLE
};
NVIC_Init(&NVIC_InitStruct);
六、实际应用注意事项
-
F1的特殊性:
无需配置引脚复用映射(AF配置内置于GPIO模式)
- DMA功能较简单,适合低速传输
-
F4的特殊性:
- 必须配置引脚复用映射:
/*引脚复用映射 未配置复用功能时,GPIO无法连接到SPI外设,导致信号无法传输*/GPIO_PinAFConfig(SPI_CLK_GPIO_PORT, GPIO_PinSource5, GPIO_AF_SPI1); // SCKGPIO_PinAFConfig(SPI_MISO_GPIO_PORT, GPIO_PinSource6, GPIO_AF_SPI1); // MISOGPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, GPIO_PinSource7, GPIO_AF_SPI1); // MOSI
- 必须将MISO配置成复用+上拉
(这里有些难理解,MISO正常情况下应该是上拉输入,F4系列却强行需要配置为AF+上拉,这里与F1配置不同,尤为需要注意)
- F4的优势:
- 支持更高的时钟频率和更精细的DMA控制
- 通过
GPIO_PinAFConfig()
灵活分配引脚功能
- 跨平台兼容代码:
#if defined(STM32F10X)// F1专用配置GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; #elif defined(STM32F40XX)// F4专用配置GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); #endif
七、调试技巧
-
F1常见问题:
- 检查
GPIO_Mode_AF_PP
是否正确配置 - 确保APB2时钟使能
- 检查
-
F4常见问题:
- 确认
GPIO_PinAFConfig()
调用 - 检查DMA流(Stream)和通道(Channel)是否匹配
- 确认
-
通用验证方法:
// 读取SPI状态寄存器 printf("SPI1->SR = 0x%04X\n", SPI1->SR); /* 关键位:- BIT 1: TXE (发送缓冲区空)- BIT 0: RXNE (接收数据就绪)- BIT 5: MODF (模式错误) */
总结
- STM32F1:配置简单,适合低速场景,注意复用模式为
GPIO_Mode_AF_PP
- STM32F4:功能强大,
需额外配置引脚复用映射
,支持高性能DMA和CRC - 移植建议:使用条件编译区分芯片型号,优先验证SPI基础通信功能