ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于STM32F103的空气净化器完整设计实战

基于STM32F103的空气净化器完整设计实战 简介本资源是一套完整的基于STM32F103RCT6微控制器的空气净化器嵌入式开发资料面向嵌入式初学者、电子设计爱好者及物联网实践者解决室内空气质量监测与智能调控的实际工程问题。资源包共162个文件含38个头文件.h与36个源码文件.c覆盖传感器驱动温湿度、甲醛、PWM风扇控制、LCD显示及系统初始化等核心模块另有原理图.schdoc、PCB设计文件.pcbdoc、Keil工程配置.uvprojx/.uvoptx、编译输出.axf/.hex及调试脚本.bat完整呈现从硬件设计到固件烧录的全流程。压缩包大小为4.05MB结构清晰、模块解耦便于理解各外设ADC、TIM、GPIO、UART协同逻辑。目前已有1493人学习下载适合用于课程设计、毕业设计或STM32实战进阶可直接编译运行并快速验证多传感器融合与闭环控制效果。 先说下这套资料的成色。基于STM32F103的空气净化器设计资料我拿到手之后完整捋过一遍程序不是那种东拼西凑的Demo原理图不是缺线少网的截图PCB也不是只有孤零零一块板框。它是一套能直接编译、直接打样、能跑起来控制风机和显示PM2.5的完整工程。对于刚学完单片机基础、想拿一个真实产品练手的开发者或者正在做家居小电器方案选型的工程师这份资料的价值在于把STM32F103最常见的几大外设——PWM、ADC、DMA、I2C、定时器中断——全部放在一个真实产品场景里串了一遍。今天我把整个设计逻辑摊开讲一遍包括硬件选型、代码框架、PCB细节和调试中踩过的坑。1. 项目概述与整体设计思路1.1 空气净化器的核心功能拆解空气净化器这东西功能上看起来简单开风机、过滤空气、显示个空气质量。但真正落到产品层面控制逻辑比想象中要多一点。这套资料实现的功能我列一下按键开机/关机支持三档手动风速弱、中、强自动模式根据PM2.5浓度自动调节风速档位睡眠模式低转速、关闭指示灯、降低噪音实时显示PM2.5浓度、温湿度、当前风速档位定时关机功能0.5h / 1h / 2h / 4h紫外灯和负离子发生器的开关控制接口蜂鸣器按键提示音这些功能说多不多但每一块都要吃MCU的资源。风机转速靠PWM调速PM2.5检测靠ADC采样粉尘传感器的模拟电压温湿度用I2C读传感器显示用I2C或SPI驱动OLED按键和蜂鸣器占普通GPIO。整套系统跑下来STM32F103C8T6这种48脚的中配芯片资源刚好够用不会觉得局促也不会浪费。1.2 为什么选STM32F103作为控制核心选题阶段很多人会纠结空气净化器用51单片机不行吗用ESP32不行吗用Arduino不行吗说实话都能做。但这个项目选STM32F103有几个非常具体的理由。第一它主频72MHzCortex-M3内核跑空气净化器这种级别的控制算法绰绰有余而且未来想扩展WiFi通信、传感器融合算法算力都够。第二外设齐全TIM支持多路PWM输出ADC有12位分辨率且支持DMAI2C和USART都有这些外设组合起来非常贴合空气净化器这种“采集-处理-控制-显示”的典型架构。第三成本低、供货稳定、参考资料多遇到问题几乎都能找到现成解答。还有一个细节STM32F103的引脚大部分是5V容忍的这意味着按键、蜂鸣器这类5V逻辑的外围器件可以直接互连不需要额外加电平转换硬件设计省事很多。我实际做下来整板除了电源部分几乎不需要什么专用芯片设计难度就被拉低了不少。1.3 功能模块与引脚资源分配动手画原理图之前我习惯先做一张资源分配表把每个功能模块占用的引脚、用到的外设、通信方式全部列清楚。这样做的好处是后面画原理图、写代码、调板子遇到问题容易定位。下面这张表是我在这个项目中实际用的分配方案功能模块外设资源引脚说明风机PWM调速TIM2_CH1PA020kHz输出经MOS管驱动风机PM2.5粉尘传感器ADC1_IN1PA1DMA循环采样读取粉尘浓度电压温湿度传感器I2C1PB6 / PB7SHT30地址0x44OLED显示屏I2C1PB6 / PB7SSD1306地址0x3C与SHT30共用I2C总线按键K1~K4GPIO输入PB0~PB3开关机、模式切换、风速加减、定时紫外灯控制GPIO输出PB4通过三极管/MOS管驱动负离子发生器GPIO输出PB5通过三极管/MOS管驱动蜂鸣器GPIO输出PA8有源蜂鸣器低电平触发SWD下载调试SWDIO / SWCLKPA13 / PA14程序下载与在线调试串口调试预留USART1PA9 / PA10预留后续可接WiFi模块或蓝牙模块这里要提醒一句I2C总线上挂两个设备没问题但要注意地址不能冲突。SHT30默认地址0x44SSD1306常见地址是0x3C两个不冲突所以能共用一条I2C总线。如果你换别的型号传感器第一件事就是核对地址是否冲突否则会出现设备无法应答的诡异问题。2. 硬件设计从最小系统到整机电路2.1 STM32F103最小系统设计要点空气净化器的控制板核心就是STM32F103最小系统加上外围电路。最小系统这部分看似简单但很多人第一次画板子就栽在这里。我列几个关键点。时钟电路STM32F103用8MHz无源晶振两个负载电容取18pF到22pF。晶振的两个引脚分别接电容到地电容值不需要特别精确20pF左右就行。注意晶振底下尽量不要走其它信号线否则容易被干扰导致启动失败或者时钟频率不对。复位电路NRST引脚接一个100nF电容到地加一个10kΩ上拉电阻。这样上电时能保证可靠的复位。很多人画最小系统时把复位电路省了调试器连接时可能还能正常工作但实际产品上电瞬间芯片状态不确定很容易出现偶发性死机。BOOT引脚BOOT0必须通过10kΩ电阻下拉到地让芯片从Flash启动。BOOT1随便接一般也下拉。有时候下载失败排查到最后发现是BOOT0悬空电平不确定导致芯片没有正常进入用户程序这种问题最坑人。电源去耦每个VDD引脚旁边放一个100nF陶瓷电容尽量靠近引脚放置。VDDA引脚要单独接一个10Ω电阻再连3.3V同时对地接一个1uF100nF电容给ADC提供干净一点的模拟电源。这个问题和后面ADC采样数值跳变有直接关系。2.2 电源拓扑与风机驱动电路空气净化器的电源拓扑比普通单片机板要复杂一点因为系统里同时存在12V、5V、3.3V三种电源轨。我用的方案是外部12V DC适配器输入12V直接给风机和紫外灯供电12V经DC-DC降压到5V给传感器和蜂鸣器供电5V经AMS1117-3.3降到3.3V给MCU、OLED供电这里有一个设计取舍要说明一下为什么不直接用一个5V适配器然后风机也用5V因为大多数空气净化器的风机额定电压是12V或24V5V供电会导致转速上不去、风量不够。所以电源输入端直接按12V设计这样整机结构上更接近真实产品。如果你手头只有5V风机也可以简化成只用5V和3.3V两路电路会简单很多。风机驱动电路是硬件设计的核心。STM32的GPIO只能输出几毫安电流肯定不能直接驱动风机所以要在中间加一级MOS管。我用的是一颗N沟道MOS管型号可以选AO3400这类低导通电阻的管子。电路结构是PWM信号串一个100Ω电阻接MOS管栅极栅极对地接一个10kΩ下拉电阻防止MCU复位瞬间PWM输出高阻状态导致风机误转。MOS管的源极接地漏极接风机的负极风机正极接12V。风机线圈是感性负载所以MOS管漏极要并联一个续流二极管二极管负极接12V正极接漏极。这个二极管必不可少否则MOS管关断瞬间会产生很高的尖峰电压轻则造成系统复位重则击穿MOS管。另外紫外灯和负离子发生器这类负载功率不大用一颗NPN三极管比如S8050驱动就够了。注意继电器的场合不要用三极管这东西线圈电流太大必须用MOS管或者专门驱动芯片。2.3 传感器、显示与交互电路PM2.5检测我选用的是夏普GP2Y1010AU0F粉尘传感器。这个传感器是空气净化器里的经典方案淘宝上很容易买到价格也不高。它的输出是一个模拟电压浓度越高电压越高。但硬件电路有几个坑传感器内部有一颗红外LED需要周期性的脉冲驱动典型的驱动脉冲是10ms周期、0.32ms脉宽LED的驱动电流大概几十毫安。这意味着传感器不是简简单单三根线接上去就能用还得有LED驱动和运放调理电路。好在资料里已经把GP2Y1010AU0F的典型应用电路给出来了照着画就基本没问题。温湿度传感器我用的SHT30I2C接口精度和稳定性都比DHT11好不少。DHT11不是不能用只是它的时序靠软件模拟代码里容易因为中断干扰导致读取出错。而SHT30走硬件I2C不需要精确延时写代码省心很多。显示部分用0.96寸OLEDSSD1306控制器I2C接口只需要接VCC、GND、SCL、SDA四根线。OLED的显示内容我建议分成三个区域第一行显示当前模式和风速档位第二行显示PM2.5数值第三行显示温湿度。UI不用做得花哨黑色底白色字信息清楚就行。按键电路一定要做处理。直接用GPIO接按键到地内部上拉这是最简单的做法。如果担心EMC干扰导致误触发可以在按键两端并联一个100nF电容做硬件消抖。注意PCB布局时按键要放在结构上手指能按到的位置不然画出来好看但装进壳子里按不到就尴尬了。2.4 原理图设计里几个容易踩的坑原理图阶段踩过的坑我总结几次最耽误时间的。第一粉尘传感器的模拟输出线和风机PWM线在原理图里如果靠得太近打样回来后PM2.5数值会漂得离谱。这是因为PWM信号在PCB上会产生电场干扰而GP2Y1010AU0F的输出阻抗不低很容易耦合噪声。解决方法是模拟信号走线尽量短、尽量粗并且在传感器输出到ADC引脚之间加一个100nF滤波电容。第二I2C上拉电阻不能省。STM32内部虽然有上拉但驱动能力不够总线频率高了波形就会变形。我在SCL和SDA上各接了一个4.7kΩ上拉电阻到3.3V这个阻值是常规做法实测通信稳定。如果你把OLED和传感器都挂在这条总线上上拉电阻一定要加不然显示雪花或者传感器读不到数据。第三12V和3.3V电源轨的地在原理图上虽然都是GND但布局布线时要把电源地和模拟地分开处理。我采用的是单点接地整个PCB的地平面铺铜后在电源输入端附近汇合。这个做法能有效降低电机PWM开关噪声对ADC采样的干扰。后面PCB章节还会再详细讲。3. 程序框架与核心代码实现3.1 程序架构与工程组织程序部分我使用KEIL5开发环境标准外设库编写。使用HAL库的思路完全一样只是API名字不同。整个工程我按模块划分文件每个模块一个.c和一个.h大致结构如下main.c初始化外设主循环调度pwm.c风机PWM初始化及占空比设置adc.cADCDMA采样及滤波处理sensor.cSHT30温湿度读取、PM2.5浓度计算oled.cOLED显示驱动key.c按键扫描与事件处理control.c主状态机、模式控制和风机档位管理timer.c定时器中断作为系统时基这种模块化组织方式的好处是改动任何一个功能模块不需要牵扯其它文件。比如我后期想换一个传感器型号只需要改sensor.c主循环里的调度逻辑完全不用动。主程序的框架是一个超级循环加定时器中断。10ms的定时器中断负责按键扫描和LED闪烁这类时间敏感任务主循环负责较慢的传感器读取、显示刷新和模式控制。这样做避免了在一个大循环里用delay延时导致按键响应迟钝的问题。3.2 PWM配置与风机调速风机调速是空气净化器最核心的控制功能。我用TIM2的通道1产生PWM信号频率设为20kHz。为什么是20kHz而不是1kHz或者200Hz因为风机在低于15kHz的PWM频率下会发出人耳可闻的“滋滋”声20kHz接近人耳听觉上限噪音基本听不到。同时20kHz对MOS管的开关损耗也不大是一个比较均衡的选择。定时器时钟是72MHz要输出20kHz只需要做一次分频72MHz除以3600等于20kHz。所以我设置预分频PSC0自动重载值ARR3599输出比较寄存器CCR就是占空比。占空比从0到100%对应CCR从0到3599。三档风速我分别取占空比30%、60%、90%睡眠模式取20%这样既保证最低转速能维持空气循环又不会出现电机堵转。PWM初始化代码大致如下void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); // PA0复用为TIM2_CH1 GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period 3600 - 1; TIM_TimeBaseStructure.TIM_Prescaler 0; TIM_TimeBaseStructure.TIM_ClockDivision 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse 1800; // 初始50%占空比 TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM2, TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE); } void Fan_SetDuty(uint16_t duty) { TIM_SetCompare1(TIM2, duty); }这里有个常见错误定时器的时钟来自APB1APB1预分频如果不设置默认就是72MHz。如果你改过RCC的时钟树配置一定要用SystemInit默认的72MHz主频设置否则PWM频率计算会出错。我调试时遇到过PWM频率变成18kHz的情况查了半天发现是时钟树配置被改过。3.3 ADC采样、DMA与PM2.5计算粉尘传感器的输出电压要经过ADC转换变成数字量。STM32F103的ADC是12位分辨率采样范围0到3.3V。我使用ADC1的通道1对应PA1引脚采样模式配置为连续转换加DMA循环搬运。DMA的作用是让ADC自动把采样结果搬运到内存数组里CPU不需要每次转换完都进一次中断。我在内存里放了一个32个元素的数组DMA循环填充主循环里定时对这32个数做平均滤波这样能有效压低传感器输出中的随机噪声。ADC和DMA的初始化核心配置如下#define ADC_BUF_SIZE 32 uint16_t adc_buf[ADC_BUF_SIZE]; void ADC_DMA_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // PA1模拟输入 GPIO_InitStructure.GPIO_Pin GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN; GPIO_Init(GPIOA, GPIO_InitStructure); // DMA1通道1搬运ADC1数据 DMA_InitStructure.DMA_PeripheralBaseAddr (uint32_t)ADC1-DR; DMA_InitStructure.DMA_MemoryBaseAddr (uint32_t)adc_buf; DMA_InitStructure.DMA_DIR DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize ADC_BUF_SIZE; DMA_InitStructure.DMA_PeripheralInc DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode DMA_Mode_Circular; DMA_InitStructure.DMA_Priority DMA_Priority_High; DMA_InitStructure.DMA_M2M DMA_M2M_Disable; DMA_Init(DMA1_Channel1, DMA_InitStructure); ADC_InitStructure.ADC_Mode ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode DISABLE; ADC_InitStructure.ADC_ContinuousConvMode ENABLE; ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel 1; ADC_Init(ADC1, ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); }传感器输出电压和PM2.5浓度的换算这里要特别说明。GP2Y1010AU0F的输出电压和粉尘浓度近似线性但不同批次、不同环境下传感器的基准电压和灵敏度都有差异。资料代码里我留了一个宏定义做换算默认按浓度(输出电压-0.6V)*200计算单位ug/m3输出电压低于0.6V按0处理。这只是给调试用的参考值真正要做到比较准必须拿标准粉尘源做两点校准。如果你只是做样机演示这个换算关系完全够用。ADC采样还有一个硬性要求传感器LED脉冲和ADC采样时序要配合。GP2Y1010AU0F的LED脉冲宽度0.32ms必须在LED点亮之后的280us左右去采样得到的才是有效的浓度对应电压。这部分如果传感器模块已经集成了驱动电路就不用自己操心时序但如果买的是裸传感器就必须在程序里控制LED脉冲和采样间隔。资料里的代码用的是传感器模块所以主循环直接读AD值就行。3.4 OLED显示与按键扫描OLED显示驱动本身不复杂SSD1306的初始化代码网上到处都是。我讲两个容易忽略的细节。第一I2C通信时序要稳定建议把I2C时钟频率控制在400kHz以内STM32F103的I2C外设跑400kHz没有问题。第二OLED的刷新频率不用太高每秒刷新几次就够而且不要在主循环里刷一整个屏幕那样占用时间太多。我采用的方式是数据变化的时候才更新对应的区域通过设置显示坐标只更新变化的部分。这样主循环的CPU占用率很低可以腾出时间做别的事。按键扫描用10ms定时中断来做。每次进入中断读取四个按键的GPIO电平放入一个状态缓冲区然后通过边沿检测判断是短按还是长按。我实现的逻辑是短按按键按下时间小于1秒释放时触发一次按键事件长按按键持续按下超过1秒触发一次长按事件这样功能键、开关机键就可以区分短按和长按的操作。比如开关机键短按是开机/关机长按是进入睡眠模式。这种交互逻辑在实际产品里很常见代码实现也不复杂。3.5 模式控制与状态机空气净化器的状态我定义成4种待机、手动、自动、睡眠。整机运行的核心就是一个状态机状态切换条件来自按键事件和PM2.5浓度。手动模式最直接用户按下风速或风速-程序把档位值在1、2、3之间循环然后调用Fan_SetDuty设置对应的占空比。自动模式是重点。我设定两个阈值PM2.5小于35ug/m3判定为优风机转低档35到75ug/m3为良转中档大于75ug/m3转高档。这个阈值参考了空气质量标准实际可以根据产品定位调整。自动模式下的档位变化不是瞬时的我加了一个防抖逻辑——连续3次检测都超过阈值才切换档位避免浓度在阈值附近时风机频繁变速。睡眠模式的逻辑稍微特殊一点风机固定20%占空比OLED背光调暗或者直接关掉显示所有按键的LED指示灯也熄灭。这样夜间运行时不会产生光污染。定时关机我放在主循环里处理倒计时结束直接进入待机状态关闭风机和紫外灯同时OLED显示关机画面。时间基准用的就是定时器10ms中断里累计出来的秒数不开额外定时器。代码的模块化程度再强调一下主循环只负责调度具体逻辑都在各模块文件里。这五六个模块文件看下来整个控制逻辑是清晰可见的。后面如果要加空气质量历史曲线、手机APP控制都是在现有框架上扩展不需要重写底层。4. PCB设计布局、布线到打样4.1 布局分区思路PCB布局我采用的是功能分区法整板分成四个区域电源区、电机驱动区、主控区、接口区。分区的核心原则是强弱分离——大电流、高频开关的电路跟小信号模拟电路必须拉开距离。电源区放在板子一角包含DC输入端子、防反接二极管、DC-DC芯片、LDO和对应的滤波电容。电机驱动区紧挨着电源区因为风机电流就是从电源轨直接来的。主控区放在板子中间STM32F103、晶振、复位电路、去耦电容、SWD接口都在这里。接口区分布在板子边缘包括OLED接口、传感器接口、按键接口、蜂鸣器接口。为什么要这样分因为风机驱动线上的电流是脉冲式的会产生很强的电磁干扰如果主控区和驱动区混在一起ADC采样和I2C通信很容易被干扰。实际测试时我发现驱动区靠近传感器接口的话PM2.5数值会周期性跳动频率和PWM频率吻合把分区拉开之后问题就消失了。4.2 布线规则与层叠方案这个项目用两层板就能搞定不需要上四层。两层板的关键是地平面的完整性。布线规则我按电流大小来定宽度。12V电源输入线和风机供电线至少1.5mm宽最好能到2mm。5V电源线至少1mm宽。3.3V电源线0.5mm以上。信号线0.25mm到0.3mm都行。不要小看这条规则很多板子打样回来一开风机就重启就是电源线太细、压降太大导致的。晶振布线要特别注意晶振引脚的两根线走短走直并且尽量包地处理即晶振底下铺一圈地铜周围不要走其它信号线。我见过有人在晶振旁边走了一根PWM信号线结果系统时钟总是不稳定时好时坏最后查出来就是干扰问题。粉尘传感器的模拟信号线从接口到ADC引脚之间走的线要短旁边不要走数字信号线。可以在传感器信号线上串联一个100Ω电阻引脚处再加100nF电容到地组成一个低通滤波器能滤掉一部分高频干扰。过孔的使用也有讲究。电源引脚必须打两个以上过孔连接到另一层的电源网络单过孔在大电流下电阻偏大。地过孔越多越好因为过孔是连接顶层和底层地铜的关键通道数量少了地平面就不完整。4.3 出图打样前的检查清单出Gerber文件之前我强烈建议过一遍下面这些检查项都是实战中攒下来的经验检查所有的封装焊盘和实际元器件尺寸是否一致。电容电阻的封装比较容易看错0603和0805差一个数量级用卡尺量一下最保险。检查DC输入端的极性。防反接二极管的方向一旦画反上电瞬间就烧板。检查晶振两个负载电容是否都接到GND。很多人只画一个电容导致晶振起振困难。检查MOS管的D极和S极有没有接反。接反的话PWM怎么调风机都不转因为体二极管把电流直接旁路了。检查丝印是否压住焊盘。压在焊盘上的丝印会影响焊接尤其是表贴器件。检查定位孔的机械层是否正确。如果用AD画定位孔建议放在机械层1如果用立创EDA直接用板框工具画孔就行。DRC检查必须零错误。间距、线宽、钻孔尺寸、开路短路一个都不能放过。打样的时候我的建议是选嘉立创这类常规工艺板厚1.6mm铜厚1盎司绿油白丝印下单前看一眼板子尺寸控制在数量价优惠范围内。打样回来先不要急着焊全套芯片我习惯先焊电源部分确认3.3V、5V正常之后再焊MCU和相关电路。这样如果电源出问题不会把主控芯片烧掉。5. 调试实录与问题排查5.1 下载与启动问题打样回来第一件事就是下载程序。最常见的现象是KEIL提示“No target connected”或者“Cannot access target”。排查顺序我总结成四个步骤第一量MCU的VDD是不是3.3V地是不是真的连通第二量NRST复位引脚正常应该是高电平如果是低电平说明复位电路有问题或者芯片进入了复位状态第三确认BOOT0是低电平如果悬空或者被拉到高电平芯片会从系统存储器启动而不是用户Flash程序自然跑不起来第四确认SWD的四根线有没有接对——SWDIO、SWCLK、GND、VCC少一根都没法下载。还有一个不太容易想到的地方SWD占用的是PA13和PA14如果你在程序里把这俩引脚配置成了普通GPIO输出那程序第一次下载后第二次就下载不进去了。解决办法是在工程里把SWD的两个引脚配置为复用功能或者下载时按住复位键不放等KEIL连接上之后再松手。5.2 风机不转或者风速不受控风机不转先别急着怀疑程序。首先把PWM占空比设成100%也就是直接把输出拉高看风机转不转。如果还不转问题在驱动电路或者风机本体和程序无关。用万用表量MOS管的D极和S极电压如果D极一直是12V说明MOS管没有导通检查栅极电压有没有被拉到高电平如果栅极电压正常但MOS管不导通大概率是封装接反了。如果D极一直是0V说明电源没到风机检查供电线路和续流二极管有没有焊反。续流二极管焊反的典型现象是上电就发热甚至直接烧MOS管。风速不受控的问题多出现在PWM配置上。用示波器看PA0输出波形如果没有波形检查GPIO是否配置成了复用推挽输出TIM2的时钟是否已经使能。有波形但占空比不变那可能是软件里改的寄存器和实际输出不是同一个通道比如初始化的是TIM2_CH1设置比较值的时候却用了TIM_SetCompare2。5.3 PM2.5数值跳变ADC采样数值跳变是空气净化器调试里最烦人的问题因为它可能由好几个因素叠加导致。我第一次调的时候PM2.5显示值在0到500之间疯狂跳动电机一开数值就乱飞。排查步骤先关掉风机看读数是否稳定。如果关掉风机就稳定那说明是电机PWM干扰串到了传感器的模拟信号上这时候要在传感器输出加滤波电容同时检查传感器和电机驱动的走线间距。如果关掉风机读数还是跳那问题在ADC配置或者传感器供电上用万用表量传感器VCC是不是稳定的5V再看ADC的采样时间是不是太短。GP2Y1010AU0F输出阻抗较高ADC采样时间至少要配置到239.5个周期不能默认用最短采样时间。还有一点是软件上的滑动平均滤波的窗口大小会影响数据平滑程度和响应速度。窗口太小噪声压不住窗口太大浓度变化半天才反映出来。我实测下来32个点的窗口比较合适更新频率1Hz折中效果最理想。5.4 常见问题速查表我把调试过程中遇到比较典型的问题整理成一个速查表方便你对照排查现象可能原因排查思路无法下载程序BOOT0电平异常、SWD接线错误、芯片供电问题量VDD、NRST、BOOT0电平检查SWD接线可降低调试器速度PWM输出无波形TIM时钟未使能、引脚复用配置错误示波器查PA0检查AFIO时钟和GPIO_Mode_AF_PP配置风机不转MOS管未导通、续流二极管反接、电机损坏100%占空比测MOS管D-S电压确认驱动逻辑风机噪声大PWM频率过低确认PWM频率在18kHz以上建议20kHzPM2.5数值乱跳电机干扰、传感器滤波不足、ADC采样时间太短关电机对比测试传感器输出加100nF电容ADC采样时间调大OLED白屏I2C地址错误、SCL/SDA接反、上拉电阻缺失测SCL/SDA波形确认地址0x3C检查上拉电阻传感器读取数据为0I2C总线锁死、传感器地址冲突断电等几秒恢复I2C总线逐个挂载设备确认地址一开风机MCU就复位电源线太细、续流二极管缺失、DC-DC带载不足加大电源线宽检查续流二极管测12V在风机启动时的跌落波形个人体会整套资料啃完、板子跑起来之后我最大的感触是空气净化器这个项目麻雀虽小五脏俱全它把一个嵌入式产品开发最核心的几件事——需求拆解、资源分配、外设编程、PCB设计、整机调试——全部过了一遍。你做完这个项目之后再做其它小家电或者物联网设备基本上就是套用这套框架换传感器、换执行器的事。我建议拿到资料后不要急着改代码先把原理图从电源到MCU从头到尾看一遍再对照代码里每个外设的初始化逻辑最后看PCB每个元件的摆放位置。三样东西串起来之后你对这套系统的理解才算是完整的。后面如果想把产品做智能化给MCU加一个WiFi模块或者蓝牙模块通过串口协议和手机小程序通信STM32F103这边只需要预留一个USART接口控制框架完全不用大改。这就是我常说的先把底子打扎实后面怎么扩展都顺手。本文还有配套的精品资源点击获取
返回列表