新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于AT89C52与DAC0832的直流电机调速系统设计详解

发布时间:2026/9/19 20:19:37来源:尧图网络
基于AT89C52与DAC0832的直流电机调速系统设计详解
简介基于AT89C52单片机的直流电机调速系统设计文档为2021年9月收藏的完整课程设计/毕业设计参考方案主要面向电子信息、自动化等专业学生及51单片机入门者。方案以AT89C52为控制核心采用DAC0832数模转换器将数字信号转为电压从而调节电机转速并通过数码管显示转速与档位解决传统调速电路结构复杂、精度不足的问题。文档从系统总体设计、硬件接口电路到软件流程均有清晰说明包含DAC0832直通模式配置、8255扩展数码管驱动、定时器/计数器频率测量等关键细节并给出C语言实现思路整体结构完整可直接作为设计报告框架参考。资源包共1个doc文件约202KB属于纯文档型资料适合用于课程设计报告撰写、答辩讲解或项目前期参考已有99人学习具有一定参考价值。1. 为什么这个直流电机调速系统敢用 DAC0832 而不是 PWM2021 年 9 月 16 日我整理一份课程设计资料时发现一个有意思的设计直流电机调速没有用常见的 PWM 脉冲调制而是让 AT89C52 单片机配合 DAC0832 数模转换器把数字量直接换算成模拟电压来推动电机。大多数人在实际项目里会默认选 PWM因为开关管效率高、CPU 开销小。但这个系统反其道而行用 DAC 输出线性电压调速好处是电压纹波小、调速曲线平滑调试时用万用表就能直接看到 DA 输出电压和转速的对应关系这在教学演示和低速平稳控制场景里反而比 PWM 更直观。适合做单片机课程设计、蓝桥杯备赛的在校生以及想快速验证 DA 转换链路完整性的嵌入式工程师。下面把接口电路、数码管扫描、按键档位状态机和仿真排错一条线讲透。2. DAC0832 直通模式接口电路与三角波输出验证2.1 DAC0832 内部结构与工作模式选型DAC0832 是一颗 8 位全 MOS 中速 D/A 转换器内部采用 R-2R T 形电阻解码网络转换结果是电流型输出转换时间约 1us。它支持单电源 5V 到 15V 供电参考电压允许在 -10V 到 10V 范围内选取这里直接取 5V 作为参考电压。为什么选它而不是更常见的 TLC5615 或 PCF8591因为本设计的要求很明确数据位宽 8 位就够、转换速度要求不高、需要直观的电压输出范围可控并且 DAC0832 可以工作在完全不需要写时序的直通模式把数据总线拉上去就能输出对应电压。DAC0832 有三种工作方式直通方式、单缓冲方式、双缓冲方式。双缓冲适合多路 DAC 同步输出的场景单缓冲适合输出寄存器需要锁存控制的场景。本系统只控制一台电机转速更新不需要与外部同步因此选直通方式更合适——CS、XFER、WR2 全部接数字地芯片内部寄存器直通P0 口数据一变输出电流立即跟随变化减少了两层软件时序开销。下表给出直通模式下 AT89C52 与 DAC0832 的实际连接关系AT89C52 引脚DAC0832 引脚电平/信号说明P0.0 - P0.7DI0 - DI78 位数字量输入GNDCS片选接地始终有效GNDXFER传输控制接地GNDWR2写信号接地5V 电源Vref参考电压 5VGNDRFB反馈电阻端配合运放使用这里要注意一个隐藏坑AT89C52 的 P0 口是开漏结构内部没有上拉电阻直接接 DAC0832 的数据输入端时高电平驱动能力不足。常见做法是在 P0 口外接 10k 排阻到 VCC否则高电平输出会被拉低导致 DA 输出电压到不了满幅值实测可能最大只有 4V 左右。很多课程设计做到整机调试时发现转速上不去问题就出在这里。2.2 直通模式下的输出特性直通模式下DAC0832 的电流输出与数字量 D 的关系为 Iout (D / 256) * Vref / Rfb。因为电机需要电压驱动而不是电流驱动所以输出端要接一个 I/V 转换电路常见做法是用运放搭电流转电压比如 LM358 接成反相放大器。注意 DAC0832 是电流型输出IOUT1 和 IOUT2 是互补电流输出单纯用万用表去量 IOUT1 对地电压是量不准的必须经过运放转换成电压。Rfb 引脚是内部反馈电阻的引出端接运放输出端能补偿温漂系数。这里的 R-2R 网络建立时间很快跟上单片机 P0 口的输出速率完全没压力所以不需要在数据总线上加锁存器。为了在焊板子之前先验证数字量到模拟电压这条链路是否打通我一般会在系统主程序之前单独跑一个开环测试代码让 P0 口输出线性变化的数字量观察运放输出端是否出现三角波#include reg52.h // 开环测试DAC0832 直通模式三角波发生 void main() { unsigned char val 0; bit direction 0; // 0: 递增, 1: 递减 // P0 口输出低电平先保证 DAC 输出电压接近 0V P0 0x00; while (1) { if (direction 0) { P0 val; if (val 255) direction 1; // 到满幅值改递减 } else { P0 val--; if (val 0) direction 0; // 回到 0 改递增 } // 延时约 200us控制三角波周期可调 _nop_(); _nop_(); _nop_(); _nop_(); } }这段代码的作用不是调速而是验证 P0 口到运放输出端的通路是否正常。变量 direction 用来控制数据增减方向val 从 0 递增到 255 再递减回 0对应 DAC 输出从 0V 逐步升到接近 Vref 再降回来运放输出端应该出现线性三角波。四个_nop_()是空指令用来做短暂延时实际调试时建议换成 1ms 级延时便于示波器观察一个完整周期。如果波形有台阶而不是线性斜坡优先检查 P0 口上拉电阻是否牢固如果波形幅度偏小重点量 Vref 引脚是不是标准的 5V。这里的参数意义要说明白val 的步进是 1对应 DA 分辨率约 5V / 256 19.5mV也就是说每次数字量加 1理论输出电压抬升 19.5mV。在实际测速过程中这个粒度已经足够让转速稳定分辨到肉眼可见的变化。2.3 从三角波切换回调速闭环三角波验证只适合开环测试真正投入调速时P0 口的输出量不再线性扫动而是由按键设置的档位决定。档位写入 DAC 的数字量不是随意定的需要根据电机额定电压和运放放大倍数做比例换算。假如电机额定电压 12V功率放大级把运放输出放大到 12V那么 DAC 数字量 255 对应 5V 参考电压再放大 2.4 倍这组比例关系会直接写进显示缓冲区并在数码管上同时显示档位和 DA 输出值。3. 8255A 扩展驱动的数码管动态扫描与显示缓冲结构3.1 为什么不用单片机 I/O 口直接驱动数码管系统运行状态需要显示“DJ-XX”和当前 D/A 输出的数字量这一步拆开来看包含多种信息档位编号、单位标识、DA 输出十六进制数。如果全部用动态扫描方式在单片机上完成需要 8 个 I/O 口做段码、6 个 I/O 口做位选AT89C52 还剩多少口可以接按键和 DAC另外数码管内部是 LED 器件单片机 I/O 口提供的是“虚电压”能输出高低电平但驱动能力有限直接点亮亮度很低。所以这里通过 8255A I/O 扩展芯片占用单片机 P0 和 P2 口由 8255A 的 PA 口输出段码、PC 口输出位选再经过达林顿管或 74HC245 增强驱动能力。8255A 在这里实际上充当了显示寄存器和 IO 扩展器的双重角色把显示刷新任务从 CPU 中断中剥离出来。硬件连接上8255A 的地址线 A0、A1 接 AT89C52 的 P2.0 和 P2.1片选 CS 接 P2.7这样通过地址就能选中 8255A 的 PA、PB、PC 和控制寄存器。PA 口作为输出方式 0接数码管段码PC 口低 3 位做位选同时 PC 口还要单独接一位到“档位状态灯”。8255A 方式 0 是无握手直通输出不需要额外状态查询适合显示刷新这类简单输出场景。3.2 段码表与扫描节奏设计共阴极数码管需要软件给出段码表按共阴极接法要显示字符“0”到“9”加上“H”和空字符按位排列成数组// 共阴极数码管段码表 // 位序: dp g f e d c b a unsigned char code segCode[] { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F, // 9 0x76, // H 0x00 // 空白 };段码表按位顺序排列依靠的是共阴极数码管内部发光二极管阳极接段码、阴极接位选的结构。动态扫描的核心思路是同一瞬间只点亮一位高频率轮流点亮所有位利用人眼视觉暂留合成完整显示。扫描频率不能太低低于 50Hz 会觉得闪也不能高到超过位选三极管开关速度推荐 1ms 到 2ms 切换一位6 位数码管完成一轮扫描约 6ms刷新率约 160Hz既无闪烁也不产生明显拖影。3.3 显示缓冲区如何组织把要显示的内容先放进缓冲区再统一交给扫描程序这是显示系统的关键设计。实际项目里显示缓冲区定义如下unsigned char data disBuf[6]; // 6 位数码管显示缓冲区 unsigned char data curScanBit; // 当前扫描位其中 disBuf[0] 到 disBuf[5] 分别对应显示内容从高位到低位。比如电机档位是 3、DA 输出数字量是 0xA5需要显示“d 3 A 5”那么 disBuf[0] 0x00灭、disBuf[1] 0x00灭、disBuf[2] 0x00灭、disBuf[3] 0x5B显示 3、disBuf[4] 0x77显示 A但段码表未列需要用 0x77 自行补充、disBuf[5] 0x6D显示 5。我一般会把“d J - ”作为固定前缀或者在最高位显示档位、后面接 DA 值具体布局可以调整。但缓冲区大小固定为 6扫描函数不关心内容只负责把 disBuf 的值搬到位上这样逻辑上解耦改显示格式时不碰扫描代码。扫描服务函数如下放在定时器中断里调用void scanDisplay() interrupt 1 using 1 { TH0 0xFC; // 重装初值定时 1ms12MHz 晶振 TL0 0x18; // 关位选防止拖影 P2 0x1F; // 8255A PC 口低 3 位清零关闭所有位 // 段码输出 PA_OUT segCode[disBuf[curScanBit]]; // 打开当前位 P2 (P2 0x1F) | ((curScanBit 1) 3); curScanBit; if (curScanBit 6) curScanBit 0; }这段代码里8255A 的 PA 口映射为 PA_OUTPC 口低 3 位作为位选。先关全部位选再送段码最后开本位这个顺序不能反否则会出现鬼影和暗亮。TH0 和 TL0 的重装值在 12MHz 晶振下定时 1ms扫描一轮 6ms肉眼看不到闪烁。如果用的是 STC 单片机IRC 时钟频率可能存在误差需要根据实际主频重算初值。3.4 档位显示与 DA 数值的动态关联显示内容和实际电机转速不是独立事件。键盘设置档位后程序需要把档位映射成 DAC 数字量再同时写入显示缓冲区void setGearToDisplay(unsigned char gear) { unsigned char index gear 0x0F; // 档位限制在 0-15 unsigned char dacValue gearVolt[index]; // 查表获得 DA 值 unsigned char highNib dacValue 4; unsigned char lowNib dacValue 0x0F; disBuf[0] 0x00; // 灭 disBuf[1] 0x00; // 灭 disBuf[2] segCode[gear / 10 % 10]; // 档位十位 disBuf[3] segCode[gear % 10]; // 档位个位 disBuf[4] segCode[highNib]; disBuf[5] segCode[lowNib]; }gearVolt 是一张档位到 DA 值的映射表常见做法是线性映射档位 1 对应 0x20档位 15 对应 0xF0。因为电机低速段非线性明显线性查表不一定合适可以按实际电机特性手工修改这张表。我通常会在实验记录本上先测量不同 DA 值对应的电机转速再反过来修正表项这个过程是整个调速系统调试中最耗时的部分。4. 定时计数器测频与键盘档位状态机的 C 语言实现4.1 频率测量的时间基准与计数通道数码管上显示的转速需要量化系统里面用两个定时/计数器资源分别充当定时器和计数器。定时器 0 用来产生固定闸门时间定时器 1 工作在计数模式统计电机轴上码盘输出的脉冲数。具体做法是定时器 0 设置为方式 1定时 500ms定时器 1 设置为方式 1计数外部脉冲在 T1 引脚的下降沿。等定时器 0 溢出时读取定时器 1 的计数值乘以 2 就是 1 秒的脉冲频率再除以每转脉冲数得到转速。这种测频法适合频率相对稳定的信号如果电机转速跳变很快需要改用测周法但这超出了本系统的适用范围。中断服务函数关键部分如下unsigned long pulseCnt 0; unsigned char timeFlag 0; void timer0_isr() interrupt 1 { static unsigned char tick; TH0 0x3C; // 12MHz 下定时 50ms TL0 0xB0; tick; if (tick 10) { tick 0; timeFlag 1; // 500ms 闸门到达 } } void timer1_isr() interrupt 3 { pulseCnt; // 外部脉冲计数 }注意定时器 1 溢出周期要远大于闸门时间否则 pulseCnt 累计到 65535 溢出会丢数据。如果电机转速高、脉冲频率超过 100kHz建议把定时器 1 改为方式 2 自动重装并在中断里维护一个 16 位或 32 位计数变量。这个细节在蓝桥杯单片机备赛里常考实际工程中也很容易踩坑。4.2 键盘扫描与档位状态机档位设置是三个按键配合实现的一个“设置键”用于切换输入位两个“加/减键”用于修改当前位的数值。参照原文流程图的设计每次按下设置键有效输入位从第六段数码管依次跳到第五段、第四段对应百位、十位和个位第三次输入完成后把 V 值存入 disbuf 中。这个过程本质是一个四状态状态机用当前输入位数 curDigitIndex 作为状态变量。#define SEG_DIGIT_3 0 // 第三段数码管存储最终 V 值 #define SEG_DIGIT_4 1 #define SEG_DIGIT_5 2 #define SEG_DIGIT_6 3 unsigned char curDigitIndex; unsigned char setValue[3]; void keyScan() { if (key_set_pressed) { curDigitIndex; if (curDigitIndex 3) curDigitIndex 0; } if (curDigitIndex 1 curDigitIndex 3) { if (key_up_pressed) { setValue[curDigitIndex - 1]; if (setValue[curDigitIndex - 1] 9) setValue[curDigitIndex - 1] 9; disBuf[SEG_DIGIT_6 - curDigitIndex] segCode[setValue[curDigitIndex - 1]]; } if (key_down_pressed) { if (setValue[curDigitIndex - 1] 0) setValue[curDigitIndex - 1]--; disBuf[SEG_DIGIT_6 - curDigitIndex] segCode[setValue[curDigitIndex - 1]]; } } if (curDigitIndex 0 setOK) { // 组合三位数为最终 V 值 unsigned char v setValue[0] * 100 setValue[1] * 10 setValue[2]; P0 v; // 直接输出到 DAC curDigitIndex 0; } }这里 key_set_pressed、key_up_pressed、key_down_pressed 分别对应三个按键的下降沿检测结果实际板级调试时需要在主循环里用软件消抖每 10ms 扫描一次键盘连续两次读到相同电平才确认按键有效。状态机的好处是逻辑集中在 keyScan 一个函数里不管用户怎么乱按curDigitIndex 都不会越界。注意第三次输入完成后把 V 值送入 P0这是整个系统的核心动作数字量 V 经过 DAC0832 变成模拟电压控制电机转速。4.3 频率显示格式与单位切换显示模块还要处理量程自动切换。原文明确给出规则频率低于 1MHz 时六位数码管直接显示频率数值频率高于 1MHz 时前四位显示数值最后一位显示字母 H。这里虽然测的是转速但在教学演示里直接把脉冲频率当作显示对象。切换逻辑不复杂比较 frequency 和 1000000 的大小然后往 disBuf 里填不同的字符。需要注意频率值本身不是以 BCD 码形式存储的如果直接用整型除以 10 的幂取各位在 Keil C51 里要注意 unsigned long 运算的 bank 切换我一般会把除法运算提取成独立函数避免 lcall 太深导致变量覆盖错误。5. Proteus 仿真排错与 DA 更新时序处理技巧5.1 Proteus 里最容易出的三个问题用 Proteus 仿真 51 单片机项目时DAC0832 直通模式往往能跑通但数码管动态扫描经常遇到两个现象亮度不均和数字跳动。亮度的核心问题是位选驱动没有加限流阻抗仿真模型中 8255A 的 PC 口直接下拉数码管阴极电流过大会让段码电压被拉偏解决方法是每个位选输出串一个 330 欧电阻或者用 PNP 三极管做高电平驱动。第二个常见问题是程序从 Keil 编译后导入 Proteus 时丢失了 HEX 文件仿真无法运行。这属于操作问题但值得在排错清单里放第一条。正确的做法是在 Keil 的 Output 选项卡勾选 Create HEX File编译后把生成的 .hex 文件路径填写到 Proteus 单片机属性里。第三个坑是 DAC0832 的电流输出没有做 I/V 转换仿真里电机模型无法识别电流表现为电机不转。Proteus 中的直流电机模型实际上是根据端电压运动的所以必须用 opamp 把 DAC 输出电流转换成电压再接到 ENG 驱动电机。我习惯在 D/A 输出端接一个 LM358 反相比例放大电路RFB 接输出RIN 接地增益设为 -1这样 0 到 5V 的 DA 输出被映射为 0 到 -5V再通过反相器恢复正电压给电机。5.2 DA 更新与动态扫描的时序避让实际调试中发现如果在主循环里频繁更新 P0 口数码管会出现肉眼可见的闪动原因是 P0 口同时承担 8255A 的数据传输虽然 8255A 锁存了显示数据但动态扫描期间 CPU 对 P0 的写入操作会短暂拉低数据线导致段码出错。一个有效的技巧是把 DAC0832 的数字量更新放在定时器中断里而不是主循环直接赋值。具体做法是维护一个全局变量 dacOutputVal在键盘状态机里只修改这个变量然后由定时器 0 中断服务函数在扫描完当前位之后附带把 P0 更新为 dacOutputVal。我一般会这样设计void timer0_isr() interrupt 1 { // 原本的定时器 0 重装代码 TH0 0xFC; TL0 0x18; // 在显示扫描之前更新 DAC 输出 P0 dacOutputVal; // 再执行数码管动态扫描 scanDisplay(); }这样 P0 口在每次中断里先被更新为 DAC 当前值随后 scanDisplay 里对 P0 的访问变成向 8255A 输出数据两者在时间上严格串行不会出现主循环里写了一半 P0 就被显示代码抢走的问题。但要注意 scanDisplay 里凡是访问 8255A 的语句都会改变 P0 的值所以 P0 保持 DAC 输出值的时间只维持到下一句指令DAC0832 直通模式下输出会有微型毛刺不过对于直流电机这种大惯性负载几百纳秒的毛刺无实际影响。如果做更精细的波形输出可以把 DAC0832 改成单缓冲模式用锁存器保存数据这样才能保证 DAC 输出长时间稳定。5.3 验证“档位 DA 输出数字量”是否真的对得上最终验证方法是逐档按下按键用万用表测 DAC0832 运放输出端电压记录每个档位对应的电压值和数码管显示的数字量绘制成一张曲线表。如果档位 1 到 15 的 DA 值按 0x20 到 0xF0 均匀递增电压应近似线性递增如果中间某一档电压跳变异常优先检查 P0 口上拉电阻和运放电路而不是单片机的程序——因为数字量到模拟量之间只隔了这两层。这个方法比看转速准得多也是快速定位“为什么 3 档和 4 档转速一样”这类问题的最有效手段。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

