STM32F103VC小车寻迹
STM32F103VC小车寻迹
针对使用STM32F103VC微控制器实现小车寻迹功能,以下是分步解决方案:
一、硬件设计
-
传感器模块
- 推荐使用4-5路TCRT5000红外传感器(或灰度传感器)
- 安装间距:15-20mm(根据实际路径宽度调整)
- 连接方式:DOUT引脚接STM32 GPIO(PA0-PA4)
-
电机驱动
- 推荐L298N或TB6612电机驱动模块
- 连接方式:
- PWM控制引脚:TIM2_CH1/CH2(PA0/PA1)
- 方向控制:PC0-PC3(IN1-IN4)
-
电源系统
- 7.4V锂电池供电(电机驱动)
- LM2596降压至5V(传感器)
- AMS1117-3.3V(STM32供电)
二、软件实现
1. GPIO初始化(传感器)
void Sensor_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
2. PWM初始化(电机控制)
void PWM_Init(uint16_t arr, uint16_t psc)
{
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_OCInitTypeDef OC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA0(通道1)和PA1(通道2)为复用推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 定时器基础配置
TIM_InitStruct.TIM_Period = arr;
TIM_InitStruct.TIM_Prescaler = psc;
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
// PWM模式配置
OC_InitStruct.TIM_OCMode = TIM_OCMode_PWM1;
OC_InitStruct.TIM_OutputState = TIM_OutputState_Enable;
OC_InitStruct.TIM_Pulse = 0;
OC_InitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &OC_InitStruct);
TIM_OC2Init(TIM2, &OC_InitStruct);
TIM_Cmd(TIM2, ENABLE);
}
3. 核心控制算法(PID调节)
#define KP 40.0f
#define KD 15.0f
int last_error = 0;
int Calculate_PID(int current_error)
{
int derivative = current_error - last_error;
int output = KP * current_error + KD * derivative;
last_error = current_error;
return output;
}
void Motor_Control(int pid_output)
{
int left_speed = 2000 + pid_output; // 基础PWM值2000(需校准)
int right_speed = 2000 - pid_output;
// 限幅处理
left_speed = (left_speed > 3999) ? 3999 : (left_speed < 0) ? 0 : left_speed;
right_speed = (right_speed > 3999) ? 3999 : (right_speed < 0) ? 0 : right_speed;
TIM_SetCompare1(TIM2, left_speed); // 左电机
TIM_SetCompare2(TIM2, right_speed); // 右电机
}
4. 主控制逻辑
int main(void)
{
Sensor_Init();
PWM_Init(3999, 71); // 72MHz/(71+1)=1MHz,50Hz PWM
while(1)
{
// 读取传感器状态(二进制编码)
uint8_t sensor_state = GPIO_ReadInputData(GPIOA) & 0x1F;
// 路径误差计算
int error = 0;
switch(sensor_state){
case 0b00011: error = -2; break;
case 0b00111: error = -1; break;
case 0b00110: error = 0; break;
case 0b11100: error = 1; break;
case 0b11000: error = 2; break;
default: error = last_error; // 丢失路径时保持上次误差
}
// PID计算并控制电机
int pid = Calculate_PID(error);
Motor_Control(pid);
Delay_ms(10); // 10ms控制周期
}
}
三、调试要点
-
传感器校准
- 使用万用表测量AO引脚电压,调节电位器使:
- 白底时输出电压 < 1.5V
- 黑线时输出电压 > 3.0V
- 使用万用表测量AO引脚电压,调节电位器使:
-
PID参数整定
- 先设KI=0,逐渐增大KP直到出现震荡
- 加入KD抑制震荡,典型比例 KP:KD ≈ 3:1
-
抗干扰措施
- 在传感器电源并联100μF电解电容
- 电机驱动电源与MCU电源完全隔离
- 软件添加去抖滤波(连续3次检测相同结果才确认)
实际应用中需根据具体车型(轮距、重心等)和赛道特性(弯道曲率、线宽)进行参数优化。建议先使用示波器观察PWM输出波形,再结合串口打印实时误差值进行调试。
CPPDEFINES = [\'STM32F103xB\']如何选择?
移植时SConscript中 CPPDEFINES = [‘STM32F103xB’]如何选择目标芯片:STM32F103VC
19.3-星曈科技 openmv Hopenmv发送五个uchar Openmv+STM32F103C8T6视觉巡线小车 STM32循迹小车系列教程
19.3-【星曈科技】openmv Hopenmv发送五个uchar Openmv+STM32F103C8T6视觉巡线小车 STM32循迹
2024-08-20 11:32:38
19.4-STM32接收数据-状态显示在屏幕 openMV寻迹与小车控制 Openmv+STM32F103C8T6视觉巡线小车
19.4-STM32接收数据-状态显示在屏幕 openMV寻迹与小车控制 Openmv+
2024-08-20 11:12:45
利用单片机STM32F103VC和GSM进行汽车指纹报警系统设计
电子发烧友网站提供《利用单片机STM32F103VC和GSM进行汽车指纹报警系统设计.doc》资料免费下载
资料下载
佚名
2023-11-07 15:14:46
基于STM32的麦克纳姆轮小车的寻迹实现
个人博客:http://www.chenjianqu.com/原文链接:http://www.chenjianqu.com/show-27.html 本项目用STM32F407,麦克纳姆轮小车,八路
资料下载
张莉
2022-01-14 11:40:58
DM9000时序怎么和STM32F103VC的FSMC A模式时序对上,其它模式可以吗?
问题:DM9000的时序时怎么和STM32F103VC的FSMCA 模式时序对上的,其它模式可以吗?有时候凭着感觉也能配置正确,但是还是觉得不是很清楚,希望大家可以指点一下,十分感谢!!!
STM32F103VC使用simulation和虚拟串口进行串口数据收发时,进不了IDLE中断的原因?
单片机:STM32F103VC,keil版本:5.18; 在使用simulation和虚拟串口进行串口数据收发时,数据能够正常发送,但是接收数据时,能进入接收中断,进不了IDLE中断, 各位有遇到过这种情况的吗?
意法半导体STM32F103RCXX系列型号解读
KB Flash、20 KB RAM,LQFP48封装; STM32F103VE:1 MB Flash、96 KB RAM,LQFP100封装; STM32F103VC:1 MB Flash、96 KB RAM,L
2023-08-24 18:54:49
STM32F103VC串口做输入打印到终端的方法
STM32F103VC下将串口作为输入打印到终端定义两个文件,一个是uart.c一个是uart.huart.h的代码:/*uart.h code
新手学习stm32f103vc的方法?
老师给买了一个stm32f103vc板子,不带触摸屏的,还有jtag v8。看了一点stm32固件库使用手册中文翻译版,现在初学,采用哪个KEIL uvision 4的版本比较好?已经安装
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- dtmb信号覆盖城市查询
- EDA是什么?有什么作用?
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 什么是场效应管?它的作用是什么?
- 如何进行编码器的正确接线?接线方法介绍
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- 苹果nfc功能怎么复制门禁卡
- amoled屏幕和oled区别
- 单片机和嵌入式的区别是什么
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 通讯隔离作用
- 苹果笔记本macbookpro18款与19款区别
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机
- 元宇宙概念龙头股一览