新闻详情

新闻详情

首页 / 资讯中心 / 详情

51单片机+DAC0832的0-15V数控直流电源设计与Proteus仿真

发布时间:2026/9/16 2:36:49来源:尧图网络
51单片机+DAC0832的0-15V数控直流电源设计与Proteus仿真
简介一份基于51单片机与Proteus仿真的0-15V数控直流稳压电源完整设计资源包面向电子类课程设计、毕业设计及电源设计入门学习者。系统以51单片机为核心结合DAC0832实现数字可调输出利用ADC0808采集电位器状态调节电压并通过运放电路完成0-15V直流放大输出数码管实时显示电压值覆盖了从信号采集、数模转换到功率输出的完整链路。资源共35个文件包含Proteus仿真工程dsn/pdsprj、Keil程序源码c/a51/hex、PCB版图文件lyt/pdsbak以及说明文档与文本文件等压缩包整体仅325KB结构紧凑便于直接打开学习。目前已有189人浏览学习适合需要快速获取完整方案、进行仿真验证或二次开发的读者。借助仿真、程序与PCB设计可直观理解数控电源的软硬件协同工作方式节省从零搭建的时间成本。1. 为什么用DAC0832而不是PWM做0-15V数控电源把一个基于51单片机Proteus仿真的0-15V数控直流稳压电源设计拆开讲最值得先回答的问题不是“怎么接线”而是“为什么是这个方案”。整条链路非常经典51单片机做核心控制DAC0832把8位数字量转成模拟量运放把DAC的输出再放大三倍最后得到0-15V可调直流输出。设定电压不是靠电位器直接分压而是让ADC0808读取电位器电压再交给单片机换算成DAC码。这种数字设定方式比PWM加RC滤波更适合作仪表级电源因为纹波和响应速度更可控。资源包内有仿真文件、C程序和PCB图适合做课程设计或想把数控电源原理吃透的人。2. 数字调压链路与关键选型从ADC设定到运放输出2.1 信号传递路径与每级电压范围先建立系统级认识。这个真实工作链路可以拆成四个环节设定电位器 - ADC0808采样 - 51单片机换算 - DAC0832输出 - 运放放大 - 0-15V输出电位器两端接5V中间抽头接ADC0808的IN0。转动电位器时ADC把0-5V模拟电压映射成0-255数字量。单片机拿到这个值后直接写进DAC0832DAC输出电压也落在0-5V范围最后由末级运放放大到0-15V。这种设计的关键在于ADC和DAC都是8位线性对应不需要复杂查表。有一个容易绕晕的地方ADC基准电压和DAC基准电压必须一致。这里ADC0808的Vref和DAC0832的Vref都接同一路5V此时旋转电位器从0读到255DAC输出也从0走到满刻度最终输出电压线性变化。如果两边基准不一致输出曲线就会出现“一段密、一段疏”的非线性。整个环路是开环工作输出端没有反馈运放的放大倍率、DAC增益误差、电阻精度都会直接累加到输出上。严格说这是“数控调压”而不是“闭环稳压电源”。想要把输出精确钉在设定值还得在输出端加分压电阻回采到ADC的另一个通道这个我放到最后一章讲。Proteus仿真阶段先把开环跑通往后再加环是更稳妥的路径。2.2 DAC0832直通模式接线与输出电流公式DAC0832是8位乘法型D/A转换器它内部只有R-2R电阻网络输出量是电流而不是电压。芯片输出电流Iout1与数字量D的关系大约是Iout1 Vref × D / (256 × R)对外部来说典型的做法是把它接到一个运放的反相输入端再用芯片内置的反馈电阻RFB把电流转成电压。常见的单极性接法输出公式为Vout1 -Vref × D / 256也就是说Vref为5V时第一级运放输出约-5V到0V。这个负电压经过第二级反相放大三倍就变成0-15V。很多人忽略IOUT2的接法它是电流返回路径必须接到运放同相端的虚地点不能悬空。在Proteus里DAC0832可以用直通模式省去繁琐的锁存时序。直通模式下各引脚接法如下引脚接法说明ILE5V芯片锁存允许必须为高CSGND片选常有效不用地址译码WR1GND写信号常有效数据立即进入WR2GND异步传输控制XFERGND数据传输控制DI0-DI7P0口8位数字输入写P0即输出IOUT1第一级运放反相端电流输出IOUT2运放同相端的虚地点电流返回RFB第一级运放输出内部反馈电阻这种接法有一个实际好处主程序往P0口写一个数DAC输出马上就跟着变不需要额外拉高片选线。缺点是直通方式缺少外部锁存保护P0口在初始化或切换数码管时不该被写DAC否则输出会跳变。所以代码里最好单独用一个宏不要随意碰P0。我用这个调压方案做调试时会先写一个固定值测链路#include reg51.h void main(void) { P0 0x80; // DAC0832直通模式输出满量程的1/2 while(1); }这段代码没有复杂逻辑目的是验证DAC、运放、电源三部分是否正常。0x80对应数字128理论输出电压约7.5V左右。如果量出来差很多先检查DAC的Vref是不是5V再看第二级放大电阻有没有接成10k和30k。常见问题是运放负电源没接输出会被钳在0V以下或者只能到0.7V这时候不可能得到0-15V范围。2.3 运放放大倍率计算与正负电源问题第一级运放做I/V转换得到一个反相的0到-5V信号。第二级运放负责把-5V到0V变成0-15V这就要放大-3倍。反相放大器的增益公式是A -Rf / Rin取Rin10kΩRf30kΩ放大倍数为-3。第一级输出-5V时第二级输出为:Uout (-5V) × (-30k/10k) 15V于是满码对应15V。Proteus仿真中运放供电我一般直接用±15V双电源这样能保证输出覆盖0-15V的完整区间。实际做PCB时如果只有单组电源问题就来了运放需要负电源来输出接近0V的电压。如果使用LM358单电源供电输出低端会停在几十毫伏不是严格的0V。更好一点的做法是用OP07加一组-5V电荷泵或者用轨到轨运放配合负压产生电路。如果只是课程设计Proteus里用±15V电源仿真最省事。真实做板时要注意运放供电不要超过手册上限LM358的共模输入范围也有限制。另一个点是放大电阻的精度10k和30k用普通5%贴片电阻理论输出15V实际可能只有14.6V但这类数控电源本来就允许通过调节Vref来做满度标定不需要为了精度去堆精密电阻。3. Proteus仿真电路搭建与引脚级排错3.1 整体器件清单Proteus工程里需要先放对元件搜索名称写错会在连线时浪费大量时间。以下是我在这个项目里使用的器件清单器件Proteus搜索关键词数量89C52单片机AT89C52或80C521D/A转换器DAC08321A/D转换器 | ADC0808 | 1 | | 双运放 | LM358 | 1 | | 电位器 | POT-HG或POT-LIN | 1 | | 共阳数码管 | 7SEG-MPX2-CA | 1 | | 电阻电容晶振 | RES / CAP / CRYSTAL | 若干 | | 直流电压表 | DC VOLTMETER | 2 |为什么选LM358而不是UA741一是Proteus里LM358模型稳定二是双运放只用一个芯片就能完成两级放大仿真界面更干净。实际打样时如果想降低输出失调可以换成OP07但这类课程设计课题里LM358完全够用。3.2 围绕89C52的I/O分配I/O分配必须在一开始定死否则代码和原理图来回改很容易出错。这个设计里DAC0832占用P0口全部8位ADC0808的数据输出占用P1口数码管段选占用P2口剩下的控制信号全部放到P3口。推荐引脚分配如下P0.0-P0.7DAC0832数据输入。P1.0-P1.7ADC0808数据输出。P2.0-P2.7数码管段选。P3.0-P3.1数码管位选P3.0选十位P3.1选个位。P3.2-P3.4ADC0808通道地址A、B、C。P3.5ADC0808的ALE和START并联使用。P3.6ADC0808的EOC查询。P3.7ADC0808的输出使能OE。这样分配后P3口刚好用完。ADC0808的ALE和START并联是常用做法因为启动一次转换本来就需要同时锁存通道地址并产生启动脉冲。单独占用两个口会浪费资源P3.5拉高再拉低就能完成地址锁存和启动。对应到Keil工程里引脚定义代码可以写成#include reg51.h #define DAC_OUT P0 #define ADC_DATA P1 sbit ADC_A P3^2; sbit ADC_B P3^3; sbit ADC_C P3^4; sbit ADC_STR P3^5; // ALE与START并联 sbit ADC_EOC P3^6; sbit ADC_OE P3^7; sbit DIG1 P3^0; // 数码管十位 sbit DIG2 P3^1; // 数码管个位这里DAC_OUT定义成P0后后面所有写DAC的代码都通过这个宏完成。ADC_DATA同理。用宏而不是直接写P1、P0是为了在代码里区分“DAC数据”和“ADC数据”避免混淆。P3.5同时驱动ALE和START在Proteus里连线时要用节点分叉不能只接START不接ALE。3.3 Proteus连线顺序与具体步骤连线顺序建议“先DAC、再运放、后ADC、最后数码管”这样信号从数据流向输出不容易飞线绕晕。第一步放置89C52和DAC0832。DAC的数据线DI0-DI7接P0CS、WR1、WR2、XFER全部接地ILE接VCC。IOUT1接LM358的2号引脚IOUT2接LM358的3号引脚RFB接运放输出。这一步完成电流转电压。第二步第二级放大。第一级运放输出接第二级反相输入端第二级同相输入端接地输入端电阻10k反馈电阻30k输出端接一个电压表。第三步ADC0808连接。它需要一个外部时钟Proteus里用“时钟源”直接给500kHz脉冲幅度设为5V。ADC的Vref接5VVref-接地电位器抽头接IN0地址线接P3.2-P3.4数据线接P1。第四步数码管接P2段选和P3.0、P3.1位选。共阳数码管的公共端通过PNP三极管再接位选更接近真实电路但Proteus课程设计里直接接位选引脚也能跑。连完以后需要仔细检查一个地方DAC0832的IOUT2必须运放虚地。如果IOUT2接到GND而不是运放同相端得到的结果是输出满幅只有一半。这个错误在仿真里不太容易被发现因为电压表数值看起来还有规律但它会让输出上限停留在约7.5V而不是15V。3.4 仿真运行不工作时的快速排错遇到仿真没反应先按顺序查三件事。第一查P0口上拉电阻。51单片机的P0是开漏电路写1时不接上拉就相当于高阻态DAC输入端可能随机漂移。Proteus中不接上拉有时候能跑但输出的数字到不了满码。解决办法是在P0口接一个10k排阻到VCC。第二查ADC时钟。ADC0808的时钟频率太高或太低都会导致采样失败。Proteus里给500kHz转换一次大约需要100μs配合主循环轮询足够。没有时钟源时ADC的EOC可能永远不翻转程序会卡死在while等待循环里。第三查运放供电。第二级运放输出要做到15V供电电压至少要±15V。如果只给运放5V输出电压会被钳在4V左右这是新手最容易忽略的问题。4. Keil C51程序设计ADC采样、DAC输出与数码管扫描4.1 主循环与整体流程程序整体采用“轮询ADC、直接写DAC、动态扫描数码管”的结构。不用中断逻辑更直白适合课程设计调试。主循环的任务是读取ADC0808通道0的数据把0-255直接映射到DAC0832再根据同一个ADC值换算成0-15的整数电压送数码管显示。主函数代码如下#include reg51.h #define DAC_OUT P0 #define ADC_DATA P1 sbit ADC_A P3^2; sbit ADC_B P3^3; sbit ADC_C P3^4; sbit ADC_STR P3^5; sbit ADC_EOC P3^6; sbit ADC_OE P3^7; sbit DIG1 P3^0; sbit DIG2 P3^1; unsigned char code seg[] { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 }; void Delay(unsigned char t); unsigned char GetADC(unsigned char channel); void Display(unsigned char volt); void main(void) { unsigned char adc_val; unsigned char dac_val; unsigned char volt_disp; while(1) { adc_val GetADC(0); dac_val adc_val; if(dac_val 250) { dac_val 250; } DAC_OUT dac_val; volt_disp (unsigned char)((unsigned int)adc_val * 15 / 255); Display(volt_disp); Delay(2); } }主循环中给dac_val设了250的上限。原因是满码255对应理论15V但运放接近正电源轨时线性会变差实际只能到14.7V左右。限制到250以后输出约14.65V稳定性比硬冲到15V更好。在Proteus里这个限制不一定看得到但移植到真实硬件时能避免运放饱和带来的非线性。volt_disp用unsigned int做中间变量再除以255得到的是0-15的整数正好用两位数码管显示。如果要做小数显示需要把15改成150再处理小数位但那至少要三位数码管。这里按课题最常见情况做整数显示。Delay(2)放在主循环末尾不是简单的延时它同时承担数码管扫描刷新任务。延时太短会闪烁延时太长ADC采样频率也会下降2ms左右比较合适。4.2 ADC0808读取通道数据ADC0808读取函数需要严格符合启动时序。这个芯片启动一次转换的方式是先设置通道地址然后让ALE和START同时产生一个正脉冲之后等待EOC从低变高最后打开OE读取数据。具体实现如下unsigned char GetADC(unsigned char channel) { unsigned char dat; ADC_A channel 0x01; ADC_B (channel 1) 0x01; ADC_C (channel 2) 0x01; ADC_STR 1; ADC_STR 0; while(ADC_EOC 0); ADC_OE 1; dat ADC_DATA; ADC_OE 0; return dat; }选择通道0时ADC_A、ADC_B、ADC_C都为0对应IN0输入。如果后面想采样输出反馈可以把通道号改成1并把输出分压接到IN1引脚上。这里有一点要注意ADC_STR拉高再拉低是同时给ALE和START发脉冲。地址线A、B、C在脉冲之前建立必须早于脉冲至少一个指令周期。上面的代码顺序是地址先赋值再拉高STR时序上满足要求。while(ADC_EOC 0)是一个阻塞等待。如果ADC时钟没接EOC引脚始终不变程序就会卡死在这里。所以仿真运行后界面像“假死”一样时先检查时钟源有没有接到ADC0808的CLOCK脚。4.3 DAC0832数据输出DAC0832工作在直通模式单片机往P0写数DAC会立刻把数字转成对应电流。dac_val直接使用adc_val没有做比例压缩是因为设定电位器和DAC都基于同一路5V参考电压。电位器旋到最小ADC读到0DAC输出也是0运放最终输出0V。电位器旋到最大ADC读到255DAC输出接近满度运放输出接近15V。直接映射有一个特例需要处理电位器抽头在旋转高端时ADC可能稳定在254或255输出也会在15V附近跳动。此时上面的250上限保护会兜底将最终DAC值限制在250避免输出超过15V后电压表读数异常。如果把上限去掉输出也不是严格的15V所以宁愿留下一点余量。向DAC写数时的典型错误是在P0口还接着其他外设。这里P0只接了DAC和上拉电阻所以直接赋值是安全的。如果自己扩展了LCD显示不能把LCD数据线也挂在P0上否则每次更新DAC都会干扰屏幕内容。4.4 数码管动态扫描显示数码管显示采用动态扫描两个位共用一组段选线同一时刻只点亮一位。只要切换速度够快人眼看到的就是两位同时稳定的数字。这里使用共阳数码管段码表里0xC0表示数字00xF9表示数字1依此类推。显示函数如下void Display(unsigned char volt) { unsigned char high volt / 10; unsigned char low volt % 10; P2 seg[high]; DIG1 1; DIG2 0; Delay(2); P2 0xFF; P2 seg[low]; DIG1 0; DIG2 1; Delay(2); P2 0xFF; }P2先输出十位段码然后DIG1置1、DIG2置0让十位数码管点亮2ms。紧接着消隐再输出个位段码点亮个位。消隐动作很关键如果不消隐切换段码时前一帧的数据会残留在下一段显示上形成拖影。电压换算时用的volt是0-15的整数。比如ADC读到170170×15/255约等于10十位显示1个位显示0。显示逻辑简单但能覆盖全部量程。如果想显示15.0这类小数需要改成三位数码管并把电压值直接按0-150映射段码表增加小数点处理。4.5 把代码装进Keil工程再启动仿真整理以上代码时有两点需要确认。第一Delay函数要放在使用之前或者加函数原型声明否则Keil会报未定义的警告。第二Proteus里单片机晶振频率要和Keil编译设置一致这里用12MHzDelay里的循环次数就是按12MHz估算的。实际Proteus连线中ADC0808的数据输出接在P1口但P1和P3都包含了sbit定义编译时不会有冲突。因为sbit是位地址操作P1作为unsigned char整体读取时只发生在ADC_OE置高以后。若EOC信号未准备好读到的数据是外部引脚的空状态不影响后续逻辑。运行后如果数码管显示不变先用电压表量ADC的IN0引脚。电位器转动时IN0电压应该在0-5V之间变化。如果IN0不变说明电位器接法不对固定端没有接5V和GND。如果IN0正常但输出不变问题多半在DAC的IOUT2接错第一级运放没有正确建立反相电压。5. 进阶排错与实用改造零点校准、软闭环和PCB移植5.1 零点与满度校准开环数控电源在真实硬件上最明显的误差是零点偏置和满度偏移。零点偏置来自运放失调电压满度偏移来自DAC参考电压和电阻误差。软件里可以在“电位器电压-DAC值”的映射关系上做两点校准。先让电位器旋到最小记下ADC读数为adc_min再旋到最大记下adc_max。正式运行时用线性插值计算DAC值dac_val (adc_val - adc_min) * 250 / (adc_max - adc_min);代码里把adc_val和adc_min都先转成int再进行减法避免无符号数下溢。min点不是0时这个公式可以强制输出从0V开始max点不是255时也能保证满度更接近15V。实际使用时我一般会在Proteus里反复旋转电位器把两个端点值打印出来再硬编码到程序里。满度偏移还可以通过调整DAC0832的Vref来实现。把Vref从5V微调到4.9V到5.1V之间输出电压上限会成比例变化。这个方法比换电阻更精准。5.2 用ADC0808第二通道做软闭环上面的设计只使用了电位器和DAC开环控制输出电压会受运放增益漂移影响。一个成本很低的改进方案在输出端用两个电阻分压比如10k和5k把0-15V降到0-5V接到ADC0808的IN1通道。然后在主循环里读取IN1作为实际输出电压与设定值比较做简单比例校正unsigned char actual; unsigned int error; actual GetADC(1); error (unsigned int)dac_val - (unsigned int)actual; dac_val (unsigned char)(error * 3 / 10);error*3/10相当于比例系数0.3方向需要根据实际接线确认。如果系统稳定但输出电压一直偏低可以把这个系数改成0.5再试如果输出震荡就改成0.1。这是最简单的P控制不是严格意义的PID但对这个精度需求足够。需要注意IN1通道的最大输入不能超过5V分压电阻选10k和5k时输出15V对IN1就是5V正好在ADC量程边缘。如果实测超过5V把5k换成4.7k以下即可。5.3 PCB移植时的三个细节把Proteus仿真转成真实电路时最常翻车的是电源和接地噪声。第一运放电源引脚旁边要加0.1μF陶瓷电容和10μF电解电容并联去耦放在运放供电脚附近。Proteus里不加电容也能跑但真实电路中高速噪声会直接串进输出。第二输出15V走线要加宽至少1mm0-15V数控电源的最大输出电流通常设计在几百毫安级铜箔太细压降会拉低输出电压。第三DAC0832的参考电压Vref不能直接接VCC最好用TL431稳压到5V否则单片机工作电流变化会把Vref拉偏导致数字不变但输出电压缓慢漂移。我在移植这类设计时会先把输出电压的反馈分压电阻固定在PCB上不飞线因为软闭环一旦开起来反馈回路的稳定性比对开环放大电路的阻抗更敏感。比例系数先在Proteus里用0.2调通再搬到真实板子改到0.3左右通常就能看到稳压效果。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

