尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

STM32智能小车开发全攻略:从硬件选型到八功能模块代码实现

STM32智能小车开发全攻略:从硬件选型到八功能模块代码实现 简介本资源是一套完整的STM32智能小车多功能开发套件面向嵌入式初学者、课程设计学生及电子竞赛备赛者解决多模态智能控制功能集成难、代码移植性差、硬件选型无依据等实际问题。压缩包共2000个文件75.35MB涵盖889个头文件h、325个源码文件c及大量编译中间文件o、d、crf、axf、hex等主体采用STM32 HAL库CubeMX生成框架所有功能模块均带中文注释结构清晰、接口规范便于理解与向标准库迁移。目前已获2775人学习下载覆盖循迹、红外/超声波避障、PID跟随、编码器测速、蓝牙串口遥控、WiFi远程控制、4G联网通信及LD3320语音识别等八大核心功能配套完整硬件清单与引脚定义说明可直接用于课程实验、毕业设计或智能车竞赛原型开发。 玩单片机这些年陆陆续续做过不少小东西但要说最能练手、最考验综合能力的项目STM32智能小车绝对排得上前列。一个底盘上同时塞下循迹、跟随、避障、测速、蓝牙遥控、WiFi图传、4G远程、语音识别这些功能基本把嵌入式开发里常见的传感器采集、电机控制、通信协议、状态机设计全过了一遍。这篇文章就把我完整做完的这版智能小车从硬件选型到各功能模块的代码实现从头到尾梳理一遍所有例程都是实测跑通的硬件清单也会完整列出来。很多朋友刚开始接触STM32小车容易犯一个毛病上来就买一堆模块结果接线接得乱七八糟代码东拼西凑最后哪个功能都没调通。我当初也是这么过来的所以这篇文章的顺序就按照“先整体设计、再硬件选型、然后逐个功能模块拆解、最后给调试经验”来写。不管你是准备做课程设计还是想自己DIY一台功能齐全的小车按这个思路走基本不会翻车。1. 项目整体设计与系统架构1.1 功能模块总览这辆小车最终实现的八大功能我列一下循迹通过红外反射传感器识别赛道黑线自动循迹行驶跟随基于超声波测距动态跟踪前方移动目标避障超声波传感器扫描前方障碍物自动规划转向绕行测速编码器定时器输入捕获实时测量左右轮转速蓝牙HC-05模块手机App发送指令手动控制WiFi板载ESP8266模块局域网内通过TCP/HTTP协议远程控制4G板载4G Cat-1模块实现公网远程控制和数据上报语音识别离线语音识别模块直接喊话控制小车动作这八个功能同时挂在一个STM32F103C8T6上CPU主频72MHzFlash 64KBRAM 20KB说紧张也紧张说够用也够用。关键是要做好资源分配和模式切换不能所有外设同时满载跑。1.2 主控选型与资源分配主控用的是最经典的STM32F103C8T6也就是大家常说的“最小系统板”。为什么选它便宜、资料多、引脚够用而且网上例程一抓一大把。虽然现在STM32F407、H750性能更强但对于这个小车项目来说F103完全撑得住。引脚资源分配我是这么规划的PA0-PA3编码器A/B相输入TIM2和TIM3的通道1/2PA6-PA7PWM输出TIM3通道1/2控制左电机PB0-PB1PWM输出TIM4通道3/4控制右电机PA8-PA11循迹模块5路数字信号输入PB6-PB7I2C或UART接口接OLED显示PB10-PB11USART3接蓝牙HC-05PA2-PA3USART2接ESP8266 WiFi模块PC10-PC11USART4接4G模块或语音识别模块PB12-PB14SPI接口预留方便后续扩展实际接线时可以根据手上的模块微调但一个原则必须守住定时器的PWM输出通道和编码器输入通道不要冲突否则调到你怀疑人生。1.3 分时调度与工作模式切换八个功能不可能同时全开比如循迹的时候蓝牙遥控指令来了到底听谁的这就需要定好优先级。我用的方案是外加一个拨码开关手动选择当前工作模式模式1自动演示循迹优先避障次之模式2遥控模式蓝牙/WiFi/4G指令优先模式3跟随模式模式4语音控制模式在代码里就是一个mode变量主循环里根据mode的值调用不同的控制逻辑。这样各功能模块互不干扰调试的时候也省心。2. 硬件清单与接线要点2.1 完整硬件清单下面这张表是我实际用到的所有硬件型号和数量都标出来了照着买就行。硬件型号/规格数量用途说明主控板STM32F103C8T6最小系统板1主控制器电机驱动TB6612FNG1驱动两个直流电机直流电机带AB相霍尔编码器1:30减速比2动力测速小车底盘2驱或4驱亚克力板底盘1车体平台电池7.4V 18650锂电池组1整机供电降压模块LM2596S可调降压模块2输出5V给主控和传感器循迹模块TCRT5000红外循迹传感器5循迹检测黑线超声波模块HC-SR041测距避障/跟随舵机SG901超声波云台可选蓝牙模块HC-051手机近距离遥控WiFi模块ESP8266-01S1局域网/云端控制4G模块移远EC200S或Air724UG1公网远程通信语音识别模块LD3320或ASR01离线语音模块1离线语音指令识别显示器OLED 0.96寸 I2C1显示速度/模式/距离蜂鸣器有源蜂鸣器模块1提示音开关自锁开关1电源总开关杜邦线公母/公公若干若干接线其中4G模块如果只是本地实验可以先用SIM7600CE或者EC200S这类Cat-1模块插一张物联网卡就能跑。注意4G模块功耗比蓝牙WiFi高不少供电要单独从降压模块出别跟主控抢电否则容易复位。2.2 供电系统设计供电是整个系统最容易出问题的地方。我刚开始直接把7.4V电池接到主控板Vin口结果电机一转芯片就复位OLED屏闪几下就重启了。原因很简单电机启动瞬间电流大把电源电压拉垮了。正确的供电方案应该是这样7.4V电池出线先接总开关然后分两路一路直接给TB6612的VM供电电机电源另一路经过LM2596降压到5V给STM32主控板、传感器模块供电主控板上的3.3V稳压再给ESP8266、OLED等模块供电如果你用的是四驱底盘电机电流更大建议在电池和驱动板之间加一个大电容1000μF以上能有效抑制电压波动。2.3 电机驱动与编码器接线TB6612是MOS管驱动芯片比老掉牙的L298N效率高、体积小我强烈推荐。TB6612接线VM接电池正极7.4VVCC接5V逻辑电源GND共地必须和主控共地PWMA/PWMB接STM32的PWM输出引脚AIN1/AIN2、BIN1/BIN2接GPIO控制方向A01/A02接左电机B01/B02接右电机编码器电机一共6根线电机两根粗线编码器两根电源红黑编码器AB相两根白绿或黄蓝。编码器电源一般接5V或者3.3V具体看电机型号我用的是5V供电输出信号经分压后进STM32。如果编码器输出5V电平直接接引脚STM32也能容忍但稳妥起见加个10K电阻分压更安全。接线这里有一个经常犯的错编码器A/B相接错定时器通道。STM32的定时器输入捕获必须接到对应通道上比如TIM2_CH1是PA0TIM2_CH2是PA1如果你把A相接PA1、B相接PA0也能测出速度但方向就反了最后PID控制就乱套。建议统一左电机编码器接TIM2右电机接TIM3对应的PA0/PA1、PA6/PA7。3. 核心功能模块一循迹系统3.1 循迹传感器的原理与安装循迹模块我用的是TCRT5000本质是一个红外发射管加一个接收管。红外光照射到黑色表面时吸收多、反射少接收管输出高电平照射到白色地面时反射强输出低电平。这样就能通过电平判断车轮是压在黑线上还是白地上。5路循迹传感器的安装位置很有讲究。我一开始把5个传感器排成一条直线装在车头正前方结果遇到小角度弯道时车还没转过来传感器已经全部偏出黑线直接冲出赛道。后来改成弧形排列中间三个靠近车头、两边两个稍微后缩这样能更早感知弯道方向。3.2 5路循迹的阈值校准每个传感器的灵敏度不一样安装高度、环境光也不一样所以不能直接拿别人代码里的阈值硬套。我第一次用网上抄来的阈值小车在深色地板上跑全部传感器都输出低电平直接“失明”。校准方法很简单把车放在白地上逐个读取传感器的模拟量记下白底值再放到黑线上记下黑线值取中间值作为阈值。如果你用的是数字量输出的循迹模块模块上有个电位器可以调节灵敏度调到指示灯临界翻转的位置就行。代码里我初始化时读一轮传感器动态设置阈值uint16_t threshold[5] {1500, 1500, 1500, 1500, 1500}; // ADC阈值 void LineSensor_Calibrate(void) { // 分别在白底和黑线上采样更新阈值 for (int i 0; i 5; i) { uint16_t white Read_ADC(i); // 读白底值 Delay_Ms(50); uint16_t black Read_ADC(i); // 读黑线值 threshold[i] (white black) / 2; } }3.3 循迹控制算法从开关量到PID最简单的循迹逻辑就是“开关量判断”哪边传感器压到黑线就往哪边打方向。这在小角度直道上还行一到S弯就左右摇摆、冲出赛道。我后来上了PID控制效果立竿见影。核心思路根据5路传感器的输出状态计算一个“位置偏差值”偏差范围比如从-100最左到100最右中间对应-0。然后把这个偏差喂给PID控制器输出调整量去修正左右电机的PWM占空比。位置偏差的计算我推荐加权平均法。5路传感器从左到右分配权重-100、-50、0、50、100哪一路检测到黑线低电平就用对应的权重值。多个传感器同时检测时取平均。int8_t Get_LinePosition(void) { // 返回 -100~100 的位置偏差 int16_t weight_sum 0; int16_t weight_total 0; int8_t weights[5] {-100, -50, 0, 50, 100}; for (int i 0; i 5; i) { if (LineSensor_Read(i) 0) { // 检测到黑线 weight_sum weights[i]; weight_total; } } if (weight_total 0) { return -128; // 丢失黑线返回特殊值 } return weight_sum / weight_total; }PID参数是调出来的不是算出来的。我的经验是先从P开始调P设小一点比如0.5观察小车转弯响应慢慢加到2.0左右然后再加I消除稳态误差I设0.01就开始有效果D用来抑制震荡设0.1起步。注意每个项目底盘重量、电机响应速度不同参数不能复制粘贴必须现场调。3.4 弯道丢失黑线的处理循迹小车跑丢线是家常便饭。以前我的处理是直接停车后来改进了一下检测到所有传感器都离开黑线时不立即停车而是根据上一次的位置偏差方向继续打方向跑一小段时间如果还找不到线再停车。// 主循环中的丢线处理 if (position -128) { // 上次偏差在左边继续左转找回黑线 Set_PWM(LEFT_SPEED - 30, RIGHT_SPEED 30); lost_time; if (lost_time 100) { Motor_Stop(); } } else { lost_time 0; }这个策略效果很明显过急弯的通过率从五成提升到九成以上。4. 核心功能模块二测速与电机闭环控制4.1 霍尔编码器与定时器测速原理测速这部分是很多新手最懵的。编码器电机内部有一个码盘电机转的时候码盘跟着转霍尔传感器检测码盘上的磁极变化输出方波脉冲。单位时间内数脉冲个数就能算出转速。STM32定时器有个编码器模式硬件上直接解码A/B两相脉冲不需要外部中断不停计数解放CPU。初始化流程配置GPIO为复用推挽输入配置TIM2/TIM3为编码器模式设置计数范围溢出周期读取CNT寄存器得到脉冲数关键代码void Encoder_Init(TIM_TypeDef* TIMx) { TIM_EncoderInterfaceConfig(TIMx, TIM_ENCODERMODE_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_SetAutoreload(TIMx, 65535); TIM_Cmd(TIMx, ENABLE); } int16_t Encoder_Get_Count(TIM_TypeDef* TIMx) { int16_t count TIMx-CNT; TIMx-CNT 0; // 读完后清零下次重计 return count; }4.2 速度换算公式从脉冲数到实际速度的换算公式转速(r/min) 脉冲数 / (编码器线数 × 减速比 × 定时器采样周期(s) / 60)拿我用的电机举例编码器线数13线即每圈输出13个脉冲减速比1:30定时器每50ms读一次。那么电机轴每转一圈编码器输出 13 × 30 390个脉冲如果50ms内读到390个脉冲说明电机输出轴转了一圈轮子直径65mm周长 0.065 × 3.14159 ≈ 0.204m1分钟转60圈速度 0.204 × 60 12.24 m/min这个换算在PID速度闭环里用于给目标值赋值。比如你想让小车跑0.3m/s目标就是每秒约1.47圈对应50ms脉冲数约29个。4.3 速度闭环PID控制算法实现没有PID速度闭环时小车电池电量足就跑得快、亏电了就跑得慢直线根本走不直。加上速度闭环后两个轮子各搞一个PID让实际速度跟随目标速度。速度环PID用增量式PID输出的是PWM占空比的增量这样不需要累加误差值代码简单int16_t Speed_PID(int16_t target, int16_t current) { static int16_t error_prev 0; static int32_t error_sum 0; int16_t error target - current; float Kp 0.3f, Ki 0.05f, Kd 0.1f; error_sum error; if (error_sum 3000) error_sum 3000; // 积分限幅 if (error_sum -3000) error_sum -3000; int16_t delta Kp * error Ki * error_prev Kd * (error - error_prev); error_prev error; return delta; // 叠加到原PWM上 }这个函数每个控制周期调用一次控制周期可以用定时器中断固定10ms。PWM的限幅一定做好我实测占空比超过90%电机就进入非线性区再往上加也没意义反而容易烧驱动。4.4 直行跑偏的滤波处理编码器数据会有少量抖动尤其车轮空转或路面打滑时。我用了一阶低通滤波int16_t filtered_speed 0.7f * filtered_speed 0.3f * raw_speed;这个公式虽然简单但能把高频抖动滤掉大半。直行时右轮和左轮的目标速度设成相同值依靠PID分别闭环就能保持相对直线。5. 核心功能模块三避障与跟随5.1 超声波测距时序与代码实现HC-SR04用起来就是一个“触发-回响”的过程给Trig引脚一个10μs以上的高电平脉冲模块内部发出8个40kHz声波脉冲同时Echo引脚拉高声波碰到障碍物返回模块收到回波后Echo引脚拉低。Echo高电平的时间就是声波往返的时间。距离(mm) Echo高电平时间(μs) / 58为什么除以58因为声速约340m/s往返距离是声波实际传播路径的两倍。Echo时间换算成距离如果是1ms声波走了340mm实际距离是170mm而1ms 340/1000 mm/μs 0.34mm/μs除以2得到0.17mm/μs。所以距离 时间(μs) × 0.17mm ≈ 时间/5.88 ≈ 时间/58单位mm。这个近似在工程上完全够用。代码用输入捕获或者直接延时读取都可以我用了外部中断测量高电平宽度void Ultrasonic_Trigger(void) { GPIO_SetBits(GPIOB, GPIO_Pin_9); // Trig拉高 Delay_Us(20); GPIO_ResetBits(GPIOB, GPIO_Pin_9); // 拉低 } // 在Echo引脚的外部中断回调中测量高电平时间然后换算距离 uint32_t echo_time; float Get_Distance_cm(void) { return echo_time * 0.017f; // 时间μs * 0.017 厘米 }5.2 避障控制策略分段决策避障只靠单一距离判断小车会像无头苍蝇一样乱撞。我用的策略是把前方距离分成三个区间距离超过40cm安全全速前进距离20-40cm减速同时看左右传感器数据决定微调方向距离小于20cm危险停车后判断障碍物方位如果超声波是固定的只测正前方那遇到侧面来车就检测不到。所以我加了一个SG90舵机每0.5秒扫一次角度0度、90度、180度形成简单的三方向雷达。舵机角度控制PWM占空比SG90的周期是20ms0度对应0.5ms高电平90度对应1.5ms180度对应2.5ms。配置定时器输出比较值换算一下就行。5.3 跟随模式实现跟随和避障的硬件一样但控制逻辑完全相反避障是遇到障碍物躲开跟随是遇到障碍物保持距离跟着走。我的跟随逻辑是距离大于30cm加速前进距离15-30cm停车或缓慢前进距离小于15cm后退为了让跟随更平滑我把PID控制移植过来了目标距离25cm实际距离作为反馈PID输出量控制小车速度。这样目标人物走快走慢小车都能平滑跟随不会一冲一停。5.4 多传感器数据融合的小心得超声波测距有一个弱点对吸音材料比如海绵、毛绒玩具、衣物测不准经常跳变。所以跟随模式下我用滑动平均滤波连续采5个数据取中值基本能滤掉异常值。uint16_t Sonar_Median_Filter(void) { uint16_t buf[5]; for (int i 0; i 5; i) { buf[i] Sonar_Read(); Delay_Ms(10); } // 冒泡排序取中值 for (int i 0; i 4; i) { for (int j 0; j 4 - i; j) { if (buf[j] buf[j1]) { uint16_t tmp buf[j]; buf[j] buf[j1]; buf[j1] tmp; } } } return buf[2]; }这个中值滤波比平均值滤波更能抗干扰因为超声波偶尔会出现一个特别大或特别小的错误值平均值会被拉偏中值不会。6. 无线通信模块蓝牙、WiFi、4G、语音识别6.1 蓝牙HC-05配置与手机遥控HC-05是我最早调通的无线模块。上电后模块有两种状态快闪是AT命令模式慢闪是透传模式。默认波特率9600长按模块上的按键上电就能进入AT模式。AT模式常用指令AT测试通信返回OKATNAMECar改蓝牙名称ATPSWD1234设置配对密码ATUART115200,0,0修改波特率配置好之后进入透传模式手机装一个“蓝牙串口助手”类的App连接小车的蓝牙发送指令控制小车。串口中断接收代码void USART3_IRQHandler(void) { uint8_t cmd; if (USART_GetITStatus(USART3, USART_IT_RXNE)) { cmd USART_ReceiveData(USART3); // 解析指令 switch (cmd) { case F: Motor_SetSpeed(300, 300); break; // 前进 case B: Motor_SetSpeed(-300, -300); break; // 后退 case L: Motor_SetSpeed(-200, 200); break; // 左转 case R: Motor_SetSpeed(200, -200); break; // 右转 case S: Motor_SetSpeed(0, 0); break; // 停止 } } }蓝牙模块的连接不上问题九成是波特率不匹配、共地没接、或者模块处在AT模式没切回来。HC-05上电时如果按键被按住或者KEY引脚拉高模块就一直在AT模式这模式下手机是搜不到蓝牙的。6.2 WiFi模块局域网与TCP控制ESP8266-01S虽然体积小但功能完整支持TCP/UDP/HTTP。我用它做两件事一是连接手机热点或路由器手机通过TCP客户端发指令二是通过HTTP模式发指令方便后期接入物联网平台。ESP8266用AT指令控制给串口发AT指令模块就会连接WiFi网络。流程是重启模块ATRST设置工作模式ATCWMODE1Station模式连接路由器ATCWJAPSSID,密码建立TCP服务器或客户端ATCIPMUX1ATCIPSERVER1,8080然后用手机或电脑的网络调试助手连接模块的IP发指令控制小车。代码里要处理TCP数据带有的 IPD 头这是很多新手被卡住的地方。比如Arduino发过来的数据是IPD,0,5:hello需要先用冒号定位再取后面的数据。我踩过最大的坑是供电ESP8266发射瞬间电流接近300mA如果稳压芯片输出能力不足会直接掉电重启表现为模块连不上WiFi、发送AT指令超时。解决办法是给ESP8266单独用一个3.3V稳压芯片供电不要在STM32板的3.3V引脚上硬扛。6.3 4G模块公网远程控制如果说WiFi是局域网控制那4G模块就是真正的公网远程控制。我在这个项目中用的是移远EC200S模块支持Cat-1网络插一张物联网卡就能上公网。4G模块和WiFi模块的代码逻辑很像都是串口发AT指令但多了拨号、找网、APN设置等步骤。核心AT指令流程AT\n 测试模块响应ATCPIN? 检查SIM卡状态返回READY表示卡识别成功ATCSQ 查信号强度返回类似 CSQ: 18,0 就是有信号ATCEREG? 查网络注册状态ATCGDCONT1,IP,CMIOT 设置APNATCGACT1,1 激活PDP上下文APN这个坑很大不同运营商的物联网卡APN不一样。移动一般用CMIOT联通用UNIM2M电信用CTLTE。写错APN就是连不上网但返回的错误信息还要看具体的模块固件。4G拨号成功后就可以用ATCIPSTART建立TCP连接连到公网服务器或者物联网云平台。我搭了一个简单的TCP服务器小车定时上报电池电压和速度数据手机端通过MQTT服务器发控制指令小车就能在全球任何一个有4G信号的地方被控制。6.4 语音识别模块离线语音控制语音识别我试验过两种方案。一种是LD3320非特定人语音识别不需要训练但识别率一般而且价格略高。另一种是现在很火的离线语音识别模块比如ASR01它需要电脑端SDK训练词条烧录到模块里识别率非常高而且价格便宜。ASR01模块用起来很简单接好串口后模块通过麦克风听到唤醒词然后进入识别状态识别成功后通过串口把对应的指令码发出来。比如我训练的指令用户说模块串口输出“小科小科”0xAA 0x01唤醒“前进”0xAA 0x02“后退”0xAA 0x03“左转”0xAA 0x04“右转”0xAA 0x05“停止”0xAA 0x06“循迹”0xAA 0x07“避障”0xAA 0x08主控串口收到0xAA开头的数据就做二次解析把它当成一个遥控指令处理。整个流程和蓝牙遥控非常像所以代码复用的程度很高我专门封装了一个RemoteControl_Parse(uint8_t *buf, uint8_t len)函数蓝牙、WiFi、4G、语音识别模块的指令最终都汇聚到这个函数里统一处理。这样设计的好处是新增一种通信模块只要改串口初始化其他控制逻辑完全不动。6.5 多通信模块共存串口资源分配蓝牙、WiFi、4G、语音识别模块都是串口通信而STM32F103C8T6只有3个USART和2个UART。串口分配如下USART1PA9/PA10调试串口连接USB转TTLUSART2PA2/PA3接ESP8266 WiFiUSART3PB10/PB11接HC-05蓝牙UART4PC10/PC11接4G模块UART5PC12/PD2接语音识别模块问题来了STM32F103C8T6没有引出PD2到排针我用的板子所以语音识别模块我改到USART2复用WiFi用SPI接口接的ENC28J60网卡方案这是另一套方案。如果你也遇到串口不够用的情况有两个解决方法一是用支持更多串口的STM32F103ZET6二是用软件模拟串口库。我建议直接换ZET6软件模拟串口在波特率波动大时容易丢数据。7. 软件架构与代码组织7.1 分层结构与代码目录代码写到3000行以上之后再往前翻找函数就痛不欲生。我强烈建议按模块分文件夹组织代码Project/ ├── Core/ │ ├── main.c │ ├── stm32f1xx_it.c ├── Hardware/ │ ├── motor.c │ ├── encoder.c │ ├── ultrasonic.c │ ├── linesensor.c │ ├── servo.c ├── APP/ │ ├── control.c │ ├── pid.c │ ├── remote.c │ └── mode_switch.c ├── Middlewares/ │ ├── oled.c │ ├── bluetooth.c │ ├── wifi.c │ └── lte.c硬件驱动层只管读写寄存器、初始化外设不关心业务逻辑应用层调用驱动接口实现具体的控制流程。这样调试循迹时不用管蓝牙调蓝牙时不用管电机非常清爽。7.2 主循环调度状态机设计主循环我用状态机组织每一帧检查传感器和通信数据然后根据模式执行对应动作while (1) { Read_Sensors(); // 1. 采样所有传感器 Process_Remote(); // 2. 处理远程指令 Update_OLED(); // 3. 刷新显示 switch (work_mode) { case MODE_LINE: Run_LineRobot(); break; case MODE_AVOID: Run_Avoid(); break; case MODE_FOLLOW: Run_Follow(); break; case MODE_REMOTE: Run_Remote(); break; case MODE_VOICE: Run_Voice(); break; } }状态机的好处是逻辑清晰、可读性强、后期加新功能只需要新增一个case。8. 常见问题排查与调试经验实录8.1 循迹类问题现象传感器全部输出高电平没检测到黑线排查步骤先量传感器供电是否正常5V→ 用万用表量输出引脚在黑白两色下的电平是否变化 → 调节电位器 → 检查安装高度一般1-2cm最佳。我遇到过一次是传感器全部接反了输出端焊到了VCC上怎么调都没用。现象小车循迹跑S型乱摆原因P参数过大。先把PID的I、D归零P降到0.3左右跑起来如果还是摆继续降到0.1。稳定后逐步加P直到出现临界震荡再回调到震荡值的60%.8.2 电机与编码器类问题现象电机不转或转一下停一下先确认DIR和PWM引脚的组合是否正确——TB6612如果IN1IN20电机刹车如果IN1IN21电机也是刹车。只有IN1≠IN2才转动。另外PWM频率不能太低我设的是10kHz太低会有明显噪音和扭矩下降。现象编码器读数为0先用手拨动车轮检查CNT寄存器的值是否变化。如果不变大概率是编码器A/B相没有接到定时器的正确通道或者编码器供电没接。8.3 无线通信类问题现象原因解决方案蓝牙连接不上模块在AT模式重新给KEY引脚低电平后再上电蓝牙连上但收不到数据波特率不匹配检查手机端和模块波特率是否一致WiFi AT指令超时模块供电不足独立3.3V电源供电加100μF电容WiFi收到乱码数据格式未解析正确截取IPD后的数据段4G信号弱天线没接好检查IPEX天线是否扣紧天线朝外4G无法附着网络APN错误确认运营商APN并修改语音识别不响应未配置唤醒词重新烧录语音模型8.4 供电类问题现象电机启动瞬间单片机复位这是最典型的供电问题。处理顺序先量电池空载电压是否足够 → 用示波器看电机启动瞬间的电压跌落 → 在电池输出加1000μF电容 → 将驱动板电源和主控电源完全分开。我最后换了两个LM2596一路专给电机驱动VM一路专门给逻辑电路系统再也没复位过。8.5 超声波类问题现象超声波测距稳定在0或者一个大于量程的固定值HC-SR04测量结果为0通常是Echo引脚没有正确捕获高电平时间检查回波信号是否真的到了。测量结果为固定值比如400多厘米通常是回声没回来模块内部超时溢出。环境有强噪声或者探头被灰盖住也会这样。另外要留意超声波工作电压接了5V才能正常工作3.3V供电会出现各种各样诡异的输出。9. 项目总结与后续扩展这个项目做下来我最大的感受是STM32智能小车不是一个“跑通就完事”的项目而是一个可以不断升级深挖的平台。八个功能全部调通你对STM32的定时器、串口、中断、PWM、PID控制、通信协议这些知识的掌握程度基本就到“熟练”级别了。如果你做完这个基础版本想继续扩展我列几个方向供参考第一摄像头循迹。把红外循迹换成OpenMV或者K210摄像头识别精度和场景适应性都会上一个台阶但随之而来的是更大的计算量建议换STM32H750或者加一个协处理器。第二加入RTOS。8个功能同时跑的时候裸机主循环的实时性会打折扣。把FreeRTOS移植进来超声波测距任务、PID控制任务、通信任务分别用不同的优先级调度系统的响应会更稳定。第三接入物联网云平台。4G模块已经具备联网能力再接上MQTT协议把小车数据上报到云平台再通过小程序或网页控制你就能做出一个真正“远程可控”的智能车。第四加视觉导航。光流传感器、IMU惯导、里程计融合做一个简单的室内定位导航系统。这个方向偏算法对数学要求高但收获也大。最后再分享一个小技巧所有串口通信的调试我都建议先用USB转TTL在电脑上模拟对端设备把AT指令流程全部跑通再接上单片机。这样能把问题隔离在“通信协议”和“硬件连接”两层之外调起来效率高得多。我当年就是因为跳过这步直接在单片机上调4G模块AT指令发出去半天没反应结果排查了好几天最终发现只是杜邦线接触不良。先电脑后单片机这是一个能帮你避开大量无用功的习惯。本文还有配套的精品资源点击获取
返回列表