从玩具小车到智能风扇:STM32F103C8T6核心板+PWM+ULN2003A的5个创意项目实践
在创客的世界里,STM32F103C8T6核心板就像一块神奇的画布,而PWM和ULN2003A则是你手中的画笔。当这三者相遇,便能创造出无数令人惊叹的作品。本文将带你超越基础教程,探索五个既实用又有趣的项目,从可调速迷你风扇到远程控制的智能小车,每个项目都经过精心设计,确保可复现性和趣味性。
1. 可调速迷你风扇:夏日桌面好伙伴
炎炎夏日,一个由你亲手打造的迷你风扇不仅能带来清凉,更是展示技术实力的绝佳方式。这个项目将利用STM32的PWM功能通过ULN2003A驱动直流电机,实现无级调速。
硬件清单:
- STM32F103C8T6核心板
- ULN2003A驱动模块
- 5V直流电机(带风扇叶片)
- 电位器(10kΩ)
- 杜邦线若干
核心代码片段:
// PWM初始化 void PWM_Init(uint16_t arr, uint16_t psc) { // 初始化代码与上文类似,此处省略 // 设置定时器3通道2为PWM输出 } // 主函数中读取电位器值并设置PWM int main() { ADC_Init(); // 初始化ADC PWM_Init(899, 0); // 80kHz PWM频率 while(1) { uint16_t adc_val = ADC_Read(0); // 读取电位器值 uint16_t pwm_val = adc_val * 900 / 4095; // 映射到PWM范围 TIM_SetCompare2(TIM3, pwm_val); // 设置PWM占空比 delay_ms(50); } }调试技巧:如果电机启动困难,可以尝试在程序中设置一个最小启动PWM值(如50),确保电机能顺利启动后再响应电位器调节。
2. 循迹小车的差速控制:智能移动的第一步
循迹小车是入门机器人领域的经典项目。通过两个直流电机和红外传感器,我们可以实现基础的自动导航功能。关键在于如何利用PWM实现精准的差速控制。
关键组件:
- 两个直流电机(带减速箱)
- 红外循迹模块(TCRT5000)
- 7.4V锂电池
- 电机固定支架和车轮
差速控制逻辑表:
| 传感器状态(左中右) | 左轮PWM | 右轮PWM | 小车动作 |
|---|---|---|---|
| 0 1 0 | 70% | 70% | 直行 |
| 1 0 0 | 30% | 70% | 右转 |
| 0 0 1 | 70% | 30% | 左转 |
| 1 1 1 | 0% | 0% | 停止 |
电机驱动代码优化:
// 设置左右电机速度 void Set_Motor_Speed(uint8_t left, uint8_t right) { // 限制PWM范围在30%-70%防止打滑 left = constrain(left, 30, 70); right = constrain(right, 30, 70); // 转换为实际PWM值(假设ARR=899) uint16_t left_pwm = map(left, 0, 100, 0, 899); uint16_t right_pwm = map(right, 0, 100, 0, 899); TIM_SetCompare2(TIM3, left_pwm); // 左电机 TIM_SetCompare1(TIM4, right_pwm); // 右电机 }注意:ULN2003A的每个通道最大电流为500mA,如果电机电流较大,建议将两个通道并联使用,或考虑使用更强大的驱动如L298N。
3. PWM模拟舵机控制:低成本的角度解决方案
标准舵机价格较高且需要特定信号,而我们可以用普通直流电机+PWM模拟实现简单的角度控制,非常适合对精度要求不高的场景。
实现原理:
- 电机通过减速箱增加扭矩
- 末端安装电位器作为位置反馈
- PID控制算法调节PWM输出
- 限位开关保护防止过转
PID控制核心代码:
typedef struct { float Kp, Ki, Kd; float integral, prev_error; } PID_Controller; float PID_Update(PID_Controller* pid, float setpoint, float actual) { float error = setpoint - actual; pid->integral += error; float derivative = error - pid->prev_error; pid->prev_error = error; return pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative; } // 使用示例 PID_Controller pid = {0.8, 0.05, 0.1, 0, 0}; float target_angle = 90.0; // 目标角度 while(1) { float current_angle = Read_Potentiometer(); // 读取当前位置 float output = PID_Update(&pid, target_angle, current_angle); uint16_t pwm = constrain(output, 0, 100); // 限制输出范围 Set_Motor_PWM(pwm); delay_ms(20); }硬件连接示意图:
电位器 —— ADC引脚 电机 —— ULN2003A —— STM32 PWM 限位开关 —— GPIO输入4. 蓝牙远程调速:手机控制你的创造物
通过HC-05蓝牙模块,我们可以用手机APP远程控制电机转速,为项目添加无线交互能力。
实现步骤:
- 配置HC-05蓝牙模块(AT命令设置)
- 手机端安装蓝牙串口APP(如"蓝牙串口")
- STM32接收串口数据并解析
- 根据指令调整PWM输出
串口通信处理代码:
// 在串口中断中处理数据 void USART1_IRQHandler() { if(USART_GetITStatus(USART1, USART_IT_RXNE)) { static char buffer[10]; static uint8_t index = 0; char c = USART_ReceiveData(USART1); if(c == '\n') { // 命令结束 buffer[index] = '\0'; Process_Command(buffer); index = 0; } else if(index < sizeof(buffer)-1) { buffer[index++] = c; } } } void Process_Command(char* cmd) { if(strncmp(cmd, "SPEED:", 6) == 0) { int speed = atoi(cmd+6); speed = constrain(speed, 0, 100); uint16_t pwm = map(speed, 0, 100, 0, 899); TIM_SetCompare2(TIM3, pwm); } }手机APP指令示例:
- "SPEED:50" 设置速度为50%
- "STOP" 停止电机
5. 智能光照调节系统:环境感知与自动控制
结合光敏电阻和PWM电机控制,我们可以创建一个能自动调节遮挡板角度的智能光照系统,适用于温室或家庭采光调节。
系统组成:
- 光敏电阻检测环境光照
- 直流电机控制遮光帘
- 手动/自动模式切换
- OLED显示当前状态
光照控制逻辑:
#define AUTO_MODE 1 #define MANUAL_MODE 0 uint8_t mode = AUTO_MODE; uint16_t light_levels[3] = {1500, 2500, 3500}; // 低、中、高光照阈值 void Auto_Light_Control() { uint16_t light = Read_Light_Sensor(); uint8_t speed; if(light < light_levels[0]) { speed = 0; // 光线很弱,完全打开 } else if(light < light_levels[1]) { speed = 30; // 中等光线,半开 } else if(light < light_levels[2]) { speed = 70; // 较强光线,基本关闭 } else { speed = 100; // 强光,完全关闭 } Set_Motor_PWM(speed); } // 在主循环中 while(1) { if(mode == AUTO_MODE) { Auto_Light_Control(); } // 其他处理... delay_ms(1000); }硬件优化建议:
- 为电机添加编码器实现更精确的位置控制
- 使用MOSFET替代ULN2003A以获得更高驱动能力
- 增加温度传感器实现多环境参数调控
- 添加WiFi模块实现远程监控
在完成这些项目后,你会发现STM32F103C8T6配合PWM和ULN2003A的组合几乎可以满足大多数小型电机控制需求。从简单的风扇调速到复杂的自动控制系统,限制你的只有想象力。