1. 硬件连接与初始化
1.1 硬件连接详解
AD7190是一款高精度、低噪声的24位Σ-Δ型ADC,特别适合需要多通道采集的工业测量应用。与STM32的连接主要采用SPI接口,以下是硬件连接的详细说明:
-
电源连接:
- VDD和VREF+引脚都需要连接3.3V电源
- 建议在电源引脚附近放置0.1μF去耦电容
- 参考电压输入端(VREF+)需要特别关注稳定性,建议使用低噪声LDO供电
-
SPI接口连接:
- CS(片选):使用GPIO控制,低电平有效
- SCLK(时钟):SPI时钟线,建议速率不超过5MHz
- DIN(数据输入):STM32发送数据到AD7190
- DOUT(数据输出):AD7190发送数据到STM32
注意:AD7190的DOUT引脚在SPI通信期间会输出数据,空闲时应保持高阻态。如果使用STM32的硬件SPI接口,需要确保MISO引脚配置正确。
1.2 寄存器配置解析
AD7190有多个关键寄存器需要配置:
-
通信寄存器(COMM_REG):
- 用于选择要访问的寄存器
- 每次读写操作前都需要先写通信寄存器
-
模式寄存器(MODE_REG):
- 控制ADC的工作模式(连续/不连续)
- 设置滤波器参数(影响输出数据速率)
- 配置校准模式
-
配置寄存器(CONFIG_REG):
- 选择激活的输入通道
- 设置增益(1~128)
- 选择单/双极性输入
在代码中,我们使用以下关键配置:
c复制#define MODE_DISCONTINUOUS 0x04 // 不连续模式
#define CONFIG_CH0_1_2_3 0x80 // 使能通道0-3(差分输入)
#define CONFIG_GAIN_128 0x07 // 增益128倍
选择增益128倍时,需要注意输入信号范围不能超过VREF/GAIN,否则会导致输出饱和。例如,当VREF=3.3V时,最大输入电压为3.3V/128≈25.8mV。
2. 核心代码实现
2.1 SPI通信函数详解
AD7190的SPI通信有一些特殊要求:
-
时序要求:
- CS必须在SCLK为低电平时变化
- 数据在SCLK上升沿采样
- 每次传输都是24位数据
-
写寄存器函数:
c复制void AD7190_WriteReg(uint8_t regAddr, uint32_t data) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // CS拉低
HAL_SPI_Transmit(&hspi1, ®Addr, 1, 100); // 发送寄存器地址
HAL_SPI_Transmit(&hspi1, (uint8_t*)&data, 3, 100); // 发送24位数据
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // CS拉高
}
这里需要注意,AD7190的寄存器写入需要先发送8位寄存器地址,再发送24位数据。HAL_SPI_Transmit函数会自动处理字节顺序。
- 读寄存器函数:
c复制uint32_t AD7190_ReadReg(uint8_t regAddr) {
uint32_t data = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // CS拉低
HAL_SPI_Transmit(&hspi1, ®Addr, 1, 100); // 发送寄存器地址(读模式)
HAL_SPI_Receive(&hspi1, (uint8_t*)&data, 3, 100); // 接收24位数据
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // CS拉高
return data;
}
读操作时,需要先发送寄存器地址(最高位为1表示读操作),然后接收24位数据。
2.2 初始化配置流程
AD7190的初始化需要遵循特定顺序:
- 硬件复位:
c复制// 通过连续发送1来复位AD7190
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
for (int i = 0; i < 50; i++) {
HAL_SPI_Transmit(&hspi1, (uint8_t*)0xFF, 1, 100);
HAL_Delay(1);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
这种复位方式通过连续发送1来确保AD7190内部状态机复位。复位后需要等待至少500μs才能进行后续操作。
- 配置模式寄存器:
c复制AD7190_WriteReg(AD7190_MODE_REG, 0x040000 | MODE_DISCONTINUOUS);
这里0x040000设置滤波器参数,对应4.8kHz的输出数据速率。MODE_DISCONTINUOUS使能不连续转换模式。
- 配置输入通道和增益:
c复制AD7190_WriteReg(AD7190_CONFIG_REG, CONFIG_CH0_1_2_3 | CONFIG_GAIN_128);
这里同时使能了4个差分输入通道,并设置增益为128倍。
- 设置不连续组:
c复制AD7190_WriteReg(AD7190_COMM_REG, 0x00); // 选择模式寄存器
AD7190_WriteReg(AD7190_MODE_REG, 0x040000 | MODE_DISCONTINUOUS | 0x00000F); // 组大小=4
0x00000F表示4个通道为一组,在不连续模式下,ADC会依次转换这4个通道然后进入空闲状态。
2.3 数据采集实现
数据采集分为单通道读取和多通道轮询两种方式:
- 单通道读取:
c复制float AD7190_ReadChannel(uint8_t channel) {
uint32_t rawValue;
float voltage;
// 触发单次转换
AD7190_WriteReg(AD7190_COMM_REG, 0x00); // 选择数据寄存器
HAL_Delay(1); // 等待转换完成
// 读取数据
rawValue = AD7190_ReadReg(AD7190_DATA_REG);
// 数据转换(单极性模式)
voltage = (rawValue * 3.3f) / 0xFFFFFF; // 24位数据转换
return voltage;
}
这里需要注意,HAL_Delay(1)的等待时间需要根据实际输出数据速率调整。对于4.8kHz的速率,转换时间约为208μs。
- 多通道轮询:
c复制void AD7190_MultiRead(float* results) {
for (int i = 0; i < 4; i++) {
results[i] = AD7190_ReadChannel(i);
HAL_Delay(10); // 通道切换延时
}
}
通道切换需要一定时间稳定,HAL_Delay(10)提供了足够的稳定时间。在实际应用中,可以根据信号特性调整这个延时。
3. 关键参数与性能优化
3.1 不连续模式配置细节
不连续模式与连续模式的主要区别:
-
工作方式:
- 连续模式:ADC持续转换,数据寄存器不断更新
- 不连续模式:完成一组转换后进入空闲状态,需要外部触发下一次转换
-
功耗对比:
- 不连续模式功耗更低,适合电池供电应用
- 连续模式响应更快,适合高速采集
-
组配置:
- 通过MODE_REG的GSEL位设置组大小
- 0x00000F表示4通道一组
- 可以配置为1-16个通道一组
3.2 数据格式与校准
-
数据格式转换:
- 单极性模式:0~VREF对应0~2²⁴-1
- 双极性模式:-VREF/2~+VREF/2对应-2²³~+2²³-1
-
校准方法:
- 零点校准:短接输入引脚,执行零点校准
- 满量程校准:施加已知参考电压,执行满量程校准
- 校准系数存储在内部寄存器中
校准代码示例:
c复制// 零点校准
AD7190_WriteReg(AD7190_COMM_REG, 0x00); // 选择模式寄存器
AD7190_WriteReg(AD7190_MODE_REG, 0x040000 | MODE_ADJUST_ZERO);
HAL_Delay(100); // 等待校准完成
3.3 采样率与滤波器设置
AD7190的输出数据速率由模式寄存器的FILTER位控制:
-
滤波器选择:
- 同步滤波器:抑制50/60Hz工频干扰
- 快速滤波器:响应更快,但噪声较大
- SINC4滤波器:折中方案,平衡速度和噪声
-
典型配置:
- 4.8kHz:0x040000
- 2.4kHz:0x080000
- 1.2kHz:0x100000
更高的输出数据速率会降低分辨率,需要根据应用需求权衡。
4. 调试技巧与常见问题
4.1 硬件调试要点
-
电源噪声:
- 使用低噪声LDO供电
- 增加足够的去耦电容
- 分离模拟和数字地
-
信号完整性:
- 保持信号线短且直
- 避免平行走线减少串扰
- 对敏感信号使用屏蔽线
-
参考电压:
- 使用低噪声参考源
- 增加10μF+0.1μF滤波电容
- 避免负载变化影响参考电压
4.2 软件调试技巧
-
SPI通信验证:
- 先尝试读取ID寄存器(默认值0x0X)
- 使用逻辑分析仪捕获SPI波形
- 检查CS信号时序
-
数据异常排查:
- 检查电源电压是否稳定
- 验证参考电压值
- 检查输入信号是否超范围
-
噪声抑制方法:
- 软件滤波(移动平均、中值滤波)
- 适当降低输出数据速率
- 启用芯片内置滤波器
4.3 性能优化建议
-
提高采样精度:
- 降低输出数据速率
- 使用外部低噪声参考
- 执行系统校准
-
多通道同步:
c复制// 配置4通道同步转换
AD7190_WriteReg(AD7190_COMM_REG, 0x00);
AD7190_WriteReg(AD7190_MODE_REG, 0x040000 | MODE_DISCONTINUOUS | 0x0000FF);
这种配置可以减少通道切换带来的时序误差。
- 低功耗设计:
- 使用不连续模式
- 在不采集时关闭部分电路
- 降低SPI时钟频率
5. 完整工程实现
5.1 CubeMX配置要点
-
SPI配置:
- 模式:Full-Duplex Master
- 时钟极性(CPOL):Low
- 时钟相位(CPHA):1 Edge
- 数据大小:8bit
- 时钟分频:根据需求设置(≤5MHz)
-
GPIO配置:
- CS引脚:输出模式,初始高电平
- 其他SPI引脚:根据硬件连接配置
-
时钟配置:
- 确保系统时钟足够支持SPI速率
- 考虑使用外部晶振提高时钟精度
5.2 中断处理优化
对于实时性要求高的应用,可以使用中断方式:
- 中断配置:
c复制// 在CubeMX中启用SPI中断
// 在NVIC中设置适当优先级
- 中断服务函数:
c复制void SPI1_IRQHandler(void) {
HAL_SPI_IRQHandler(&hspi1);
if (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE)) {
// 处理接收完成中断
uint8_t data = SPI1->DR;
// ...数据处理逻辑...
}
}
- DMA应用:
- 对于高速连续采集,可以配置SPI DMA
- 减少CPU开销,提高系统效率
5.3 工程结构建议
-
模块化设计:
- ad7190.c/h:AD7190驱动
- spi.c/h:SPI底层接口
- main.c:应用逻辑
-
配置文件:
- 硬件相关参数集中管理
- 便于移植到不同平台
-
调试接口:
- 添加串口打印调试信息
- 设计状态指示LED
在实际项目中,我发现模块化设计可以大大提高代码的可维护性。特别是将AD7190的驱动与硬件平台分离,只需要修改底层的SPI接口函数就可以移植到不同的MCU平台。