短剧后台管理系统技术选型与避坑实战指南 2026/9/16 4:06:56

短剧后台管理系统技术选型与避坑实战指南

1. 项目概述:为什么短剧后台管理系统不是“买个源码就能上线”的简单买卖短剧后台管理系统,这六个字背后藏着一个正在高速运转的商业引擎。它不是传统影视CMS的简单翻版,也不是通用内容管理系统的套壳改造——它是为“单集1-3分钟、日更2-5集…

阅读更多 →
VMware Workstation Pro 安装 Ubuntu 虚拟机详细教程 2026/9/16 4:06:56

VMware Workstation Pro 安装 Ubuntu 虚拟机详细教程

VMware Workstation Pro 安装 Ubuntu 详细教程做开发这么多年,虚拟机一直是我工作流里离不开的东西。尤其是需要在 Windows 和 Linux 环境之间来回切换的时候,VMware Workstation Pro 配合 Ubuntu 的组合可以说是最稳、最省心的方案之一。网上相关的教程…

阅读更多 →
网关限流熔断降级实战:守住流量洪峰的第一道防线 2026/9/16 4:06:56

网关限流熔断降级实战:守住流量洪峰的第一道防线

网关平时看着岁月静好,一旦流量洪峰打过来,最先扛不住的不是业务应用,反而是那些看起来“只做转发”的网关节点。我经历过一次印象很深的故障:上游一个核心服务单节点超时率飙升,Consumer端的重试机制自动触发&#xf…

阅读更多 →
VMD排列熵与ELM结合的轴承故障诊断Python实现 2026/9/16 4:06:56

VMD排列熵与ELM结合的轴承故障诊断Python实现

简介:基于变分模态分解(VMD)、排列熵与极限学习机(ELM)的滚动轴承故障诊断Python实现,面向机械设备健康管理研究人员、工业运维人员及相关专业学生,着力解决振动信号特征提取与故障模式识别的实…

阅读更多 →
基于STM32的智能饮水机Proteus仿真:从DS18B20到继电器的温度控制设计 2026/9/16 4:06:55

基于STM32的智能饮水机Proteus仿真:从DS18B20到继电器的温度控制设计

简介:这份基于STM32的智能饮水机Proteus仿真工程,面向嵌入式初学者与电子设计爱好者,实现了水位低于阈值报警、温度低于阈值自动加热、按键手动设置阈值等功能,是学习ADC采样、传感器比较控制与单片机中断/按键输入的良好示例。资…

阅读更多 →
LabVIEW+PXIe实现深海高压环境水声实时采集系统 2026/9/16 4:03:55

LabVIEW+PXIe实现深海高压环境水声实时采集系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