尧图精选

基于STM32的智能小车设计与实现:PWM调速、循迹避障与灭火功能详解

🕒 发布时间:2026/9/21 1:16:39 📁 来源:尧图网络
简介这是一份围绕STM32F103C8T6微控制器的智能小车完整设计方案面向单片机初学者、嵌入式开发人员以及正在进行课程设计或毕业设计的学生。内容从硬件电路搭建到软件代码实现系统讲解了PWM调速、红外循迹、红外避障、障碍物跟随、超声波避障、红外遥控、测速以及灭火等核心功能的实现思路。设计文档详述了STM32F103C8T6最小系统、3.3V电源电路、程序下载电路、OLED接口、电机驱动等硬件模块并配有对应的软件说明与程序流程图便于理解代码逻辑和整体调试。资料包内为单个doc文档共61页、约14473字压缩包大小16.58MB内容凝练而完整。该资源已有9200余人学习下载可作为项目设计、课程设计或毕业设计的直接参考。 直接开工。这标题一看就是经典的课设/毕设套餐STM32F103C8T6这颗芯片在智能小车圈子里确实皮实耐用关键是资料多、例程全遇到问题基本都能搜到答案。我最初接触这个项目是在带学生做电子设计竞赛训练的时候后来自己也完整搭过一套从零开始焊板子到最终跑通全部功能前前后后折腾了小一个月。这篇文章就把整个设计过程、模块选型、代码逻辑和一些容易踩的坑完整梳理一遍给正在做类似项目的朋友一个参考。1. 项目需求拆解与整体方案设计1.1 功能需求梳理这个智能小车项目看起来很复杂功能一大堆PWM调速、循迹、避障、跟随、遥控、测速、灭火。但只要把需求拆开看本质上就是三件事感知环境、处理决策、执行动作。感知红外循迹传感器检测黑线、超声波模块测距、红外避障模块探测障碍物、火焰传感器寻找火源决策STM32F103C8T6作为主控芯片读取传感器数据根据预设逻辑判断下一步动作执行通过PWM控制电机转速驱动轮子转动实现前进、后退、转向、停止等动作1.2 为什么选STM32F103C8T6选这颗芯片有几个现实原因。首先是性价比高淘宝上最小系统板十几块钱一块功能却一点都不弱72MHz主频、64KB Flash、20KB SRAM跑这些传感器和电机控制的逻辑绰绰有余。其次是外设资源刚好够用多个定时器可以同时输出PWM、捕获编码器信号多个ADC通道可以采集传感器模拟量USART还能接蓝牙模块。还有一个很重要的点是资料极其丰富。不管是标准库还是HAL库网上都有大量现成例程GPIO控制、定时器中断、串口通信这些基础操作几乎不用从零开始写。即便是从51单片机直接跳过来的人跟着例程也能很快上手。1.3 整体系统架构整个系统分成三层感知层五路红外循迹模块TCRT5000、HC-SR04超声波模块、红外避障传感器、火焰传感器、编码器测速模块决策层STM32F103C8T6最小系统板负责所有传感器数据的采集处理运行控制算法执行层L298N电机驱动模块带两个直流减速电机外加一颗舵机控制灭火风扇的转向各模块之间的连接关系不算复杂核心是把电源分配好把信号线接对。下面列一下我当时整理的引脚分配模块引脚说明电机驱动IN1~IN4PB12~PB15L298N控制引脚电机驱动ENA/ENBPA0/PA1PWM输出左/右电机速度控制超声波Trig/EchoPA2/PA3测距触发与回波接收五路循迹PA4~PA8数字输出检测黑线红外避障左/右PB0/PB1数字输出检测障碍火焰传感器PA9ADC模拟量采集测速编码器A/BPB6/PB7TIM4正交解码模式蓝牙模块PA9/PA10USART1无线遥控通信灭火舵机PA11PWM控制风扇转向灭火风扇电机PA0另一路PWM转速控制电源方面需要注意L298N的电机供电建议单独用7.4V锂电池组不要和单片机共用一个电源。逻辑电压可以从L298N的5V输出口取但前提是电机负载不能太大否则电压跌落会导致单片机复位这个问题后面详细讲。2. PWM调速的实现逻辑与参数计算2.1 为什么需要PWM调速直流电机的转速控制有两种常见方式一是直接调节电压二是用PWM占空比调节等效电压。前者需要额外的DAC或者可调电源电路成本和复杂度都上去了。PWM方案只需要一个定时器通道就能实现通过改变高电平占空比等效输出电压连续可调这在嵌入式系统里几乎是最优雅的调速方案。还有个隐蔽的好处是PWM调速可以顺便控制启动电流。直接全电压给电机启动瞬间电流冲击很大对电源和驱动模块都不友好。用PWM软启动让占空比从0逐渐增大电流冲击会小很多。2.2 定时器配置与PWM频率选择我用的是STM32的定时器1TIM1高级定时器和定时器2TIM2通用定时器。TIM1输出的PWM接左电机PA0TIM2输出的PWM接右电机PA1这样两个电机就能独立调速。PWM频率的选择有个讲究。频率太低电机会发出明显嗡嗡声运转也不平滑频率太高MOS管的开关损耗增大驱动模块发热严重。比较合适的范围是10kHz到20kHz这个区间人耳听起来不刺耳常用的小功率MOS开关也扛得住。我当时设置的是10kHz。配置关键是自动重载值ARR和预分频系数PSC。芯片主频72MHz要得到10kHz的PWMPSC 71即72MHz/(711) 1MHzARR 99即1MHz/(991) 10kHz这样占空比就是CCR寄存器的值除以100从0到99对应0%到99%的占空比。代码里我封了一个简洁的调速函数void Motor_Speed(uint8_t left_speed, uint8_t right_speed) { // 限制占空比范围0~100 if(left_speed 100) left_speed 100; if(right_speed 100) right_speed 100; __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, left_speed); __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, right_speed); }2.3 差速转向的原理与实现智能小车转向方式分好几种靠前轮舵机转向类似真车、靠后轮差速转向坦克式、全向轮麦克纳姆轮平移。我们这种四轮小车最常用的是差速转向原理和坦克履带一致——左右轮速度不一致车身就会向慢的那一侧偏转。差速转向的参数需要实测校准。我之前遇到一个情况写死左右速度各50%占空比直线行走时小车总是往左偏。后来用测速模块一量发现两个电机在同样占空比下的实际转速差了挺多这是电机制造公差导致的。解决办法是在直行模式下给慢的那一侧加一点补偿速度实测调整之后直线走得比较正。下面这段是我在实际调试中用到的转向控制逻辑框架具体参数需要根据自己的小车微调void Car_Forward(uint8_t speed) { Motor_Speed(speed, speed - LEFT_COMPENSATION); // 补偿偏航 } void Car_TurnLeft(uint8_t speed) { Motor_Speed(speed * 0.6, speed); // 左轮减速 } void Car_TurnRight(uint8_t speed) { Motor_Speed(speed, speed * 0.6); // 右轮减速 } void Car_SpinLeft(uint8_t speed) { Motor_Speed(0, speed); // 左轮停止右轮驱动原地左转 }3. 循迹功能从单路到五路的传感器设计3.1 红外循迹的工作原理循迹模块的核心是红外对管——一个红外发射管和一个红外接收管。红外光照射到不同颜色的物体表面反射率不一样白色表面反射率高黑色表面几乎不反射。接收管收到反射光后输出电压发生变化再经过比较器电路转成数字电平。具体到TCRT5000模块遇到白色地面时输出低电平0V遇到黑色引导线时输出高电平3.3V或5V这个信号直接接单片机的GPIO读取就行。所以循迹算法本质上就是读一组数字输入判断当前车身相对黑线的位置决定转向方向和幅度。3.2 五路传感器比三路强在哪里市面上循迹小车方案有三路的也有五路的。三路能完成最基本的循迹任务但有几个先天短板一是判断不了弯道的曲率二是遇到十字路口容易迷失三是在黑线宽度不一致的赛道上适应性差。五路方案左1、左2、中、右2、右1优势很明显可以根据黑线落在哪几个传感器上来判断车偏离黑线的程度。比如只有中间传感器触发说明车很正可以全速直行左2触发说明车轻微左偏应该小幅右转左1触发说明车明显右偏需要大幅度转向。这里有个关键设计原则转向幅度应该和偏离程度成比例不能一偏离就直接打死方向那样小车会走S形摇摆路线。我用的策略是一个简单的分级查表逻辑uint8_t Read_Tracking(void) { uint8_t val 0; val | (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) 0); // 左1 val | (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) 1); // 左2 val | (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) 2); // 中 val | (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) 3); // 右2 val | (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) 4); // 右1 return val; } void Tracking_Control(void) { uint8_t pos Read_Tracking(); switch(pos) { case 0b00100: Car_Forward(SPEED_MAX); break; // 正中全速 case 0b00010: Car_TurnLeft(SPEED_MID); break; // 轻微左偏 case 0b01000: Car_TurnRight(SPEED_MID); break; // 轻微右偏 case 0b00011: Car_SpinLeft(SPEED_LOW); break; // 严重左偏 case 0b11000: Car_SpinRight(SPEED_LOW); break; // 严重右偏 case 0b00110: Car_TurnLeft(SPEED_HIGH); break; // 中弯左转 case 0b01100: Car_TurnRight(SPEED_HIGH); break; // 中弯右转 default: Car_Forward(SPEED_MAX); break; // 传感器全丢线时的兜底策略 } }重点说下这个default分支。如果四个轮子已经压在线上了五个传感器全都没有检测到黑线全为0这时候最忌讳的是直接停车。常见处理策略有两种一种是执行记忆搜索——保持上一次正确的转向方向原地旋转直到重新找到黑线另一种是直接直行一小段因为有可能只是短暂脱离。我在巡线比赛中实测下来记忆搜索策略的恢复成功率更高。3.3 环境光线对循迹的干扰循迹模块受环境光影响很大。红外接收管除了接收自身发射管反射回来的红外线也会接收太阳光和室内照明里的红外成分。在强光环境下即使没有黑线接收管也可能一直饱和输出导致模块误判为白色地面。这个问题的解决办法有几个层面。软件上可以在初始化阶段做一次校准记录当前环境光的基准值硬件上可以加遮光罩用热缩管把红外发射和接收管罩起来只留底部开口对准地面还有一种做法是调模块上的电位器找到环境光干扰和反射灵敏度之间的平衡点。我个人的经验是调试环境最好和比赛/实战环境的光照条件保持一致。上午调好的参数晚上比赛场地灯光一换循迹效果可能大打折扣。如果条件允许调试阶段就在最终使用环境中进行这能省下后面很多麻烦。4. 避障与跟随超声波和红外方案的取舍4.1 HC-SR04超声波测距超声波避障的原理是发射40kHz的超声波脉冲碰到障碍物反射回来根据发射和接收的时间差计算距离。声速约为340m/s距离等于时间差乘以声速再除以2来回双程。HC-SR04模块使用很简单Trig引脚给一个10微秒以上的高电平脉冲触发测量模块自动发射超声波然后把Echo引脚拉高高电平持续时间就是声波往返的时间。单片机这边用一个输入捕获定时器测量Echo高电平的时间。float HCSR04_GetDistance(void) { uint32_t tick; HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET); delay_us(15); HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET); while(HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) GPIO_PIN_RESET); // 等待Echo拉高 tick DWT-CYCCNT; // 记录起始时间 while(HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) GPIO_PIN_SET); // 等待Echo拉低 tick DWT-CYCCNT - tick; // 高电平持续时间CPU周期数 float time_us (float)tick / 72.0f; // 72MHz主频 return time_us * 0.017f; // 单位cm340m/s * time_us / 2 0.017 * time_us }上面这个代码里用了DWT计数器来精确计时这是Cortex-M3内核自带的调试计数器比反复翻转GPIO测时间可靠得多精度达到时钟周期级非常适合这种微秒级别的计时。4.2 超声波模块的局限性超声波看起来简单实际用起来坑不少。首先是测量角度问题。HC-SR04的发射波束大约有15度的半角障碍物表面如果不是垂直对着超声波探头反射波不会原路返回模块就测不到。这种掠射情况下实测距离会突然跳变到很大避障算法就会误判。另一个重要问题是多路径反射。在墙角、桌椅腿密集的环境里超声波可能经过多次反射才回来测出来的距离完全失真。因此通常需要做软件滤波比如连续测量三次取中值或者设定一个合理的变化范围超过范围的测量值直接丢弃。float Filter_Distance(void) { float samples[3]; for(int i 0; i 3; i) { samples[i] HCSR04_GetDistance(); HAL_Delay(15); // 留出超声波余振时间 } // 冒泡排序取中值 for(int i 0; i 2; i) for(int j i1; j 3; j) if(samples[i] samples[j]) { float tmp samples[i]; samples[i] samples[j]; samples[j] tmp; } return samples[1]; }4.3 跟随模式的设计思路跟随功能其实和避障是互逆的避障是让小车远离障碍物跟随是让小车保持和前方目标物的设定距离。同样是靠超声波测距但控制逻辑相反。我实现的跟随控制是分段式的距离小于20cm小车后退避免撞上前方的人或物体距离在20~30cm小车停止保持安全距离距离在30~50cm小车慢速前进缩小距离距离大于50cm小车全速前进追赶目标这种分段控制的缺点是不够平滑在边界附近容易来回抖动。改进方案是用PID控制把距离误差作为输入输出是电机的速度值距离远了加速距离近了减速过渡自然很多。但PID参数需要调Kp大了容易震荡Kp小了响应迟钝实际调试需要一点耐心。4.4 红外避障的优缺点红外避障传感器和循迹传感器原理相近但安装角度不同。循迹是朝下看避障是朝前方斜下方探测。红外避障的探测距离一般在2~30cm可调通过电位器旋转调节灵敏度。红外避障最大的优点是响应速度快信号是数字量直接判断有无即可不用像超声波那样等回波。但它的探测距离短小车全速前进时从探测到障碍到轮子刹停可能已经超出制动距离了。所以红外避障适合低速场景或者配合超声波做两级避障——超声波负责远距离预判减速红外负责近距离紧急刹车。我做避障策略时用的是超声波主避障红外辅助的架构void Obstacle_Avoid_Task(void) { float dist Filter_Distance(); if(dist 15) { // 近距离红外传感器决定转向方向 uint8_t left_block Read_IR_Left(); uint8_t right_block Read_IR_Right(); if(!left_block right_block) Car_SpinLeft(SPEED_LOW); else if(left_block !right_block) Car_SpinRight(SPEED_LOW); else Car_SpinLeft(SPEED_LOW); // 两方向都有障碍默认选左转 } else if(dist 30) { if(rand() % 2) Car_TurnLeft(SPEED_MID); else Car_TurnRight(SPEED_MID); } else { Car_Forward(SPEED_MID); } }避障转向方向的选择有个小技巧如果用永远优先左转的策略在四面都是墙的迷宫里会陷入死循环。可以在转向前加一个微小的随机因子或者记录最近几次转向方向如果连续三次都是同一个方向强制换边。这个方法工程上叫随机避障或记忆避障虽然不能保证找到最优路径但至少在复杂场景下不会被困死。5. 遥控、测速与灭火多功能集成的扩展细节5.1 蓝牙遥控的实现蓝牙遥控我用的HC-05模块通过USART1和STM32通信。手机端用蓝牙串口助手APP发送字节指令比如F - 前进B - 后退L - 左转R - 右转S - 停止0~9 - 设置速度等级代码实现上最大的坑是HC-05模块的默认波特率是9600而很多人喜欢直接把STM32的USART配置成115200。两者对不上串口收到一堆乱码。排查半天最后才发现是波特率设置不匹配这种低级错误最浪费时间。HC-05还有一个特性是AT指令模式按住板载按钮再上电就能进入AT模式可以修改名称、密码、波特率等参数。我一般会把波特率统一改成115200和其他调试串口保持一致。另外蓝牙模块的电平是3.3V可以直接连接STM32的USART引脚但有些HC-05模块的VCC需要5V供电接到3.3V上可能工作不稳定。上电前最好确认下模块说明书。5.2 测速模块与闭环调速测速用的是霍尔编码器电机电机尾部带一个圆形磁环上面均匀排布霍尔元件感知磁场变化转一圈输出一定数量的脉冲。我用的是13线编码器配合电机减速比1:30轮子转一圈大概输出390个脉冲。STM32的定时器4可以配置为编码器接口模式硬件自动完成脉冲计数和方向判断不需要CPU干预这对实时性要求高的场景来说很省心。需要读速度时定时器计数值除以采样周期就能得到转速。测速之后可以做闭环调速——目标是解决同样占空比下不同电机的转速差异以及电量下降后相同占空比转速变慢这两个问题。我在实际测试中发现电池电压从8.4V降到7.2V时相同占空比下电机转速大约下降15%~20%如果开环跑巡线效果会随着电量下降逐渐变差。加了PID闭环之后无论电量高低实际转速都能锁定在目标值附近。5.3 灭火功能的传感器方案灭火模块用的是火焰传感器。火焰燃烧时会产生特定波长的红外线火焰传感器里面是红外接收管配合一个窄带滤光片可以识别火焰特征。火焰传感器输出分为数字量和模拟量两路我建议用模拟量接ADC采样这样可以同时获得火源的方向和强度信息。我把火焰传感器装在一个由舵机驱动的转台上让传感器左右扫描比较两个方向的火焰信号强度转向火焰更强烈的一侧然后启动风扇电机吹灭蜡烛。这里的舵机控制用的是50Hz的PWM信号对应周期20ms占空比0.5ms~2.5ms对应0~180度。提前说一个容易忽略的坑灭火电机的启动电流很大瞬间可能达到1A以上如果电池电量不足或供电线太细电机启动时会把电源电压拉低单片机直接复位。后来我在风扇电机的电源两端并联了一个470uF电解电容利用电容的储能特性缓冲电流冲击复位问题基本解决。5.4 多模块整合时的资源冲突功能多了必然会遇到资源冲突问题。我最开始设计时把舵机PWM和电机PWM都放在TIM1上结果发现两个通道的自动重载值没法独立设置——电机PWM要10kHz舵机要50Hz频率差太远共用一个定时器根本不行。后来把舵机单独挪到TIM2问题才解决。串口资源也一样蓝牙遥控用USART1测速编码器用TIM4超声波计时用DWT火焰传感器ADC用PA9各个外设之间要统筹规划。启动项目前先花半小时把引脚分配表画出来比做到一半发现冲突再返工省事得多。6. 系统集成调试经验从单模块验证到整车联调6.1 分模块验证的必要性千万不要直接把所有模块一次性接好然后上电跑整个程序。这种一把梭的做法出问题的时候非常难排查——你根本不知道是传感器问题、代码逻辑问题还是接线问题。正确的调试顺序是先点亮板载LED确认最小系统正常工作单独测电机驱动用固定占空比让电机转起来确认方向和调速正常测循迹模块把小车放在黑线上看串口打印的传感器状态测超声波测距用手在探头前移动看距离数据变化是否符合实际测蓝牙通信确认指令收发正常各模块都正常后再整合到一起联调每个模块的验证最好都配合串口打印把关键变量输出到串口监视器。传感器输出的数值直接看比猜效果要快太多。我调试循迹的时候把五路传感状态编码成一个五位二进制数打印出来小车一放上赛道从串口就能一眼看出每个传感器的状态排查问题效率高了一倍不止。6.2 硬件层面的常见问题排查硬件折腾得多遇到的故障也就多了。下面几个是出现频率最高的小车跑起来单片机就复位电源问题电机启动瞬间拉低电压。排查方法测电机启动瞬间单片机供电电压如果跌落超过0.3V就把电机电源和逻辑电源彻底分开或者在电机电源两端加一个大电容。电机方向反了把L298N输出端到电机的两根线对调就行不用改代码。或者反过来保持接线不变直接在代码里把PWM值和方向引脚逻辑取反。循迹模块装太低刮地面模块到地面的距离建议5~10mm太高会检测不稳定太低会被地面刮碰。安装支架既要考虑传感器也要给前面留出缓冲空间。超声波读数偶尔跳变先确认是不是滤波不够再看探头表面有没有灰尘遮挡最后看电源有没有波纹干扰。超声波模块对电源质量比较敏感可以在模块供电端加一个10uF陶瓷电容。6.3 代码架构用状态机管理复杂功能功能多的时候如果都用while循环嵌套处理代码会越来越乱加一个功能就得改一堆逻辑。我推荐用状态机来管理整车的运行模式。typedef enum { MODE_REMOTE, // 遥控模式 MODE_TRACK, // 循迹模式 MODE_AVOID, // 避障模式 MODE_FOLLOW, // 跟随模式 MODE_FIRE // 灭火模式 } Car_Mode; Car_Mode current_mode MODE_REMOTE; void Mode_Switch_Task(void) { // 每100ms检查一次是否收到模式切换指令 // 通过蓝牙串口接收指令 uint8_t cmd Bluetooth_GetCommand(); switch(cmd) { case 1: current_mode MODE_REMOTE; break; case 2: current_mode MODE_TRACK; break; case 3: current_mode MODE_AVOID; break; case 4: current_mode MODE_FOLLOW; break; case 5: current_mode MODE_FIRE; break; } } void Main_Control_Loop(void) { while(1) { Mode_Switch_Task(); switch(current_mode) { case MODE_REMOTE: Remote_Control_Task(); break; case MODE_TRACK: Tracking_Control(); break; case MODE_AVOID: Obstacle_Avoid_Task(); break; case MODE_FOLLOW: Follow_Target_Task(); break; case MODE_FIRE: Fire_Detection_Task(); break; } HAL_Delay(10); // 控制主循环周期约100Hz } }状态机的好处是代码清晰扩展新功能只需要加一个枚举值和一个case分支主线逻辑完全不用动。后来我加了模式切换提示音和OLED状态显示都是在状态机框架上小改没有经历返工。6.4 灭火任务的状态机细节灭火这个功能单独说下因为它不像循迹那样是简单的闭环控制而是多步骤的任务流程。我把灭火拆成几个步骤初始状态舵机归位到90度风扇停转检测状态舵机左右扫描采集火焰传感器ADC值确定火源方向转向状态小车转向火源方向同时持续检测确认接近状态小车向火源前进注意火焰传感器的距离趋势太近了要减速防止把蜡烛撞倒灭火状态距离合适后启动风扇电机同时左右微调舵机扇风位置确认状态火焰传感器ADC值降低判断火已熄灭风扇停转返回初始状态针对这个流程灭火逻辑内部同样用了子状态机来管理便于状态切换和异常处理。比如检测状态里如果扫描了一圈都没找到火焰就回到初始状态重新开始。这套设计在多次调试中表现比较稳定。7. 嵌入式开发的工程化建议如何把课设做出项目感7.1 代码注释和版本管理代码规范看起来是老生常谈但很多同学课设交完就不再碰了代码里全是魔法数字和和意义不明的变量名。这里有个很实际的建议每个主要模块写清楚输入输出类型、数据范围和关键参数的物理含义三个月后再回头看你会感激当初留的注释。版本管理不用搞Git这种重型工具但也建议按日期或者功能版本做好保存。我习惯的做法是每次大功能跑通就复制一份代码命名为track_v1.0_0521这种格式万一改坏了还能回退。另一个值得养成的习惯是在关键代码前加上调试宏开关方便随时切换调试模式和正常模式// 宏定义控制调试信息是否输出 #define TRACK_DEBUG_ENABLE 1 #if TRACK_DEBUG_ENABLE #define TRACK_DEBUG(format, ...) printf([TRACK] format \r\n, ##__VA_ARGS__) #else #define TRACK_DEBUG(format, ...) #endif7.2 方案文档的重要性做项目不仅要会写代码还要会写文档。这个项目的标题是.doc说明最终是要有一份完整的项目设计文档配套代码和实物才能形成闭环。技术文档的撰写有几个实用技巧先画系统框图把模块之间的信号流向画清楚这是文档的骨架每个功能模块先用一段话概述原理再给出关键代码片段和解释测试数据和调试记录放最后作为系统验证的依据遇到的关键问题和解决方案单列一节这是整篇文档的加分项7.3 预防性设计保护电路与扩展接口最后建议在硬件设计上多留些余量。在电机电源输入端加一个自恢复保险丝防止堵转时电流过大烧坏驱动芯片在传感器电源输出端加一个二极管做反接保护防止误插电源烧板子。同时在PCB或洞洞板设计上多预留几个2.54mm排针作为备用接口把空闲的GPIO都引出来。后续想加OLED、蜂鸣器、GPS模块或者OpenMV摄像头的时候直接插上就能用不用反复飞线。这个习惯是跟做产品的前辈学的一个方便扩展的方案能省掉后续无数次重新搭板子的麻烦。整套做下来让我觉得值得的其实是那个遇到问题—定位—解决的过程。比如电源干扰导致复位、超声波数字跳动、PID参数震荡每一个问题排查的过程中对嵌入式系统的理解都会深入一层。这种积累的东西之后做任何控制器项目都用得上这也是这类多功能项目值得投入时间好好做一次的原因。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →