STM32F1和STM32F4在配置硬件SPI1时有什么不同?

以下是 STM32F1STM32F4 在配置 硬件SPI1 时的关键差异对比,涵盖时钟、GPIO、外设配置和性能优化等方面:


一、时钟配置差异

特性 STM32F1 STM32F4
SPI1时钟总线 APB2 (最高72MHz) APB2 (最高84MHz/90MHz)
时钟使能函数 RCC_APB2PeriphClockCmd() RCC_APB2PeriphClockCmd()
GPIO时钟总线 APB2 AHB1 (速度更快)

F4示例代码

c 复制代码
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配置示例

c 复制代码
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配置示例

c 复制代码
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初始化

c 复制代码
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):

c 复制代码
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配置示例

c 复制代码
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中断配置示例

c 复制代码
NVIC_InitTypeDef NVIC_InitStruct = {
    .NVIC_IRQChannel = SPI1_IRQn,
    .NVIC_IRQChannelPreemptionPriority = 1,
    .NVIC_IRQChannelSubPriority = 0,  // F4特有子优先级
    .NVIC_IRQChannelCmd = ENABLE
};
NVIC_Init(&NVIC_InitStruct);

六、实际应用注意事项

  1. F1的特殊性

    • 无需配置引脚复用映射(AF配置内置于GPIO模式)
    • DMA功能较简单,适合低速传输
  2. F4的特殊性

  • 必须配置引脚复用映射:
c 复制代码
	/*引脚复用映射 未配置复用功能时,GPIO无法连接到SPI外设,导致信号无法传输*/
	GPIO_PinAFConfig(SPI_CLK_GPIO_PORT, GPIO_PinSource5, GPIO_AF_SPI1); // SCK
    GPIO_PinAFConfig(SPI_MISO_GPIO_PORT, GPIO_PinSource6, GPIO_AF_SPI1); // MISO
    GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, GPIO_PinSource7, GPIO_AF_SPI1); // MOSI
  • 必须将MISO配置成复用+上拉(这里有些难理解,MISO正常情况下应该是上拉输入,F4系列却强行需要配置为AF+上拉,这里与F1配置不同,尤为需要注意)
  1. F4的优势
  • 支持更高的时钟频率和更精细的DMA控制
  • 通过GPIO_PinAFConfig()灵活分配引脚功能
  1. 跨平台兼容代码

    c 复制代码
    #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

七、调试技巧

  1. F1常见问题

    • 检查GPIO_Mode_AF_PP是否正确配置
    • 确保APB2时钟使能
  2. F4常见问题

    • 确认GPIO_PinAFConfig()调用
    • 检查DMA流(Stream)和通道(Channel)是否匹配
  3. 通用验证方法

    c 复制代码
    // 读取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基础通信功能
相关推荐
DIY机器人工房3 小时前
(十三)嵌入式面试题收集:6道
单片机·嵌入式硬件·diy机器人工房
国科安芯3 小时前
国产RISC-V架构MCU在工控系统中的节能性分析
网络·单片机·嵌入式硬件·fpga开发·性能优化·架构·risc-v
夜月yeyue4 小时前
Linux内高端内存
linux·运维·单片机·嵌入式硬件·ci/cd·硬件架构
沉在嵌入式的鱼8 小时前
linux串口对0X0D、0X0A等特殊字符的处理
linux·stm32·单片机·特殊字符·串口配置
学习路上_write8 小时前
AD5293驱动学习
c语言·单片机·嵌入式硬件·学习
影阴8 小时前
存储器和寄存器
stm32·单片机·嵌入式硬件
吃西瓜的年年9 小时前
3. C语言核心语法2
c语言·嵌入式硬件·改行学it
李洛克0710 小时前
RDMA CM UDP 通信完整指南
单片机·网络协议·udp
思茂信息10 小时前
CST电动车EMC仿真——电机控制器MCU滤波仿真
javascript·单片机·嵌入式硬件·cst·电磁仿真
小曹要微笑10 小时前
I2C总线技术解析(纯文字版)
单片机·嵌入式硬件·esp32·iic