用STM32F103和电位器打造无刷电机调速系统从硬件连接到代码实战旋转电位器旋钮就能精准控制无刷电机转速这种直观的交互方式在机器人、无人机和工业控制领域有着广泛应用。本文将带您从零开始基于STM32F103微控制器构建完整的电位器调速系统涵盖硬件设计、ADC采集、PWM生成以及安全控制逻辑等核心环节。1. 系统架构与硬件选型无刷电机调速系统的核心在于将电位器的机械旋转角度转换为电信号再通过微控制器处理最终驱动电机。我们选择的STM32F103C8T6俗称蓝莓板因其丰富的外设和性价比成为创客首选。关键硬件组件STM32F103C8T6开发板内置12位ADC和PWM定时器10KΩ线性电位器B10K型号无刷电机驱动器如ESC电调无刷电机推荐2204-2300KV型号电源系统12V锂电池5V稳压提示电位器建议选用线性而非对数型确保旋转角度与电阻值呈线性关系。硬件连接示意图设备STM32引脚备注电位器中间引脚PA0ADC1通道0电位器VCC3.3V避免使用5V防止ADC过压电位器GNDGND共地连接电调PWM信号线PA8TIM1_CH1输出2. ADC采集与数据处理STM32的12位ADC能够将0-3.3V电压转换为0-4095的数字量。我们需要配置ADC以稳定采集电位器电压// ADC初始化代码 void ADC1_Init(void) { RCC-APB2ENR | RCC_APB2ENR_ADC1EN; // 使能ADC1时钟 ADC1-CR2 ADC_CR2_ADON; // 开启ADC ADC1-SQR3 0; // 选择通道0 HAL_Delay(1); // 等待ADC稳定 } // 获取ADC值函数 uint16_t Get_ADC_Value(void) { ADC1-CR2 | ADC_CR2_SWSTART; // 启动转换 while(!(ADC1-SR ADC_SR_EOC)); // 等待转换完成 return ADC1-DR; // 返回转换结果 }采样优化技巧采用均值滤波连续采样10次取平均值添加死区处理当变化小于5个LSB时保持原值电压范围校准记录旋转到两端时的ADC极值#define FILTER_NUM 10 uint16_t ADC_Filter(void) { uint32_t sum 0; for(uint8_t i0; iFILTER_NUM; i) { sum Get_ADC_Value(); HAL_Delay(1); } return sum/FILTER_NUM; }3. PWM生成与电机控制无刷电机通常通过20ms周期的PWM信号控制其中高电平宽度在1-2ms间变化。我们需要配置TIM1产生标准50Hz PWM// PWM初始化代码 void PWM_Init(uint16_t arr, uint16_t psc) { RCC-APB2ENR | RCC_APB2ENR_TIM1EN; // 使能TIM1时钟 GPIOA-CRH ~(GPIO_CRH_CNF8 | GPIO_CRH_MODE8); // 配置PA8为复用输出 GPIOA-CRH | GPIO_CRH_MODE8_1 | GPIO_CRH_MODE8_0; TIM1-ARR arr - 1; // 自动重装载值 TIM1-PSC psc - 1; // 预分频器 TIM1-CCMR1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM模式1 TIM1-CCER | TIM_CCER_CC1E; // 开启输出 TIM1-BDTR | TIM_BDTR_MOE; // 主输出使能 TIM1-CR1 | TIM_CR1_CEN; // 启动定时器 } // 设置PWM占空比 void Set_PWM_Duty(uint16_t duty) { TIM1-CCR1 duty; // 修改捕获比较值 }安全控制策略上电初始化时将PWM设为最小值1ms添加软件限幅保护限制在1-2ms范围急停功能通过按键立即归零// ADC值映射到PWM脉宽 uint16_t Map_ADC_to_PWM(uint16_t adc_val) { const uint16_t PWM_MIN 1000; // 1ms const uint16_t PWM_MAX 2000; // 2ms uint16_t pwm PWM_MIN (adc_val * (PWM_MAX-PWM_MIN)) / 4095; return (pwm PWM_MIN) ? PWM_MIN : (pwm PWM_MAX) ? PWM_MAX : pwm; }4. 系统集成与调试技巧将各模块组合后主程序逻辑如下int main(void) { HAL_Init(); PWM_Init(20000, 72); // 50Hz PWM ADC1_Init(); while(1) { uint16_t adc_val ADC_Filter(); uint16_t pwm_val Map_ADC_to_PWM(adc_val); Set_PWM_Duty(pwm_val); HAL_Delay(10); // 10ms控制周期 } }常见问题排查现象可能原因解决方案电机不响应PWM信号未连接检查电调信号线连接转速跳动不稳定电位器接触不良更换高质量电位器仅全速或停止两档PWM脉宽范围不正确校准PWM_MIN和PWM_MAX值ADC值始终为0引脚配置错误检查ADC通道与GPIO模式配置调试时可先通过串口打印ADC原始值和计算后的PWM值printf(ADC: %4d - PWM: %4d\r\n, adc_val, pwm_val);5. 进阶优化方向基础功能实现后可以考虑以下增强功能速度曲线优化线性映射y kx b指数曲线y a^(x-c) b适合精细低速控制S型曲线平滑加减速避免突变// 指数曲线映射示例 uint16_t Exp_Map(uint16_t x) { float x_norm x / 4095.0f; float y powf(4.0f, x_norm) / 4.0f; // 调整底数改变曲线形状 return 1000 (uint16_t)(y * 1000); }多模式控制通过按键切换速度限制模式保存用户预设转速档位添加LCD显示屏实时显示转速实际项目中我在为3D打印机设计风扇控制系统时发现为不同功率的风扇设置合适的加速斜率能显著降低机械振动。例如5015涡轮风扇适合采用S型曲线而普通4010风扇使用线性映射即可获得良好效果。
用STM32F103和电位器给你的无刷电机做个“油门”:手把手实现ADC调速(附完整代码)
发布时间:2026/5/16 11:17:23
用STM32F103和电位器打造无刷电机调速系统从硬件连接到代码实战旋转电位器旋钮就能精准控制无刷电机转速这种直观的交互方式在机器人、无人机和工业控制领域有着广泛应用。本文将带您从零开始基于STM32F103微控制器构建完整的电位器调速系统涵盖硬件设计、ADC采集、PWM生成以及安全控制逻辑等核心环节。1. 系统架构与硬件选型无刷电机调速系统的核心在于将电位器的机械旋转角度转换为电信号再通过微控制器处理最终驱动电机。我们选择的STM32F103C8T6俗称蓝莓板因其丰富的外设和性价比成为创客首选。关键硬件组件STM32F103C8T6开发板内置12位ADC和PWM定时器10KΩ线性电位器B10K型号无刷电机驱动器如ESC电调无刷电机推荐2204-2300KV型号电源系统12V锂电池5V稳压提示电位器建议选用线性而非对数型确保旋转角度与电阻值呈线性关系。硬件连接示意图设备STM32引脚备注电位器中间引脚PA0ADC1通道0电位器VCC3.3V避免使用5V防止ADC过压电位器GNDGND共地连接电调PWM信号线PA8TIM1_CH1输出2. ADC采集与数据处理STM32的12位ADC能够将0-3.3V电压转换为0-4095的数字量。我们需要配置ADC以稳定采集电位器电压// ADC初始化代码 void ADC1_Init(void) { RCC-APB2ENR | RCC_APB2ENR_ADC1EN; // 使能ADC1时钟 ADC1-CR2 ADC_CR2_ADON; // 开启ADC ADC1-SQR3 0; // 选择通道0 HAL_Delay(1); // 等待ADC稳定 } // 获取ADC值函数 uint16_t Get_ADC_Value(void) { ADC1-CR2 | ADC_CR2_SWSTART; // 启动转换 while(!(ADC1-SR ADC_SR_EOC)); // 等待转换完成 return ADC1-DR; // 返回转换结果 }采样优化技巧采用均值滤波连续采样10次取平均值添加死区处理当变化小于5个LSB时保持原值电压范围校准记录旋转到两端时的ADC极值#define FILTER_NUM 10 uint16_t ADC_Filter(void) { uint32_t sum 0; for(uint8_t i0; iFILTER_NUM; i) { sum Get_ADC_Value(); HAL_Delay(1); } return sum/FILTER_NUM; }3. PWM生成与电机控制无刷电机通常通过20ms周期的PWM信号控制其中高电平宽度在1-2ms间变化。我们需要配置TIM1产生标准50Hz PWM// PWM初始化代码 void PWM_Init(uint16_t arr, uint16_t psc) { RCC-APB2ENR | RCC_APB2ENR_TIM1EN; // 使能TIM1时钟 GPIOA-CRH ~(GPIO_CRH_CNF8 | GPIO_CRH_MODE8); // 配置PA8为复用输出 GPIOA-CRH | GPIO_CRH_MODE8_1 | GPIO_CRH_MODE8_0; TIM1-ARR arr - 1; // 自动重装载值 TIM1-PSC psc - 1; // 预分频器 TIM1-CCMR1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM模式1 TIM1-CCER | TIM_CCER_CC1E; // 开启输出 TIM1-BDTR | TIM_BDTR_MOE; // 主输出使能 TIM1-CR1 | TIM_CR1_CEN; // 启动定时器 } // 设置PWM占空比 void Set_PWM_Duty(uint16_t duty) { TIM1-CCR1 duty; // 修改捕获比较值 }安全控制策略上电初始化时将PWM设为最小值1ms添加软件限幅保护限制在1-2ms范围急停功能通过按键立即归零// ADC值映射到PWM脉宽 uint16_t Map_ADC_to_PWM(uint16_t adc_val) { const uint16_t PWM_MIN 1000; // 1ms const uint16_t PWM_MAX 2000; // 2ms uint16_t pwm PWM_MIN (adc_val * (PWM_MAX-PWM_MIN)) / 4095; return (pwm PWM_MIN) ? PWM_MIN : (pwm PWM_MAX) ? PWM_MAX : pwm; }4. 系统集成与调试技巧将各模块组合后主程序逻辑如下int main(void) { HAL_Init(); PWM_Init(20000, 72); // 50Hz PWM ADC1_Init(); while(1) { uint16_t adc_val ADC_Filter(); uint16_t pwm_val Map_ADC_to_PWM(adc_val); Set_PWM_Duty(pwm_val); HAL_Delay(10); // 10ms控制周期 } }常见问题排查现象可能原因解决方案电机不响应PWM信号未连接检查电调信号线连接转速跳动不稳定电位器接触不良更换高质量电位器仅全速或停止两档PWM脉宽范围不正确校准PWM_MIN和PWM_MAX值ADC值始终为0引脚配置错误检查ADC通道与GPIO模式配置调试时可先通过串口打印ADC原始值和计算后的PWM值printf(ADC: %4d - PWM: %4d\r\n, adc_val, pwm_val);5. 进阶优化方向基础功能实现后可以考虑以下增强功能速度曲线优化线性映射y kx b指数曲线y a^(x-c) b适合精细低速控制S型曲线平滑加减速避免突变// 指数曲线映射示例 uint16_t Exp_Map(uint16_t x) { float x_norm x / 4095.0f; float y powf(4.0f, x_norm) / 4.0f; // 调整底数改变曲线形状 return 1000 (uint16_t)(y * 1000); }多模式控制通过按键切换速度限制模式保存用户预设转速档位添加LCD显示屏实时显示转速实际项目中我在为3D打印机设计风扇控制系统时发现为不同功率的风扇设置合适的加速斜率能显著降低机械振动。例如5015涡轮风扇适合采用S型曲线而普通4010风扇使用线性映射即可获得良好效果。