|
|
第一次从零开始调试AD7124,真不容易,主要是它有50多个寄存器不知道怎么配置,90多页的芯片手册也看的一头雾水,网上CSDN很多资料都是收费的,于是自己研究。
经过反复研究芯片手册,借助AI和网友的力量,反复修改驱动、修改寄存器配置,花了2周时间,终于勉强调试成功。
具体成果如下:
通道1,我配置它用于读取片内温度传感器数值,读出来温度异常;
通道2,我配置它用于读取热电偶,正常;
通道3,我配置它用于读取PT1000,正常;
AD7124的配置和原理图相关,不能生搬硬套,贴出核心配置函数,仅供参考,完整工程涉及大量其它代码不便上传,有需要可以联系我,免费提供代码和技术交流。
如果各位找到 “通道1,我配置它用于读取片内温度传感器数值,读出来温度异常” 的原因,也感谢告知。
void ad7124_collect_task(void *arg)
{
uint8_t status_byte;
uint8_t ch_active;
uint32_t raw_code;
int32_t code;
float temp_chip;
float tc_mv;
float r_rtd;
float temp_rtd;
struct ad7124_st_reg user_config[AD7124_REG_NO];
#define TC_FILTER_LEN 8
static float tc_filter_buf[TC_FILTER_LEN] = {0.0f};
static uint8_t filter_idx = 0;
static float filter_sum = 0.0f;
static uint8_t valid_cnt = 0; // 有效采样计数
vTaskDelay(pdMS_TO_TICKS(100));
// 芯片硬件复位
ad7124_reset();
// 拷贝寄存器默认模板
memcpy(user_config, ad7124_regs, sizeof(ad7124_regs));
//=====================================================================
// ADC全局控制寄存器配置
// REF_EN=1 开启内部2.5V基准(供给片内温度传感器、热电偶通道)
// DATA_STATUS=1 开启:读DATA寄存器时自动附带STATUS字节,数据与通道原子绑定
// POWER_MODE=3 全功耗模式,多路采样推荐
// MODE=0 连续自动转换模式,多通道自动轮询
//=====================================================================
user_config[AD7124_ADC_Control].value = AD7124_ADC_CTRL_REG_REF_EN // 使能片内2.5V内部基准
| AD7124_ADC_CTRL_REG_DATA_STATUS // 开启DATA附加STATUS模式
| AD7124_ADC_CTRL_REG_POWER_MODE(3) // 全功耗模式
| AD7124_ADC_CTRL_REG_MODE(0); // 连续转换模式,多通道自动轮询
//=====================================================================
// IO控制寄存器1
// PDSW=1:PSW内部接AGND → 红色LED点亮
// IOUT1=250uA,电流输出引脚选择AIN1,给PT1000四线回路提供激励电流
// 原理图IOUT1网络连接芯片AIN1引脚,AIN1仅作恒流输出,无ADC通道占用,无冲突
//=====================================================================
user_config[AD7124_IOCon1].value = AD7124_IO_CTRL1_REG_PDSW // PDSW使能,PSW引脚下拉,LED点亮
| AD7124_IO_CTRL1_REG_IOUT1(3) // IOUT1激励电流 250uA
| AD7124_IO_CTRL1_REG_IOUT_CH1(1); // IOUT1恒流从AIN1引脚输出
//=====================================================================
// Setup0:供给【Channel1 片内温度传感器】
// 基准选择:内部2.5V;双极性;基准缓冲开启
//=====================================================================
user_config[AD7124_Config_0].value = AD7124_CFG_REG_BIPOLAR // 双极性输入模式
| AD7124_CFG_REG_REF_BUFP // 基准正端缓冲使能
| AD7124_CFG_REG_REF_BUFM // 基准负端缓冲使能
| AD7124_CFG_REG_REF_SEL(2) // 选择片内2.5V内部基准
| AD7124_CFG_REG_PGA(0); // PGA=1倍/±2.5 V
user_config[AD7124_Filter_0].value = AD7124_FILT_REG_FS(0x080); // 滤波器输出速率设置
// Channel1:片内温度传感器
// AINP=16 内部温度源,AINM=17 AVSS
user_config[AD7124_Channel_1].value = AD7124_CH_MAP_REG_CH_ENABLE // 通道使能
| AD7124_CH_MAP_REG_SETUP(0) // 使用Setup0配置
| AD7124_CH_MAP_REG_AINP(16) // AINP选择片内温度传感器
| AD7124_CH_MAP_REG_AINM(17); // AINM选择AVSS
//=====================================================================
// Setup1:供给【Channel2 热电偶 AIN2+/AIN3-】
// 基准选择:内部2.5V,与PT1000外部REFIN1基准完全解耦,避免相互负载干扰
// 双极性;无激励电流
//=====================================================================
user_config[AD7124_Config_1].value = AD7124_CFG_REG_BIPOLAR // 双极性输入模式
| AD7124_CFG_REG_REF_BUFP // 基准正端缓冲使能
| AD7124_CFG_REG_REF_BUFM // 基准负端缓冲使能
| AD7124_CFG_REG_REF_SEL(2) // 选择片内2.5V内部基准
//| AD7124_CFG_REG_PGA(4); // PGA=16倍/±156.25 mV
| AD7124_CFG_REG_PGA(7); // PGA=128倍/±19.53 mV
user_config[AD7124_Filter_1].value = AD7124_FILT_REG_FS(1920); // 滤波器输出速率设置
// Channel2:热电偶 AIN2(+) AIN3(-)
user_config[AD7124_Channel_2].value = AD7124_CH_MAP_REG_CH_ENABLE // 通道使能
| AD7124_CH_MAP_REG_SETUP(1) // 使用Setup1配置
| AD7124_CH_MAP_REG_AINP(2) // AINP选择AIN2
| AD7124_CH_MAP_REG_AINM(3); // AINM选择AIN3
//=====================================================================
// Setup2:供给【Channel3 PT1000四线RTD AIN6+/AIN7-】
// 基准选择:外部REFIN1;双极性;激励电流由IOCon1独立控制
// 比率测温拓扑:IOUT1→PT1000→基准电阻串,REFIN1并联基准电阻两端,电流自动抵消
//=====================================================================
user_config[AD7124_Config_2].value = AD7124_CFG_REG_BIPOLAR // 双极性输入模式
| AD7124_CFG_REG_REF_BUFP // 基准正端缓冲使能
| AD7124_CFG_REG_REF_BUFM // 基准负端缓冲使能
| AD7124_CFG_REG_REF_SEL(0) // 选择外部REFIN1基准
| AD7124_CFG_REG_PGA(0); // PGA=1倍
user_config[AD7124_Filter_2].value = AD7124_FILT_REG_FS(0x080); // 滤波器输出速率设置
// Channel3:PT1000四线电阻 AIN6(+) AIN7(-)
user_config[AD7124_Channel_3].value = AD7124_CH_MAP_REG_CH_ENABLE // 通道使能
| AD7124_CH_MAP_REG_SETUP(2) // 使用Setup2配置
| AD7124_CH_MAP_REG_AINP(6) // AINP选择AIN6
| AD7124_CH_MAP_REG_AINM(7); // AINM选择AIN7
//=====================================================================
// 关闭Channel0,消除轮询扫描通道0产生ch_active=0
//=====================================================================
user_config[AD7124_Channel_0].value = 0x0000;
//user_config[AD7124_Channel_1].value = 0x0000;
//user_config[AD7124_Channel_2].value = 0x0000;
//user_config[AD7124_Channel_3].value = 0x0000;
//=====================================================================
// 将全部配置下发至AD7124芯片
//=====================================================================
ad7124_load_config(user_config);
vTaskDelay(pdMS_TO_TICKS(100));
// 回读所有寄存器,校验配置是否写入成功(调试可保留,量产可注释)
ad7124_sync_chip_regs(user_config);
vTaskDelay(pdMS_TO_TICKS(100));
//=====================================================================
// 持续采集循环
// DATA_STATUS模式:一次SPI读出24bit DATA + 1byte STATUS
// STATUS Bit7 = RDY(0=就绪);Bit0~Bit3 = 当前数据所属通道号
// 消除【先读STATUS再读DATA】造成的通道错位竞争风险
//=====================================================================
while(1)
{
vTaskDelay(pdMS_TO_TICKS(100));
// 一次性读取24bit原始ADC + 附带STATUS字节
if(ad7124_read_raw_data_with_status(&raw_code, &status_byte) == 0)
{
// RDY位:Bit7,0代表转换就绪有效
if((status_byte & 0x80) == 0)
{
ch_active = status_byte & 0x0F;
code = (int32_t)raw_code; // 强制转有符号,处理正负输入
// 统一打印通道、原始无符号、有符号值,方便观测ch_active=0的数据
printf("ch_active=%d, raw=0X%06X, code=0X%06X\r\n", ch_active, raw_code, code);
if(ch_active == 0)
{
// Channel0暂时保留启用状态,直接丢弃不参与计算
}
if(ch_active == 1)
{
// Channel1 芯片内部PN结温度,公式严格依照AD7124手册
float temp_chip = ((code - 0x800000) / 13584.0f) - 272.5f;
printf("[CHIP_TEMP] T=%.2f ℃\r\n", temp_chip);
}
if(ch_active == 2)
{
//tc_mv = ((code - 0x800000) / 8388608.0f) * (2500.0f / 16.0f);//PGA=16
tc_mv = ((code - 0x800000) / 8388608.0f) * (2500.0f / 128.0f);//PGA=128
tc_mv=tc_mv*1000;
filter_sum -= tc_filter_buf[filter_idx];
tc_filter_buf[filter_idx] = tc_mv;
filter_sum += tc_filter_buf[filter_idx];
// 有效计数上限为滤波长度
if(valid_cnt < TC_FILTER_LEN)
{
valid_cnt++;
}
filter_idx = (filter_idx + 1) % TC_FILTER_LEN;
// 关键:用有效个数做分母
float tc_avg = filter_sum / valid_cnt;
printf("[TC] tc_mv=%.4f mV,tc_avg=%.4f mV\r\n", tc_mv,tc_avg);
}
if(ch_active == 3)
{
float delta = code - 0x800000;
float raw_r = (delta / 8388608.0f) * 5110.0f;
// 校准系数,补偿硬件分压偏小
float cal_k = 1.072f;
float r_rtd = raw_r * cal_k;
// 调用全量程迭代函数,支持零下测温
temp_rtd = Pt1000_CalcTemp_FullRange(r_rtd);
printf("[PT1000] R=%.2f Ω , T=%.2f ℃\r\n", r_rtd, temp_rtd);
}
}
}
}
}
|
|