FaceFusion与91n的搜索谜团:AI换脸开源工具的信息干扰与正确使用 2026/9/19 21:13:46

FaceFusion与91n的搜索谜团:AI换脸开源工具的信息干扰与正确使用

大概半个月前,我在一个技术交流群里看到有人发问:FaceFusion和91n是什么关系?是不是同一家出的?我当时愣了一下,这俩名字怎么会被人放到一起?后来自己动手搜了一圈才明白,原来很多人在搜索引擎里…

阅读更多 →
ComfyUI保姆级教程:从零安装到跑通第一张图的完整指南 2026/9/19 21:13:46

ComfyUI保姆级教程:从零安装到跑通第一张图的完整指南

做ComfyUI这套东西,我真正上手是两年前,当时把秋叶整合包、官方手动版、甚至Linux源码版都折腾了一遍。说句实话,ComfyUI绝对不是那种“装上就能画图”的傻瓜软件,它的学习曲线比WebUI要陡得多,但一旦你理解了节点式工…

阅读更多 →
3秒参考音频就能改词换句:VoiceCraft 零样本语音编辑与TTS 2026/9/19 21:13:46

3秒参考音频就能改词换句:VoiceCraft 零样本语音编辑与TTS

3秒参考音频就能改词换句:VoiceCraft 零样本语音编辑与TTS 【免费下载链接】VoiceCraft Zero-Shot Speech Editing and Text-to-Speech in the Wild 项目地址: https://gitcode.com/GitHub_Trending/vo/VoiceCraft VoiceCraft 是一个神经声码器语言模型&…

阅读更多 →
数据资产管理平台选型:从元数据到数据标准的供应商横评与PoC验证思路 2026/9/19 21:13:46

数据资产管理平台选型:从元数据到数据标准的供应商横评与PoC验证思路

简介:面向企业数据资产管理平台选型场景,这份竞品分析报告从数据语言不统一、数据找不到读不懂、数据不可信、数据不可联等痛点出发,梳理出数据标准、元数据、数据质量、数据安全与主数据管理五大需求方向,并对A、B、C、D四家主流…

阅读更多 →
N_m3u8DL-RE 速览:3 条命令搞定 DASH/HLS/MSS 流媒体下载 2026/9/19 21:13:46

N_m3u8DL-RE 速览:3 条命令搞定 DASH/HLS/MSS 流媒体下载

N_m3u8DL-RE 速览:3 条命令搞定 DASH/HLS/MSS 流媒体下载 【免费下载链接】N_m3u8DL-RE Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文. 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8DL-RE…

阅读更多 →
QuickDesk 跑 AI 远程操控:模型 Key 用 TaoToken 2026/9/19 21:10:46

QuickDesk 跑 AI 远程操控:模型 Key 用 TaoToken

/* 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
📞