简介:基于STM32的恒流源设计完整方案,包含原理图、PCB、固件源码与仿真验证材料,适合电子工程师与电源控制学习者参考。方案采用意法半导体STM32微控制器,通过MOS管配合ADC与DAC输出,实现1至300毫安可调恒流,并融入PID算法提升稳定性,覆盖硬件电路到软件控制的完整链路。资源共507个文件,压缩后约29.38MB,主要包含C语言源码、Keil工程文件、Altium Designer设计文档及编译辅助文件,可按需提取核心内容。已有4008人学习下载,验证了参考价值;借助其中的电路图纸、程序框架和PCB布局,可快速理解恒流源的设计要点,并据此搭建或改进自己的系统。整套内容从电路原理到程序实现形成闭环,有助于掌握精密电流调节方法。
1. 恒流源设计课题:为什么用STM32做数字恒流而不是传统运放恒流
某高校电子类课程设计经常遇到这样一个题目:设计一个输出0~1A可调的恒流源,要求电流稳定、能显示、能设定。按照传统做法,一个运放加一个精密电位器就能完成恒流,但电位器调电流靠人手,温度一变电流就飘,想加个按键设定和数码管显示还得再搭一套逻辑电路,调试过程几乎靠手感。改用STM32做主控后,恒流的基准电压由PWM/DAC产生,实际电流由ADC采样回来参与闭环,设定值、显示值、校准值全部变成代码里的变量,温漂和器件误差还能通过软件校准压下去。这篇设计就沿着需求、方案、实现、验收四个环节把整条链路铺开,适合正在做恒流源课设或毕设的学生,也适合需要快速做一个可编程恒流源模块的工程师参考。
2. 总体方案设计:线性恒流拓扑与STM32系统结构拆解
2.1 控制拓扑选择:线性恒流为主,开关恒流不做主方案
恒流源的核心是把负载电流稳定在设定值,放大拓扑上主要有两类:一类是运放加MOS管构成的线性恒流,MOS管工作在放大区,靠消耗压差来吸收电流波动;另一类是Buck/Boost开关恒流,通过电感储能和高频开关稳压。做课设和一般仪器级恒流源,我一般先排线性方案,理由很直接:线性方案无电感、障碍少,运放反馈环一闭合电流就稳,纹波天然小;开关方案效率高,但多出来电感选型、续流二极管、环路补偿,PCB布局稍微不好就会出现辐射干扰和电流尖峰,时间紧的情况下特别容易翻车。
线性方案的代价集中在功耗上。假设输入电压12V,负载电压3V,输出电流1A,MOS管上的压降就是9V,消耗9W功率,需要做散热处理;如果把输入直接接到24V,功耗会到20W以上,这时候就要认真考虑加散热片甚至改用开关拓扑。做设计选型时先算这一个数:P等于输入电压减去负载电压再乘以输出电流,超过2W就要给MOS管加面积足够的铜箔,超过5W要加散热器,这也是答辩时老师最常追问的点。
决定用线性方案后,整体的控制思路就清晰了:STM32输出一个可调参考电压,运放把采样电阻上的电压死死盯住这个参考值,MCU再通过ADC把采样值读回来做修正。这个闭环分两层,下面把每一层拆开说明。
2.2 系统架构与模块划分
整个系统按功能可分成五个模块:主控模块、设定模块、恒流驱动模块、电流采样模块和人机交互模块。主控模块就是STM32最小系统,负责生成PWM、采集ADC、运行校准和PID算法;设定模块用定时器PWM加两级RC滤波,输出一个平滑的直流参考电压;恒流驱动模块由运放和MOS管构成,是恒流的执行核心;电流采样模块用采样电阻加ADC完成;人机交互模块用OLED显示设定电流和实测电流,配合按键修改数值。
信号流向是整个方案的灵魂,画框图时按这条路走:PWM占空比 → RC滤波 → 参考电压Vref → 运放负反馈环 → MOS管栅极 → 负载电流 → 采样电阻电压Vs → ADC采样 → STM32计算误差 → 修正PWM占空比。注意这里有两层反馈:第一层是运放硬反馈,速度快,保证电流跟随Vref;第二层是MCU数字闭环,速度慢,负责修正电阻温漂和系统误差。两层环各干各的活,这也是设计报告里最值得写清楚的创新点。
模块划分如下表,器件选型时对照着看:
| 模块 | 主要器件 | 关键参数 | 职责 |
|---|---|---|---|
| 主控 | STM32F103系列 | 72MHz主频、12位ADC | 产生PWM、采样、校准、显示 |
| 设定 | TIM1 PWM + 两级RC | PWM频率1kHz~20kHz | 把数字占空比变成模拟Vref |
| 恒流驱动 | 运放 + N-MOS | 轨到轨运放、逻辑电平MOS | 用负反馈稳定负载电流 |
| 采样 | 精密采样电阻 | 0.5Ω/0.1%精度 | 把电流转换成电压供ADC读取 |
| 人机 | OLED + 按键 | I2C接口 | 显示设定值与实测值 |
2.3 核心器件选型与关键参数估算
采样电阻放在整个电路的地回路里,取值需要综合权衡。按目标0~1A计算,采样电阻取0.5Ω时,满量程压降0.5V,这个电压刚好在单片机ADC的合理输入范围内,又不至于把运放的共模范围顶到上限;如果取0.05Ω,满量程只有50mV,运放失调和地噪声会把这个信号淹没,精度就靠不住了。取值偏大也不行,0.5Ω在1A下功耗0.5W,功率选型要选1W以上的合金电阻,否则温度升高后阻值漂移直接反映成电流误差。
运放选型上,LM358这类低带宽单电源运放通常够用,但要注意它输出能不能摆到接近电源轨。Vref最高可能到3.3V,运放输出要能驱动MOS管完全开启,普通LM358在3.3V供电下高电平输出只能到供电的2.8V左右,这时候最好选轨到轨输出的运放,或者把运放供电单独提升到5V。MOS管选逻辑电平N-MOS,栅极阈值电压要低于运放最低输出电压,导通电阻Rds(on)要小,在1A电流下管压降越低,发热越轻。
PWM设定通路的参数计算是另一个关键位置。PWM分辨率和滤波后的纹波是一对矛盾:定时器计数周期1000,占空比步进就是0.1%,对应电流步进约1mA;两级RC滤波的截止频率越低,纹波越小,但设定值响应越慢。通常的做法是PWM频率取1kHz到20kHz之间,RC参数按截止频率为PWM频率的1/10左右设计,第3章会给出具体数值。最后电源部分也要注意:用线性稳压芯片给模拟部分供电,数字地和模拟地在采样电阻附近单点连接,不然ADC读出来的数会飘得厉害。
3. 关键模块实现:从恒流电路到STM32闭环控制代码
3.1 恒流驱动电路:低端采样电阻加运放负反馈
电路实现采用低端采样方案,负载的高端接电源正,负载低端接MOS管漏极,MOS管源极接采样电阻后入地。运放的反相输入端接PWM滤波后的参考电压Vref,同相输入端接采样电阻电压Vs,输出直接驱动MOS管栅极。这个接法的闭环逻辑是:电流增大 → Vs升高 → 运放输出降低 → MOS管关小 → 电流回落,整个过程在微秒级完成,不需要MCU干预。
关键公式是Vref等于Iset乘以Rs。设定电流1A、Rs取值0.5Ω时,Vref需要0.5V,也就是PWM滤波后的平均电压要为0.5V。运放的失调电压在2mV以内时,等效电流误差约4mA,对1%精度要求影响不大,但如果采样电阻精度只有5%,这个误差会被放大成几十毫安,所以采样电阻精度至少要0.1%。低端采样的好处是Vs对地电位很低,单电源运放就能直接处理,不用差分电路;代价是负载不直接接地,产品化时要特别注意和外部设备的共地问题,做课设演示时这个问题不明显,但答辩老师可能会问。
3.2 用PWM加RC滤波实现可调参考电压
第一次做这个项目的人最容易纠结的问题,是STM32到底用内置DAC还是用PWM滤波。我的习惯是先看手头的芯片资源:STM32F103内置DAC只有12位,两个输出通道共用一个基准电压,走线要占用两个引脚;PWM加RC滤波方案不挑芯片,所有定时器都能输出,电路上只多两个电阻两个电容。DAC方案胜在纹波低、响应快,PWM方案胜在通用和便宜,课设场景下PWM完全够用,交作业的成本也更低。
RC滤波参数按照PWM频率1kHz设计:第一级R=10kΩ、C=1uF,第二级R=10kΩ、C=1uF,两级都接地。单级截止频率约16Hz,两级叠加后对1kHz方波基波的衰减超过60dB,理论上纹波在毫伏级别。需要说明的是,截止频率低会导致参考电压建立时间变慢,设定值改变后要等几个周期才能稳定,PID响应也要适当放慢,否则两者抢时间会出现振荡。
下面这段代码是初始化定时器产生PWM的核心逻辑:
// 使用TIM1_CH1输出PWM,PA8复用为PWM引脚 void PWM_Init(void) { GPIO_InitTypeDef gpio = {0}; TIM_OC_InitTypeDef oc = {0}; __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); // PA8配置为复用推挽输出,驱动RC滤波器 gpio.Pin = GPIO_PIN_8; gpio.Mode = GPIO_MODE_AF_PP; gpio.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &gpio); htim1.Instance = TIM1; htim1.Init.Prescaler = 71; // 72MHz/72 = 1MHz计数频率 htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; // 计数到999溢出,PWM频率1kHz HAL_TIM_PWM_Init(&htim1); oc.OCMode = TIM_OCMODE_PWM1; oc.Pulse = 0; // 初始占空比0,避免上电误触发 oc.OCPolarity = TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(&htim1, &oc, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); }预分频器设为71是把72MHz时钟分频成1MHz,计数周期设为999后PWM频率正好是1kHz。如果想提高PWM频率到10kHz,只需要把Period改成99,同时把RC滤波的电容缩小,例如两级各取0.1uF,补偿频率升高带来的纹波下降。占空比和电流的换算关系是:Pulse值等于Iset乘以Rs除以3.3V再乘以1000,0.5V参考电压对应Pulse约为152。
3.3 ADC采样电路与两点校准方法
采样电阻上的电压通过PA1引脚进入ADC1。ADC的参考电压和单片机的Vref绑定,如果板子上用3.3V稳压,默认满量程就是3.3V,所以采样电阻电压0.5V换算成ADC原始值约为620。直接拿这个值算电流会引入两类误差:一是采样电阻的实际阻值和标称值有偏差,二是运放和ADC存在零偏。用两点校准可以同时消掉这两类误差。
校准的具体做法是:第一步,PWM设0,读一次ADC原始值记为offset;第二步,用万用表实测一个已知电流,例如用恒定电阻负载把电流稳定在0.5A附近,读取ADC原始值记为raw,则增益gain等于raw减去offset再除以实测电流值,这一步把采样电阻和分压网络的比例都吸进了一个系数里。之后计算电流的公式就是ADC原始值减offset再除以gain,每次上电先执行一次,不依赖硬件修改。
// 单次ADC采样,取平均值减少随机噪声 uint32_t ADC_ReadAverage(void) { uint32_t sum = 0; for (int i = 0; i < 16; i++) { HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 10); sum += HAL_ADC_GetValue(&hadc1); } return sum / 16; }一定把ADC采样时间拉长到最大档位,片段里只写了循环取平均值,实际初始化时采样时间也要配置成最长档位,能明显减少参考电压毛刺和时钟噪声的混叠。校准系数建议存到备份寄存器或外部Flash,每次开机先读,不要让用户每次都重校准。
3.4 数字闭环:开环校准与PID修正两层实现
拿到ADC回读的实际电流后,控制层有两种实现路径。最简单的是开环校准:前期把占空比和实测电流的关系做成一张表,运行时查表输出,适合负载固定、温漂不明显的场景,代码量小,答辩时不至于被追问复杂算法。另一种是闭合PID环:把设定电流和实测电流的误差喂给PID,输出量叠加到PWM占空比上,这样做的好处是MOS管温度变化导致电流漂移时,环会自动拉回来,稳流效果更接近仪器级。
// PID控制器,位置式输出,带积分限幅 float PID_Process(PID_t *pid, float set, float cur) { float err = set - cur; pid->integral += err; // 积分限幅,防止积分饱和造成电流上冲 if (pid->integral > 30.0f) pid->integral = 30.0f; if (pid->integral < -30.0f) pid->integral = -30.0f; // 微分项默认关闭:ADC噪声会被放大成毛刺 // float d = pid->kd * (err - pid->lastErr); // pid->lastErr = err; return pid->kp * err + pid->ki * pid->integral; }P参数和I参数的初值按先P后I的流程调:P从0.02开始,观察电流阶跃响应,过冲了减半,响应太慢就加倍,等到稳态误差还消不掉再加I,I从0.01开始。注意运放的硬反馈环已经把大部分电流控制做完了,MCU的PID只负责慢速修正,P和I的数值通常比纯软件控制小一个数量级,调参时如果发现电流振荡,先怀疑RC滤波截止频率太低带来相位滞后,再怀疑PID参数过大,不要一上来就改代码里的参数。
写到这里把两层环的关系再说透:运放环恒的是“采样电阻电压等于参考电压”,MCU环恒的是“实测电流等于设定电流”,前者快,后者慢。如果把运放环做到完美,MCU环可以很轻;如果运放环有温漂,MCU环就把它补回来。设计报告里如果能画出两条环路的带宽关系,基本就能让评阅老师相信你理解了控制结构。
4. 常见问题与排查:恒流源调试最容易翻车的五个点
4.1 设定电流和万用表实测电流永远对不上
现象:写代码让输出500mA,万用表测到只有460mA左右,而且不同量程档位偏差不一致。这是第一次看到恒流源实测数据对不上时最容易被卡住的问题。
原因有两类。一类是采样电阻实际阻值不是标称的0.5Ω,贴片电阻标称精度5%的就很明显;另一类是运放失调电压叠加在Vs上,Vref等于Vs时,实际电流等于Vs除以Rs,但Vs里混了运放的2mV到5mV失调,折合到1A满量程就是1%量级的误差。
解决:换0.1%精度的合金采样电阻,同时做两点校准。校准先把PWM设到0,读offset;再输出一个已知电流,标定gain。做完校准后偏差基本上能压到0.2%以内,这是成本最低的精度提升手段,比换更高精度运放划算多了。
4.2 电流不是稳定的直流,而是低频振荡甚至啸叫
现象:输出端接示波器,电流波形出现几百赫兹到几千赫兹的正弦振荡;或者负载切换瞬间有明显的过冲和回摆,现场听起来还有嘶嘶声。
原因:MCU闭环和运放闭环在抢带宽。RC滤波截止频率设计得太低时,Vref从设定新值到稳定要几百毫秒,PID却在这段时间里继续输出纠正量,两者叠加成相位滞后,就表现为振荡。另一个常见原因是积分项没有限幅,误差持续累计导致过冲。
解决:先用排除法确定是哪个环在振荡。把PID的积分项清零,只用纯P,看振荡是否消失;如果消失就是积分饱和,加上限幅。如果仍然是低频振荡,把RC滤波的一级电容加大一倍,或者PID的P值先减半,每次只改一个变量,至少留出十分钟观察稳定时间。
4.3 PWM滤波后的参考电压纹波大,电流波形上有毛刺
现象:电流恒定后示波器能看到1kHz的锯齿纹波,幅度有几毫伏到几十毫伏,对精度要求高的测量直接不合格。
原因:两级RC的滤波效果没有发挥出来,通常是布局问题:RC地线离采样电阻地太远,地回路的压降被耦合进Vref;也可能PWM频率本身太低,1kHz基波能量太大,16Hz截止频率虽然能把基波衰减掉,但方波的谐波含量不小。
解决:把RC滤波部分的接地点单独连到电源地,不要和采样电阻的地共用同一段走线。同时可以把PWM频率从1kHz提高到10kHz,占空比分辨率从1/1000变成1/100,如果压低频率又想要原来的分辨率,就把计数周期改成9999并改用100kHz附近的RC截止频率,这个方向通常能同时改善纹波和分辨率。
4.4 上电瞬间电流直接冲到满量程,容易打坏负载
现象:电源和主控同时上电的瞬间,OLED还没亮起来,负载上已经通过了接近满量程的电流。
原因:STM32的GPIO在上电期间是高阻态,PWM引脚默认电平不确定;运放在MCU初始化完成之前已经开始工作,如果Vref被什么信号抬高了,MOS管立即全开。这是硬件方案里最容易坑人的地方,上电顺序决定了“先有鸡还是先有蛋”:运放先上电,而参考电压的控制权还在复位中的MCU手里。
解决:GPIO初始化成下拉输入,PWM通道启动前把Pulse设置为0再开启定时器输出使能;复杂一点的做法是加一个使能三极管或模拟开关串联在运放输出和MOS栅极之间,由MCU的一个普通GPIO控制,MCU初始化完成后再放开栅极信号。做这一条能避免绝大多数负载损坏事故。
4.5 ADC读数跳变,OLED显示电流值最后一位不停闪
现象:设定值不变,硬件也很稳,但显示电流值几百毫秒就跳几个字,看着不稳定。
原因:ADC采样时间太短,采样电容没有充分充电获得精确电压;或者参考电压Vref+本身有高频纹波,把噪声直接量化出来了。STM32的ADC是逐次逼近型,输入源阻抗高的时候,采样时间不足会直接引起跳码。
解决:采样时间选最长档位,信号链路上对地加一个10nF电容滤高频;软件上再做一次递推平均或者一阶低通滤波。一阶低通一行搞定:last等于last加上new减last除以16,每次新采样以16分之一的权重更新显示值,稳定性提升非常明显。要注意滤波带来的延迟,闭环PID计算用的是滤波前的原始值,不要用滤波后的值去当反馈,否则相当于又增加一拍延时。
5. 验收与答辩:用数据证明恒流源真的合格
5.1 验收测试流程与数据表
验收不要只看能不能亮灯,要按正式指标逐项测。我一般按三步走:先做安全性检测,空载状态上电,用示波器看电流波形有没有过冲;再做精度测试,分别设0.2A、0.5A、1A三档,用四位半以上万用表串联进负载回路读取实测值;最后做负载调整率测试,把负载电阻在2Ω到10Ω之间切换,记录电流变化量。负载调整率公式是最大电流减最小电流除以满量程电流再乘100%,恒流源仪器标准一般要求小于0.5%,课设做到1%以内就算及格,能给出三档测试数据表,答辩就有底气。
| 测试项 | 测试条件 | 合格标准 | 实测 |
|---|---|---|---|
| 电流精度 | 设定0.2/0.5/1.0A | 误差≤1% | |
| 负载调整率 | 负载2Ω→10Ω | 变化≤0.5% | |
| 动态过冲 | 负载突变 | 过冲≤5% | |
| 纹波电流 | 1A满载 | ≤10mV |
5.2 答辩要点与常见提问应对
答辩重点是讲清楚“两个环”:运放硬反馈环保证响应速度,MCU数字环消除系统误差。老师通常用“为什么不用DAC”“MOS管功耗怎么算”“采样电阻放在低端有什么问题”三个问题试探是不是真做过,回答时直接说“用了PWM加两级RC,低成本代替DAC,代价是响应变慢,但恒流源本身不需要毫秒级响应”,就把这颗雷排掉了。功耗问题把公式和数据摆出来:12V、1A、负载3V时管子功耗9W,加25平方厘米散热铜箔,稳定温升不超过40℃,这个数字一报,老师就知道这是实测过的。
每次做完验收,我都固化一个习惯:先测最危险的上电过冲,再测精度,最后才测纹波,顺序反了哪怕指标全过也会在答辩演示时被上电烧负载一击致命。这套从电路到代码再到验收的流程,希望能帮到你,把你自己的恒流源方案稳稳落地成一份有实物、有数据、能讲清原理的完整设计。
本文还有配套的精品资源,点击获取