STM32实战项目:无刷电机驱动详解
2025-09-29
系统时钟配置
启用72MHz主频:RCC_Configuration()设置PLL
外设时钟使能:TIM1/ADC/GPIO时钟
#include 'stm32f10x.h'
void RCC_Configuration(void)
{
// 时钟复位配置
RCC_DeInit();
// 1. 开启HSE并等待就绪
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
// 2. 配置PLL:HSE作为源,9倍频
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
// 3. 设置FLASH预取指和等待周期(必须)
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
// 4. 时钟分频配置
RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB=72MHz
RCC_PCLK1Config(RCC_HCLK_Div2); // APB1=36MHz
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2=72MHz
// 5. 启动PLL并切换时钟源
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08);
// 6. 外设时钟使能
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_TIM1 | // TIM1时钟
RCC_APB2Periph_ADC1 | // ADC1时钟
RCC_APB2Periph_GPIOA | // GPIOA时钟(示例)
RCC_APB2Periph_GPIOC, // GPIOC时钟(示例)
ENABLE
);
}
// 主函数初始化调用示例
int main(void)
{
RCC_Configuration();
// 其他初始化代码...
while(1);
}
PWM模块初始化
定时器1通道1-3配置:
TIM_OCInitTypeDef.Pulse = 50%占空比
TIM_BDTRInitStruct配置死区时间(50-100ns)
互补输出使能:
TIM_CCxNCmd(TIM1, ENABLE)
#include 'stm32f10x.h'
void PWM_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCStruct;
TIM_BDTRInitTypeDef TIM_BDTRStruct;
// 1. GPIO配置(以PA8/PA7为例)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_7; // CH1/CH1N
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 2. 定时器基础配置(72MHz时钟)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseStruct.TIM_Period = 1000-1; // ARR决定PWM频率
TIM_TimeBaseStruct.TIM_Prescaler = 0; // 无分频
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
// 3. PWM通道配置(50%占空比)
TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_Pulse = 500; // 50% of ARR(1000)
TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCStruct); // 通道1
TIM_OC2Init(TIM1, &TIM_OCStruct); // 通道2
TIM_OC3Init(TIM1, &TIM_OCStruct); // 通道3
// 4. 死区时间配置(约55.5ns)
TIM_BDTRStruct.TIM_DeadTime = 0x04; // DTG=4: 4*Tdts (Tdts=13.89ns@72MHz)
TIM_BDTRStruct.TIM_Break = TIM_Break_Disable;
TIM_BDTRStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRStruct.TIM_OSSRState = TIM_OSSRState_Disable;
TIM_BDTRStruct.TIM_OSSIState = TIM_OSSIState_Disable;
TIM_BDTRStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRStruct);
// 5. 互补输出使能
TIM_CCxNCmd(TIM1, TIM_Channel_1, ENABLE); // CH1N
TIM_CCxNCmd(TIM1, TIM_Channel_2, ENABLE); // CH2N
TIM_CCxNCmd(TIM1, TIM_Channel_3, ENABLE); // CH3N
// 6. 启动定时器
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE); // MOE置位
}
ADC模块配置
规则组通道选择:
ADC_RegularChannelConfig(ADC1, ADC_Channel_x, 1…)
DMA循环模式设置:
DMA_InitStruct.Mode = DMA_Mode_Circular
// 示例:配置ADC1规则组的3个通道(顺序:通道5→通道1→通道11)
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1); // 第1个转换
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2); // 第2个转换
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 3); // 第3个转换
ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_NbrOfChannel = 3; // 规则组总通道数
ADC_Init(ADC1, &ADC_InitStruct);
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; // 循环模式
DMA_InitStruct.DMA_BufferSize = 3; // 缓冲区大小(与规则组通道数匹配)
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址固定
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16位数据
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA1_Channel1, &DMA_InitStruct);
// 设置外设地址(ADC数据寄存器)
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
// 设置内存地址(自定义缓冲区)
extern uint16_t adc_buffer[3];
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)adc_buffer;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启动转换
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMACmd(ADC1, ENABLE); // 绑定ADC到DMA
霍尔接口配置
GPIO输入模式:
GPIO_Init(GPIOx, GPIO_Pin_x, GPIO_Mode_IPU)
EXTI中断触发:
EXTI_Trigger = EXTI_Trigger_Rising_Falling
霍尔传感器 → GPIO上拉输入 → EXTI双沿中断 → NVIC优先级配置 → 中断服务函数 → 换向逻辑
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIO时钟
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; // 霍尔传感器连接的PA0/PA1/PA2
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 输入模式下速度可忽略,但需设置
GPIO_Init(GPIOA, &GPIO_InitStruct);
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
// 将GPIO引脚映射到EXTI中断线(以PA0为例)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStruct.EXTI_Line = EXTI_Line0; // 对应PA0
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 双沿触发
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
// 配置NVIC中断优先级
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
uint8_t hall_state = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); // 读取霍尔信号
// 执行换向逻辑(例如BLDC电机驱动)
EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志
}
}
速度环定时器
定时器2基础配置:
TIM_TimeBaseInit(TIM2, 1kHz)
中断服务程序:
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE)
// 系统时钟假设为72MHz(STM32F1系列)
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_InitStruct.TIM_Prescaler = 7200 - 1; // 分频系数7200 → 72MHz/7200=10kHz
TIM_InitStruct.TIM_Period = 10 - 1; // 自动重载值 → 10kHz/10=1kHz
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
// 使能TIM2更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 允许定时器溢出中断[citation:9][citation:10]
// 配置NVIC中断优先级
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
// 执行速度环PID计算或数据采集
SpeedControl_Algorithm(); // 用户自定义速度环处理函数
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志[citation:9][citation:10]
}
}
换相逻辑实现
Hall状态机:
switch(Hall_Value & 0x07){
case 0b101: PWM_SetPhaseA_High();…
}
const PhaseAction phase_table[6] = {
{0b101, PWM_A, OFF_C}, // 状态0
{0b100, PWM_B, OFF_A}, // 状态1
// ...其他状态
};
switch(Hall_Value & 0x07) {
case 0b101: // 对应霍尔状态HA=1, HB=0, HC=1
PWM_SetPhaseA_High(); // 上桥臂A相PWM调制,下桥臂B相常通
PWM_SetPhaseB_Low();
PWM_SetPhaseC_Off(); // C相关闭(互补逻辑)
break;
case 0b100: // 其他状态类似调整
// ...
}
主控制循环
while(1){
ADC_Convert();
Speed_PID_Calc();
Current_Limit_Check();
}
void Current_Limit_Check() {
if (ADC_Current > MAX_CURRENT) {
PWM_Disable(); // 立即关闭功率输出
Fault_LED_On(); // 故障指示
System_Reset(); // 可选:进入安全状态或重启
}
}
- 意法半导体中国本地造STM32微控制器启动规模量产
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 基于机智云与STM32的智能拐杖安全监测系统在养老物联网中的应用
- 内置全栈安全,一站式满足CRA法案与IEC 62443标准——米尔STM32MP257核心板
- 如何用 STM32 FLASH 实现等效 100 万次擦写的 EEPROM 功能?
- 实战解析:通过一个小项目掌握STM32所有外设
- STM32学了两年半,却还是不会做项目
- 意法半导体推出最新STM32MP21微处理器,兼具高性价比、低功耗、高灵活性
- 基于STM32的矿井作业环境监测系统设计与实现
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策




