STM32F103C8T6+TB6612+直流电机PID控制

前言:

因后期需要使用32单片机控制直流电机做实验,实验需要对电机的精度、响应以及稳定性有一定的要求,但是目前有两个问题:

1、考虑使用的电机有点贵,不能直接购买;

2、PID控制思路仍不明确。

所以假借这几个模块先做个实验试试,为了节省开发时间,本次实验采用HAL库进行开发。

实验过程用到的模块包括:STM32F103C8T6单片机、TB6612FNG电机驱动模块、直流电机(带霍尔编码器,精度一般)、TFT128*128LCD屏显示模块、8v电源模块。

实验思路:

1、利用STM32输出PWM波传输给TB6612驱动模块,使之能够将电源的电压以自己想要的方式施加在电机上,控制电机速度。

涉及知识:GPIO引脚配置、单片机定时器、PWM输出控制、H桥驱动直流电机。

2、编写LCD驱动代码,使之显示相应的内容包括电机转动的正反向,电机的转速。

涉及知识:SPI驱动LCD屏幕、LCD屏字符转码、利用STM32单片机的定时器的输入捕获功能采集电机的电压、ADC采集、卡尔曼滤波、单片机定时器输入捕获。

3、编写电机转动的控制代码,加入PID控制算法,调试PID参数。

涉及知识:PID控制算法(这里推荐B站upDR_CAN老师的视频,大学如果学过控制基础的课程,不需要全部都看)、PID调参方法(这里没找到合适的资料、暂且先用尚硅谷老师的方法来调,后期会尝试多种PID控制算法)

4、加入串口部分,利用上位机串口调试助手测试及控制电机转速、如果时间足够将加入蓝牙模块、利用手柄控制电机。

涉及知识:USART串口传输数据、蓝牙+串口传输数据

5、使用FREERTOS进行任务调度(跟实验关系不大,主要是为了练练手)。

涉及知识:FREERTOS任务调度机制、消息队列、消息通知

6、加入姿态传感器反馈部分。(不是做平衡小车,但跟B站尚硅谷的平衡车项目有很大相似性,只能说很巧)

涉及知识:MPU6050(或MPU系列)、速度计算、加速度控制、计算姿态

目录

一、stm32+TB6612+PWM+电机驱动_tb6612stm32-优快云博客

二、stm32+spi驱动lcd+电机数据采集及显示-优快云博客

三、编码器采集数据优化-优快云博客

四、基于stm32控制编码器电机的PID控制+PID调参-优快云博客

五、stm32串口蓝牙模块通信实现

六、陀螺仪模块功能实现+利用FREERTOS完善实验

### STM32控制八路灰度传感器并使用PID算法完成循迹功能 以下是实现STM32通过八路灰度传感器进行循迹,并利用TB6612驱动两台带霍尔编码器的电机运转的示例代码。 #### 主要模块说明 - **硬件初始化**: 使用STM32CubeMX配置GPIO、TIM定时器PWM输出,用于控制TB6612芯片。 - **灰度传感器读取**: 利用ADC采集灰度传感器数据[^1]。 - **PID控制器**: 实现速度闭环控制,调整小车的速度偏差。 - **电机驱动**: TB6612作为H桥驱动电路,接收PWM信号调节电机转速。 --- #### 示例代码 ```c #include "main.h" #include "adc.h" #include "tim.h" #define NUM_SENSORS 8 // 灰度传感器数量 #define KP 0.5 // PID比例系数 #define KI 0 // 积分系数 (可选) #define KD 0.1 // 微分系数 // 定义全局变量 float error = 0; // 当前误差 float integral = 0; // 积分项 float derivative = 0; // 微分项 float last_error = 0; // 上一次误差 uint16_t sensor_values[NUM_SENSORS]; // 存储灰度传感器值 /** * @brief 初始化函数 */ void SystemInit(void) { MX_GPIO_Init(); // GPIO初始化 MX_ADC1_Init(); // ADC初始化 MX_TIM2_Init(); // TIM2 PWM初始化 } /** * @brief 获取灰度传感器数值 */ void ReadSensors(uint16_t* values) { for(int i=0;i<NUM_SENSORS;i++) { HAL_ADC_Start(&hadc1); // 启动ADC转换 HAL_ADC_PollForConversion(&hadc1, 100); // 等待转换结束 values[i] = HAL_ADC_GetValue(&hadc1); // 获取ADC值 } } /** * @brief 计算目标位置偏移量 */ int CalculateOffset(uint16_t* sensors) { int sum = 0; float weighted_sum = 0; for(int i=0;i<NUM_SENSORS;i++) { if(sensors[i] > 2000) { // 假设黑线对应高电平(具体阈值需调试) sum += 1 << i; // 权重计算 weighted_sum += i * (sensors[i]); // 加权求 } } return (weighted_sum / sum) - (NUM_SENSORS/2); } /** * @brief PID控制器 */ float ComputePID(float current_offset) { error = current_offset; integral += error; derivative = error - last_error; float output = KP * error + KI * integral + KD * derivative; last_error = error; return output; } /** * @brief 调节电机速度 */ void AdjustMotorSpeed(float correction_value) { uint16_t pwm_left = 1000 + correction_value; // 左轮基础占空比+修正值 uint16_t pwm_right = 1000 - correction_value; // 右轮基础占空比-修正值 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_left); // 设置左轮PWM __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, pwm_right); // 设置右轮PWM } int main(void) { SystemInit(); while(1) { ReadSensors(sensor_values); // 读取灰度传感器数据 int offset = CalculateOffset(sensor_values); // 计算偏离中心的距离 float pid_output = ComputePID(offset); // 执行PID运算 AdjustMotorSpeed(pid_output); // 调整电机速度 HAL_Delay(50); // 延迟一定时间 } } ``` --- ### 功能解析 1. **灰度传感器读取** - 使用`ReadSensors()`函数依次启动ADC通道采样,获取八个灰度传感器的数据。 2. **目标位置偏移量计算** - `CalculateOffset()`函数通过对传感器权重加权平均来判断当前车辆相对于轨迹的位置偏差。 3. **PID控制器设计** - PID参数(KP,KD)可根据实际情况微调。积分项(KI)通常设置较小或为零以防止过冲。 4. **电机速度调节** - 根据PID输出的结果动态改变左右轮的PWM占空比,从而纠正行驶方向。 --- ### 注意事项 - 编码器反馈可用于进一步优化速度控制精度[^2]。 - 如果未配备编码器,则可通过固定延时模拟短距离前进动作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值