ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ADUC842内部模块测试:ADC、DAC、IIC、SPI、UART、PWM完整验证指南

ADUC842内部模块测试:ADC、DAC、IIC、SPI、UART、PWM完整验证指南 简介ADUC842 内部模块测试程序是一份面向嵌入式开发者的完整验证代码包围绕 ADC、DAC、IIC、SPI、UART 与 PWM 六大片上外设展开适合正在学习 ADI 微控制器或需要快速评估外设功能的工程师。压缩包共 68 个文件以 C 源码、汇编启动文件、Keil 工程文件为主并包含 hex、lst、m51、obj 等编译输出与调试辅助文件可直接用 Keil 打开工程查看配置或烧录到芯片验证整体仅 80KB目录按 ADC、DAC、UART、PWM 等模块分离便于按需检索。已有 396 人学习下载。通过这套程序读者能具体看到 ADC 不同电压范围采样、DAC 正弦波生成、IIC/SPI 数据收发、UART 波特率配置以及 PWM 频率与占空比设置等典型实现为后续驱动开发和外设调试提供直接可参考的代码模板与排错思路。 前阵子接手一块基于 ADUC842 的采集板客户要求把 ADC、DAC、IIC、SPI、UART、PWM 这些内部模块逐一打通出一套可复现的测试程序。这颗 ADI 的 8052 增强型内核芯片放在今天的 MCU 阵营里确实不算新但它在工业仪表、传感器信号采集、小规模闭环控制场景里依然很能打内置多通道高精度 ADC、双 12 位 DAC加上齐全的串行接口外围器件能省则省。这篇文章把我整个测试过程、寄存器配置、示波器实测波形和一些容易踩的坑按顺序整理出来给后续要在这颗芯片上做底层验证的工程师省点时间。1. 内部资源盘点与测试方案设计1.1 芯片模块全景与选型背景ADUC842 最让人舒服的一点是“模拟前端和数字接口集成度高”。它基于 8052 指令集片内带了 8 通道 12 位逐次逼近型 ADC2 路 12 位 DAC还集成了硬件 IIC兼容 I2C 协议、SPI、UART、三相 PWM。对一块以模拟量采集为主的板子来说这些外设基本覆盖了绝大多数应用场景不需要额外挂太多芯片。如果你之前只玩过 STM32 这类 ARM 核 MCU第一次接触 ADUC842 可能会觉得寄存器布局有点“反直觉”。它没有像 HAL 库那样给你一套统一的抽象层很多控制位直接散落在特殊功能寄存器SFR里而且每个模块的时钟、使能、中断是分开管理的。我的建议是不要急着写业务逻辑先做模块级测试把每个外设当成独立单元验证一遍确认通路没问题再往上层走。1.2 测试程序的整体架构我的做法是建一个裸机 C 工程主循环里用串口接收命令字符每个字符对应一个测试项aADC 单通道连续采样把原始值和换算电压打印到串口bDAC 输出斜坡信号同时用 ADC 回采验证输出线性度cIIC 读写外部 24C02 EEPROMdSPI 主模式与从设备回环eUART 自发自收回环测试pPWM 输出 1kHz 可调占空比这样设计的好处是模块之间互不干扰每个功能都能单独定位问题。后面扩展成完整固件时这些测试函数只要稍加裁剪就能直接复用。我强烈建议在开始之前先做一块带测试点的主板把 ADC 输入、DAC 输出、IIC/SPI/UART 引脚都引到排针调试效率会高很多。2. 模拟链路核心ADC 与 DAC 测试2.1 ADC 采样配置与信号验证ADUC842 的 ADC 是 12 位逐次逼近型结构工作原理就是一次次比较电压从最高位到最低位逐位逼近输入信号所以采样结果的质量和采样时钟、建立时间关系特别大。初始化时先要确定采样时钟分频系数直接决定单次转换时间。很多人第一次用会忽略 ADC 时钟的上限把分频设得太小导致转换结果跳变明显还以为是电源噪声问题。这里给一个常用的单通道配置代码void adc_init(unsigned char ch) { // 选择模拟输入通道ADC0 ~ ADC7 ADCCON1 (ADCCON1 0xF0) | (ch 0x07); // 配置为单次转换模式关闭DMA ADCCON2 0x00; ADCCON3 0x00; } unsigned short adc_read_single(void) { unsigned short result 0; ADCCON2 | 0x01; // 启动一次转换 while (!(ADCCON3 0x80)); // 等待ADCFLAG置位 result ((unsigned short)ADCDATAH 4) | ((unsigned short)ADCDATAL 4); return result; }需要提醒的是ADCDATAH 和 ADCDATAL 的组合方式在不同资料里写法不完全一样有的把 12 位结果对齐成 16 位、低 4 位补零有的是直接靠左对齐。一定要以当前芯片数据手册里 ADC 数据寄存器那节的格式说明为准。实测中我更喜欢在串口助手里同时打印十六进制原始值和换算后的电压值方便快速判断前级信号是否正常。关于采样周期网上经常有人问“四通道用 DMA 怎么做”。ADUC842 没有 ARM 那种通用 DMA它所谓的 ADC DMA 是把转换结果直接搬运到数据 RAM 的专用机制配置也不复杂。但真要连续采多路信号我更推荐用定时器触发加中断的方式每个通道在中断里取一次数代码的可读性和稳定性都比依赖专用搬运机制更好控制。另外ADUC842 的数据手册里也提供了 ADC 校准寄存器量产时可以在软件里做偏移和增益校准思路和外部 ADC 的三点校准类似只是寄存器操作要简单很多。2.2 DAC 输出与波形一致性检查ADUC842 有两路 12 位电压输出 DAC控制起来比 ADC 还直接。写 DAC0 的高四位到 DAC0H、低八位到 DAC0L输出端就能得到对应的电压。我在测试时会把 DAC0 输出引到示波器同时接到 ADC0 输入做成一个“自测回路”。void dac0_output(unsigned int val) { DAC0H (val 8) 0x0F; // 12位模式高4位 DAC0L val 0xFF; // 低8位 }让 DAC 输出一个 0 到满量程的锯齿波再用 ADC 回采能很直观地看到前后波形变化。正常情况下DAC 输出是一条阶梯上升的斜线ADC 回采值也应该是同趋势的阶梯偏差不会超过几个 LSB。如果你看到回采值在某个台阶上明显跳变优先检查基准电压 VREF 是否稳定其次是 DAC 输出端有没有足够的去耦电容。DAC 输出带载能力有限直接驱动重负载会把波形拉歪测波形时要接高阻探头这个习惯能省很多排查时间。大多数人测 DAC 只看静态电压我建议再测一版动态过程给 DAC 写一个正弦表用示波器看输出波形是否平滑带载后有没有明显失真。这个测试对后面做信号激励、闭环控制非常有价值。2.3 模拟链路测试的注意事项模拟链路最容易出问题的点按我遇到过的概率排序参考电压不稳大于地线乱串大于输入信号源阻抗过高大于采样时钟太快。ADUC842 的 ADC 输入内部有采样电容如果信号源输出阻抗太高采样建立时间不够转换结果就会偏小或者跳动解决办法是降低分频系数、延长采样周期必要时在前面加一级运放缓冲。这些经验放到 STM32F103 的 DAC/ADC 配置里也是相通的只是 ADUC842 没有库给你封装只能自己把参数算明白。实操提示ADC 输入引脚附近一定要放一个 0.1uF 的滤波电容同时串一个几百欧的电阻做限流不要直接把外部信号裸接进去。这个做法能大幅减少高频干扰对信噪比提升非常明显。3. 数字接口实测IIC、SPI、UART3.1 IIC 主模式通信与上拉电阻ADUC842 的 IIC 接口硬件上兼容 I2C 协议支持主/从模式。测试时我直接挂了一片 24C02 EEPROM用最经典的“写字节再读回”流程验证通信。这里要特别强调上拉电阻的取值IIC 是开漏结构SCL 和 SDA 必须接上拉。取值太小会导致低电平拉不下去取值太大则上升沿过慢通信速度提不起来。常用 4.7kΩ 在 100kHz 下基本够用如果跑 400kHz 建议换成 2.2kΩ并配合示波器看 SCL/SDA 的上升沿是否干净。实际还得根据总线上挂的器件数量和总线电容做微调。IIC 起始条件、停止条件和 ACK/NACK 的检查是调试难点。我踩过最多的坑是写完从机地址后没有确认主机是否收到 ACK 就继续发数据。如果从机地址不对或者总线上从机没上电第二次就会卡死或者数据错乱。所以每次调用发送字节函数后都要检查状态寄存器的对应位确认 ACK 后再进行下一步。从机 NACK 不一定是你代码错了很可能是器件地址设置不对比如 24C02 的 A0/A1/A2 引脚和 PCB 上的实际接法不一致。3.2 SPI 模式配置与数据收发SPI 这边我用的是主模式挂了一个 SPI 接口的 DAC 芯片做回环验证。ADUC842 的 SPI 由 SPICON 寄存器控制关键是 CPOL 和 CPHA 要和从设备严格对上。我见过太多人 SPI 波形出问题最后发现就是时钟极性选反了示波器上看 MOSI 数据完全乱了。建议先把 CPOL、CPHA 的配置列清楚采样沿CPOLCPHA上升沿采样空闲低00下降沿采样空闲低01上升沿采样空闲高10下降沿采样空闲高11配置一个简单的 SPI 字节收发unsigned char spi_byte(unsigned char dat) { SPIDAT dat; // 写数据触发传输 while (!(SPICON 0x80)); // 等待传输完成标志 return SPIDAT; }SPI 还有一个容易忽略的地方硬件片选和软件片选。ADUC842 也支持硬件片选引脚但很多从设备要求 CS 在整个帧传输期间保持稳定如果芯片的硬件片选时序和你的从设备不匹配不如直接用普通 GPIO 做软件片选灵活性更高。我在实测中一直用 GPIO 来控制 CS配合微秒级延时基本不会出问题。这里顺便说一下 IIC 和 SPI 的区别IIC 靠器件地址区分设备只需要两根线速度相对慢一些适合挂载多个器件的场景SPI 是全双工、速度快但每个从设备通常要占一个 CS 引脚线数更多适合单从机高速传输。像 ADUC842 这种把两种接口都集成进来的芯片好处就是接传感器的用 IIC接高速 DAC 或者 Flash 的用 SPI各干各的活。3.3 UART 波特率与回环测试UART 沿用 8052 的标准结构SCON、SBUF、TMOD、TH1/TL1 这些寄存器对老工程师来说太熟了。正是这种熟悉最容易让人忽略波特率计算。它的波特率是定时器 1 溢出率除以 16如果晶振频率不是精确的整除数误差就会累积通信稍微长一点就出错。我在代码里用的是 11.0592MHz 晶振能精确产生 9600、19200 等常用波特率。void uart_init(void) { SCON 0x50; // 模式18位UART允许接收 TMOD 0x0F; TMOD | 0x20; // 定时器1工作在方式28位重装 TH1 0xFD; // 19200 11.0592MHz TR1 1; TI 0; RI 0; }测试时我习惯做一个简单回环串口收到的字节原样发回上位机。这样做至少能验证硬件通路和波特率匹配如果收到的字符是乱码先不要怀疑代码用示波器看 TX 脚的实际波形数一下一位的宽度对不对。UART 地线没接好这个低级问题我见过不止一次排查的时候先确认两边共地。4. PWM 输出与波形校验4.1 三相 PWM 配置要点ADUC842 的 PWM 是三相输出每一相都有独立的高电平标志和低电平标志可以配置成正极或负极输出。PWMCON 负责总开关和触发方式PWM 周期存在周期寄存器里每一相的占空比通过对应的 PWM 数据寄存器设置。初始化时先定周期再写占空比最后打开输出使能位引脚上才会有波形。void pwm_init(void) { PWMCON 0x01; // 使能PWM // 周期和占空比寄存器具体位宽以数据手册为准 PWMPL 0x00; PWMPH 0xC8; PWM0L 0x00; PWM0H 0x64; // 占空比约50% }不同型号对 PWM 寄存器的位宽定义略有区别上面代码我注释成“示意”。实际做工程请打开数据手册把 PWM 周期和占空比的计算公式代入一遍再根据需要的频率反推计数初值不要照搬网上的寄存器赋值不同芯片差别很大。4.2 示波器实测占空比与频率PWM 配置好后用示波器探头夹在 PWM0 引脚上先看频率对不对再看高电平占整个周期的时间比例。我第一次测的时候就踩了坑忘了把 PWM 输出引脚配置成数字功能结果示波器上只有一个直流高电平。这类问题在 ADUC842 上很容易发生因为它的数字外设和 IO 口是复用的必须确认引脚功能切换寄存器已经正确设置。验证占空比时顺手测一下不同占空比下的输出比如 10%、50%、90%看看边沿的抖动幅度。如果波形抖动明显优先检查 PWM 时钟源是不是和 ADC 共用了同一个不稳的时钟树必要时把两个模块的时钟分频独立配置。5. 常见问题与排查实录5.1 各模块联调的典型故障把测试中碰到的高频问题整理成一张速查表方便大家直接对症下药现象可能原因排查方法ADC 读数跳动大采样时钟太快 / 基准不稳降低 ADC 时钟检查 VREF 电容DAC 输出电压偏低输出负载过重 / 基准被拉低高阻表笔测量检查负载IIC 卡死在等待从机地址错 / 上拉电阻不合适示波器抓 SDA 波形确认 ACKSPI 收到数据全 0xFFCPOL/CPHA 不匹配 / CS 没拉低对照从设备时序调整UART 乱码波特率误差大 / 地线没共地示波器测 TX 位宽度PWM 输出无波形引脚没切到数字功能 / 未使能输出检查引脚复用和 PWMCON5.2 代码与实际调试心得最后聊几个绝大多数资料里不会写、但很影响效率的点。第一ADUC842 的代码调试建议优先用 Keil C51配合板载串口打印比单步仿真快得多第二模拟地和数字地要尽量单点相连尤其是 ADC 和 DAC 相互回环的时候地平面处理不好会把信噪比直接拉低几个 LSB第三每个模块单独写一个 test 函数不要图省事把所有初始化堆在 main 开头出了问题很难定位。我在这个项目里最深的体会是ADUC842 虽老但它的数据手册其实写得非常清楚很多“坑”其实都是没把寄存器含义读懂就急着跑数据造成的。慢下来把寄存器表格逐行过一遍加上示波器比对比反复试错高效太多。这套测试程序跑通之后后面的业务代码基本就是在这些模块函数上做组合心里踏实很多。本文还有配套的精品资源点击获取
返回列表