1. STM32F103微控制器概述
STM32F103系列是STMicroelectronics推出的基于ARM Cortex-M3内核的32位微控制器,主频最高可达72MHz。这个系列产品线覆盖了从16KB到1MB不等的Flash存储容量,为不同规模的嵌入式应用提供了灵活选择。作为STM32家族中最经典的入门级产品,它凭借出色的性价比和丰富的片上资源,在工业控制、消费电子、物联网设备等领域获得了广泛应用。
我第一次接触STM32F103是在2015年开发一个工业传感器项目时,当时就被它完善的开发环境和丰富的外设所吸引。相比同价位的其他MCU,STM32F103提供了更强大的处理能力和更丰富的外设接口,特别适合需要复杂控制逻辑的中小型项目。
2. 核心特性与硬件资源
2.1 处理器架构与性能
STM32F103采用ARM Cortex-M3内核,三级流水线设计,支持Thumb-2指令集。72MHz的主频配合单周期乘法器和硬件除法器,使其在数值运算方面表现优异。实际测试中,执行一个32位乘法仅需1个时钟周期,而32位除法也只需要2-12个周期(取决于操作数)。
注意:虽然标称主频为72MHz,但实际运行频率取决于供电电压。当使用3.3V供电时才能达到全速运行,2.0V供电时最高频率会降至36MHz。
2.2 存储资源分配
该系列提供了灵活的存储配置:
- Flash容量:从16KB(如STM32F103C4)到1MB(如STM32F103ZE)不等
- SRAM容量:4KB-96KB
- 内置Bootloader:支持通过USART、USB等接口进行串行编程
我在多个项目中发现,STM32F103的Flash写入速度相当快,擦除一个1KB的页仅需约40ms,而编程一个16位字只需40μs。这对于需要频繁进行固件更新的应用非常有利。
2.3 丰富的外设接口
STM32F103的外设是其最大亮点之一:
- 多达11个定时器(包括2个高级控制定时器)
- 3个SPI接口(2个可工作于I2S模式)
- 2个I2C接口
- 3个USART和2个UART
- USB 2.0全速接口
- CAN 2.0B主动接口
- 12位ADC(最多3个,21个通道)
特别值得一提的是它的DMA控制器,有7个通道,可以大大减轻CPU负担。我在处理高速ADC采样数据时,使用DMA直接将数据搬运到内存,CPU占用率从70%降到了不足5%。
3. 开发环境搭建
3.1 工具链选择
STM32F103支持多种开发工具:
- 官方工具:STM32CubeIDE(免费)、STM32CubeMX(配置工具)
- 第三方IDE:Keil MDK、IAR Embedded Workbench
- 开源工具链:GCC ARM Embedded + VSCode
对于初学者,我推荐使用STM32CubeIDE,它集成了STM32CubeMX的配置功能和完整的开发环境。而对于资深开发者,Keil或IAR可能提供更好的调试体验。
3.2 硬件准备
最小系统需要:
- STM32F103开发板(如Blue Pill)
- ST-Link调试器(或兼容的J-Link)
- USB转串口模块(用于串口通信)
- 3.3V稳压电源
重要提示:STM32F103的工作电压为2.0-3.6V,所有IO口最大耐受电压为5V,但建议不要长时间工作在5V电平,否则可能缩短芯片寿命。
3.3 软件库支持
ST提供了三种编程方式:
- 标准外设库(SPL):传统方式,直接寄存器操作
- 硬件抽象层(HAL):跨系列兼容性更好
- 底层LL库:性能接近寄存器操作,但更易用
我的经验是:对性能要求极高的场合用LL库,一般应用用HAL库,而学习阶段可以从标准库开始理解底层原理。
4. 典型应用场景与实战技巧
4.1 工业控制应用
STM32F103的定时器和PWM功能非常适合电机控制。我曾用它实现无感FOC(Field Oriented Control)算法,通过高级定时器TIM1和TIM8的互补PWM输出,配合ADC采样电流,实现了对BLDC电机的精确控制。
关键配置要点:
- 死区时间设置:通常100-500ns,防止上下管直通
- PWM频率选择:10-20kHz为宜,兼顾效率和噪声
- ADC采样时机:在PWM周期中点采样电流最准确
4.2 物联网节点设计
结合JDY-31蓝牙模块,STM32F103可以构建低功耗物联网终端。我的一个环境监测项目中使用STM32F103C8T6+JDY-31,平均功耗控制在1mA以下。
低功耗实现技巧:
- 合理使用STOP模式:关闭主时钟,保留SRAM内容
- 外设时钟管理:不使用时及时关闭时钟
- IO口配置:未使用的IO设为模拟输入状态
4.3 通信接口实战
4.3.1 SBUS协议实现
与富斯接收机的SBUS通信需要注意:
- SBUS使用反向逻辑的UART信号
- 波特率为100kbps(非标准)
- 每个数据包25字节,包含16个通道信息
配置示例(使用USART2):
huart2.Instance = USART2; huart2.Init.BaudRate = 100000; huart2.Init.WordLength = UART_WORDLENGTH_9B; huart2.Init.StopBits = UART_STOPBITS_2; huart2.Init.Parity = UART_PARITY_EVEN; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16;4.3.2 SPI DMA传输
使用DMA加速SPI通信(如驱动nRF24L01):
- 配置SPI为全双工主模式
- 启用TX和RX的DMA通道
- 设置DMA为循环模式(适用于持续数据传输)
常见问题:DMA传输完成后记得清除标志位,否则下次传输可能无法启动。
5. 常见问题与解决方案
5.1 程序移植问题
从STM32F407移植到STM32F103需要注意:
- 时钟配置不同:F407有PLL分频器,F103更简单
- 外设寄存器差异:即使同名外设也可能有细微差别
- 中断向量表位置:F103的Flash起始地址是0x08000000
5.2 看门狗配置
使用CubeMX配置1秒看门狗:
- 在"Pinout & Configuration"中选择IWDG
- 设置Prescaler为32分频(32kHz LSI时钟)
- 设置Reload值为1000(1000ms)
- 在代码中定期调用HAL_IWDG_Refresh()
5.3 Flash编程问题
使用内部Flash存储数据时:
- 必须先擦除后写入(按页擦除)
- 写入地址必须对齐到16位边界
- 操作期间不能执行Flash中的代码
典型操作序列:
HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef erase; erase.TypeErase = FLASH_TYPEERASE_PAGES; erase.PageAddress = 0x0801F000; erase.NbPages = 1; uint32_t error; HAL_FLASHEx_Erase(&erase, &error); HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, 0x0801F000, 0x1234); HAL_FLASH_Lock();5.4 多通道ADC采集
使用HAL库实现多通道ADC DMA采集:
- 配置ADC为扫描模式、连续转换
- 启用DMA循环模式
- 设置规则组包含所有需要采集的通道
- 启动转换后,DMA会自动将结果存入指定数组
常见问题:通道间的采样时间间隔要足够长,否则可能影响精度。
6. 开发资源与进阶学习
6.1 官方资料获取
ST官网提供了完整的文档包:
- 参考手册(RM0008):详细描述所有外设
- 数据手册:电气特性和封装信息
- 编程手册:Cortex-M3内核细节
- 应用笔记:各种外设的使用示例
6.2 开源项目参考
GitHub上有大量优质开源项目:
- 野火/正点原子的例程库
- STM32F103无感FOC实现
- FreeRTOS移植示例
- USB设备协议栈
6.3 硬件设计要点
自制最小系统板时:
- 复位电路:10k上拉+100nF电容
- 时钟电路:8MHz晶振+20pF负载电容
- 退耦电容:每个电源引脚至少100nF
- BOOT引脚:通常下拉选择Flash启动
原理图设计建议参考ST官方的评估板设计,避免常见错误。