AD7124-4 精度

AD7124芯片,是属于AD公司的较新产品,高达24位的精度,确实让人眼馋,究竟如何呢。

寄存器配置顺序
1、AD上电后,先关闭SPI片选
2、使能开启单片机的 SPI
3、复位设备及所有内部寄存器,发送64位的1,也就是8个0xFF
4、读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
5、做好从 AD7124_ADC_Control 到 AD7124_Filter_7寄存器的配置清单、通道配置、滤波配置等。(在实际应用中,可以一次调零校准和满量程校准后,将该通道的失调寄存器的值和增益寄存器的值直接保存起来,下次上电后再直接写进去,就不用反复校准了,如果需要将失调寄存器和增益寄存器写入的话,记得把Control寄存器配置为低功耗或中功耗模式!!!我这里是直接将Control寄存器设置为低功耗、空闲模式,然后开始校准,所以没有写入失调寄存器和增益寄存器)
6、将从 AD7124_ADC_Control 到 AD7124_Filter_7ADC所有寄存器写入AD芯片,写入过程中,建议写一个寄存器,就延时20-30ms,另外,需要修改的才写,不需要修改的寄存器就不用写,浪费时间。
7、内部满量程校准,再写Control寄存器,设置内部满量程校准。
8、等待一下,确保校准完成。
9、读Status Register寄存器,用于清除该寄存器中上电复位标志。由于校准后会自动进入空闲模式,我在调试过程中,居然有出现上电复位标志被置位了,所以读一下为好,这个上电复位标志为1的话,功能都运行不了。。。
10、内部零电平校准,再写Control寄存器,设置内部零电平校准。
11、等待一下,确保校准完成。
12、读Status Register寄存器,用于清除该寄存器中上电复位标志。由于校准后会自动进入空闲模式,我在调试过程中,居然有出现上电复位标志被置位了,所以读一下为好,这个上电复位标志为1的话,功能都运行不了。。。
13、现在可以将Control寄存器设置为全功率、连续运行模式等等了。我是设置为 全功率、单次运行模式。
单次运行模式被设置后,AD进行一次转换,然后自动进入空闲模式,Status寄存器的RDY位为0,表示数据转换完成。读取数据后,再设置Control寄存器全功率、单次运行模式,等Status寄存器的RDY位为0了,就读写,依次循环…
下面上部分代码

int32_t AD7124_Setup(ad7124_device *device)
{
		int32_t ret;
		enum ad7124_registers regNr;
		
		if(!device)
			return INVALID_VAL;
			
		SPI1_CS_SET;		//关闭片选
		
		__HAL_SPI_ENABLE(&hspi1);		// 使能SPI1,开启

		AD7124_Reset();							// 复位设备及所有内部寄存器

		device->check_ready = 1;		// 使能检查设备准备好,使用开机/重置设置更新设备结构

		ret = AD7124_ReadRegister( device, &device->regs[AD7124_ID] );		//读ID寄存器
		if (ret < 0)
			return ret;	
		
		//读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
		ret = AD7124_ReadRegister( device, &device->regs[AD7124_Status] );
		if (ret < 0)
			return ret;			
		
		// ADC所有寄存器初始化,从 AD7124_ADC_Control 到 AD7124_Offset_0
		for( regNr = AD7124_ADC_Control; (regNr <= AD7124_Offset_0); regNr++ )
		{
			HAL_Delay(30);
			
			if ( device->regs[regNr].rw == AD7124_RW )
			{
				ret = AD7124_WriteRegister( device, &device->regs[regNr] );
				printf("AD-write-%X---%X\n",regNr,device->regs[regNr].value);	//写入AD数据
				if (ret < 0)
						break;
			}
			// 获取CRC状态和设备SPI接口设置,
			// 根据初始化的寄存器数组ad7124_st_reg ad7124_regs[],确定是否需要CRC、检查设备准备好,并更新设置 
			if (regNr == AD7124_Error_En)
			{
				AD7124_UpdateCRCSetting(device);			
				AD7124_UpdateDevSpiSettings(device);
			}
			if ( regNr == AD7124_ADC_Control )
			{			//如果控制寄存器开启了DATA_STATUS位(读数据寄存器后将,将跟随一个字节的指示那个通道的值,再加CRC,即3+1+CRC)
						//那么读AD7124_Data字节数量将增加1个
					if ( device->regs[AD7124_ADC_Control].value & AD7124_ADC_CTRL_REG_DATA_STATUS )
					{		
							(device->regs[AD7124_Data].size)++;
					}
			}
		}
		if (ret < 0)
			return ret;		

		//
		// 内部满量程校准
		device->regs[AD7124_ADC_Control].value = 
							/* 控制寄存器 ADC_Control Register bits */
						//	  AD7124_ADC_CTRL_REG_DOUT_RDY_DEL  // (1 << 12),
						//	| AD7124_ADC_CTRL_REG_CONT_READ     // (1 << 11)
							  AD7124_ADC_CTRL_REG_DATA_STATUS   // (1 << 10),开启数据寄存器后跟随通道显示
						//	| AD7124_ADC_CTRL_REG_CS_EN         // (1 << 9)
							| AD7124_ADC_CTRL_REG_REF_EN        // (1 << 8),内部基准电压使能,1=内部使能,0=外部使能
							| AD7124_ADC_CTRL_REG_POWER_MODE(0) // (((x) & 0x3) << 6),电源模式,0-1-2-3,低、中、全、全功耗
							| AD7124_ADC_CTRL_REG_MODE(6)       // (((x) & 0xF) << 2),ADC工作模式,5=内部调零,6=内部满量程,7=系统零电平校准,8=系统满量程
							| AD7124_ADC_CTRL_REG_CLK_SEL(0)   // (((x) & 0x3) << 0),ADC时钟源选择
							;

		printf("nbmlc->W_Control=%0x \n",(device->regs[AD7124_ADC_Control].value));
	
		ret = AD7124_WriteRegister(device, &device->regs[AD7124_ADC_Control]);	//写入值,AD将会进入中功率,满量程校准模式,
		if (ret < 0)																														//校准完成后,自动进入空闲模式
			return ret;		
		
		HAL_Delay(5000);
		
		ret = AD7124_WaitForConvReady(device, 10000);
		if (ret < 0)		
			return ret;		
		
		//读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
		ret = AD7124_ReadRegister( device, &device->regs[AD7124_Status] );
		if (ret < 0)
			return ret;			
		
		//
		
		// 内部零电平校准
		device->regs[AD7124_ADC_Control].value = 
							/* 控制寄存器 ADC_Control Register bits */
						//	  AD7124_ADC_CTRL_REG_DOUT_RDY_DEL  // (1 << 12),
						//	| AD7124_ADC_CTRL_REG_CONT_READ     // (1 << 11)
							  AD7124_ADC_CTRL_REG_DATA_STATUS   // (1 << 10),开启数据寄存器后跟随通道显示
						//	| AD7124_ADC_CTRL_REG_CS_EN         // (1 << 9)
							| AD7124_ADC_CTRL_REG_REF_EN        // (1 << 8),内部基准电压使能,1=内部使能,0=外部使能
							| AD7124_ADC_CTRL_REG_POWER_MODE(0) // (((x) & 0x3) << 6),电源模式,0-1-2-3,低、中、全、全功耗
							| AD7124_ADC_CTRL_REG_MODE(5)       // (((x) & 0xF) << 2),ADC工作模式,5=内部调零,6=内部满量程,7=系统零电平校准,8=系统满量程
							| AD7124_ADC_CTRL_REG_CLK_SEL(0)   // (((x) & 0x3) << 0),ADC时钟源选择
							;		
		
		printf("nbtl->W_Control=%0x \n",(device->regs[AD7124_ADC_Control].value));
		
		ret = AD7124_WriteRegister(device, &device->regs[AD7124_ADC_Control]);
		if (ret < 0)
			return ret;		
		
		HAL_Delay(5000);	
		
		ret = AD7124_WaitForConvReady(device, 10000);
		if (ret < 0)		
			return ret;		
		
		//读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
		ret = AD7124_ReadRegister( device, &device->regs[AD7124_Status] );
		if (ret < 0)
			return ret;		
		
		printf("\n----AD AD7124_Setup(0=normal)= %d----\n",ret);			
		
		return ret;
}

下面来说说精度问题
我是使用了内部基准2.5V,AI1 和 AI2 引脚直接接信号发生器,由于只是测试,没有接任何电容电阻等其他元件,AI输入配置为缓冲,基准不缓冲,PGA放大16倍。

第一列数据:AD转换码, 第二列:转换为电压值(单位mV,图片中单位错误,见谅), 第三列:上次AD转换码与本次之差。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

版权声明:本文为CSDN博主「weixin_44224303」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44224303/article/details/122135739

AD7124芯片,是属于AD公司的较新产品,高达24位的精度,确实让人眼馋,究竟如何呢。

寄存器配置顺序
1、AD上电后,先关闭SPI片选
2、使能开启单片机的 SPI
3、复位设备及所有内部寄存器,发送64位的1,也就是8个0xFF
4、读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
5、做好从 AD7124_ADC_Control 到 AD7124_Filter_7寄存器的配置清单、通道配置、滤波配置等。(在实际应用中,可以一次调零校准和满量程校准后,将该通道的失调寄存器的值和增益寄存器的值直接保存起来,下次上电后再直接写进去,就不用反复校准了,如果需要将失调寄存器和增益寄存器写入的话,记得把Control寄存器配置为低功耗或中功耗模式!!!我这里是直接将Control寄存器设置为低功耗、空闲模式,然后开始校准,所以没有写入失调寄存器和增益寄存器)
6、将从 AD7124_ADC_Control 到 AD7124_Filter_7ADC所有寄存器写入AD芯片,写入过程中,建议写一个寄存器,就延时20-30ms,另外,需要修改的才写,不需要修改的寄存器就不用写,浪费时间。
7、内部满量程校准,再写Control寄存器,设置内部满量程校准。
8、等待一下,确保校准完成。
9、读Status Register寄存器,用于清除该寄存器中上电复位标志。由于校准后会自动进入空闲模式,我在调试过程中,居然有出现上电复位标志被置位了,所以读一下为好,这个上电复位标志为1的话,功能都运行不了。。。
10、内部零电平校准,再写Control寄存器,设置内部零电平校准。
11、等待一下,确保校准完成。
12、读Status Register寄存器,用于清除该寄存器中上电复位标志。由于校准后会自动进入空闲模式,我在调试过程中,居然有出现上电复位标志被置位了,所以读一下为好,这个上电复位标志为1的话,功能都运行不了。。。
13、现在可以将Control寄存器设置为全功率、连续运行模式等等了。我是设置为 全功率、单次运行模式。
单次运行模式被设置后,AD进行一次转换,然后自动进入空闲模式,Status寄存器的RDY位为0,表示数据转换完成。读取数据后,再设置Control寄存器全功率、单次运行模式,等Status寄存器的RDY位为0了,就读写,依次循环…
下面上部分代码

int32_t AD7124_Setup(ad7124_device *device)
{
		int32_t ret;
		enum ad7124_registers regNr;
		
		if(!device)
			return INVALID_VAL;
			
		SPI1_CS_SET;		//关闭片选
		
		__HAL_SPI_ENABLE(&hspi1);		// 使能SPI1,开启

		AD7124_Reset();							// 复位设备及所有内部寄存器

		device->check_ready = 1;		// 使能检查设备准备好,使用开机/重置设置更新设备结构

		ret = AD7124_ReadRegister( device, &device->regs[AD7124_ID] );		//读ID寄存器
		if (ret < 0)
			return ret;	
		
		//读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
		ret = AD7124_ReadRegister( device, &device->regs[AD7124_Status] );
		if (ret < 0)
			return ret;			
		
		// ADC所有寄存器初始化,从 AD7124_ADC_Control 到 AD7124_Offset_0
		for( regNr = AD7124_ADC_Control; (regNr <= AD7124_Offset_0); regNr++ )
		{
			HAL_Delay(30);
			
			if ( device->regs[regNr].rw == AD7124_RW )
			{
				ret = AD7124_WriteRegister( device, &device->regs[regNr] );
				printf("AD-write-%X---%X\n",regNr,device->regs[regNr].value);	//写入AD数据
				if (ret < 0)
						break;
			}
			// 获取CRC状态和设备SPI接口设置,
			// 根据初始化的寄存器数组ad7124_st_reg ad7124_regs[],确定是否需要CRC、检查设备准备好,并更新设置 
			if (regNr == AD7124_Error_En)
			{
				AD7124_UpdateCRCSetting(device);			
				AD7124_UpdateDevSpiSettings(device);
			}
			if ( regNr == AD7124_ADC_Control )
			{			//如果控制寄存器开启了DATA_STATUS位(读数据寄存器后将,将跟随一个字节的指示那个通道的值,再加CRC,即3+1+CRC)
						//那么读AD7124_Data字节数量将增加1个
					if ( device->regs[AD7124_ADC_Control].value & AD7124_ADC_CTRL_REG_DATA_STATUS )
					{		
							(device->regs[AD7124_Data].size)++;
					}
			}
		}
		if (ret < 0)
			return ret;		

		//
		// 内部满量程校准
		device->regs[AD7124_ADC_Control].value = 
							/* 控制寄存器 ADC_Control Register bits */
						//	  AD7124_ADC_CTRL_REG_DOUT_RDY_DEL  // (1 << 12),
						//	| AD7124_ADC_CTRL_REG_CONT_READ     // (1 << 11)
							  AD7124_ADC_CTRL_REG_DATA_STATUS   // (1 << 10),开启数据寄存器后跟随通道显示
						//	| AD7124_ADC_CTRL_REG_CS_EN         // (1 << 9)
							| AD7124_ADC_CTRL_REG_REF_EN        // (1 << 8),内部基准电压使能,1=内部使能,0=外部使能
							| AD7124_ADC_CTRL_REG_POWER_MODE(0) // (((x) & 0x3) << 6),电源模式,0-1-2-3,低、中、全、全功耗
							| AD7124_ADC_CTRL_REG_MODE(6)       // (((x) & 0xF) << 2),ADC工作模式,5=内部调零,6=内部满量程,7=系统零电平校准,8=系统满量程
							| AD7124_ADC_CTRL_REG_CLK_SEL(0)   // (((x) & 0x3) << 0),ADC时钟源选择
							;

		printf("nbmlc->W_Control=%0x \n",(device->regs[AD7124_ADC_Control].value));
	
		ret = AD7124_WriteRegister(device, &device->regs[AD7124_ADC_Control]);	//写入值,AD将会进入中功率,满量程校准模式,
		if (ret < 0)																														//校准完成后,自动进入空闲模式
			return ret;		
		
		HAL_Delay(5000);
		
		ret = AD7124_WaitForConvReady(device, 10000);
		if (ret < 0)		
			return ret;		
		
		//读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
		ret = AD7124_ReadRegister( device, &device->regs[AD7124_Status] );
		if (ret < 0)
			return ret;			
		
		//
		
		// 内部零电平校准
		device->regs[AD7124_ADC_Control].value = 
							/* 控制寄存器 ADC_Control Register bits */
						//	  AD7124_ADC_CTRL_REG_DOUT_RDY_DEL  // (1 << 12),
						//	| AD7124_ADC_CTRL_REG_CONT_READ     // (1 << 11)
							  AD7124_ADC_CTRL_REG_DATA_STATUS   // (1 << 10),开启数据寄存器后跟随通道显示
						//	| AD7124_ADC_CTRL_REG_CS_EN         // (1 << 9)
							| AD7124_ADC_CTRL_REG_REF_EN        // (1 << 8),内部基准电压使能,1=内部使能,0=外部使能
							| AD7124_ADC_CTRL_REG_POWER_MODE(0) // (((x) & 0x3) << 6),电源模式,0-1-2-3,低、中、全、全功耗
							| AD7124_ADC_CTRL_REG_MODE(5)       // (((x) & 0xF) << 2),ADC工作模式,5=内部调零,6=内部满量程,7=系统零电平校准,8=系统满量程
							| AD7124_ADC_CTRL_REG_CLK_SEL(0)   // (((x) & 0x3) << 0),ADC时钟源选择
							;		
		
		printf("nbtl->W_Control=%0x \n",(device->regs[AD7124_ADC_Control].value));
		
		ret = AD7124_WriteRegister(device, &device->regs[AD7124_ADC_Control]);
		if (ret < 0)
			return ret;		
		
		HAL_Delay(5000);	
		
		ret = AD7124_WaitForConvReady(device, 10000);
		if (ret < 0)		
			return ret;		
		
		//读Status Register寄存器,用于清除上电复位标志,否则对AD7124_ADC_Control的配置不起作用,AD7124-8似乎没有这个问题。非常重要!!
		ret = AD7124_ReadRegister( device, &device->regs[AD7124_Status] );
		if (ret < 0)
			return ret;		
		
		printf("\n----AD AD7124_Setup(0=normal)= %d----\n",ret);			
		
		return ret;
}

下面来说说精度问题
我是使用了内部基准2.5V,AI1 和 AI2 引脚直接接信号发生器,由于只是测试,没有接任何电容电阻等其他元件,AI输入配置为缓冲,基准不缓冲,PGA放大16倍。

第一列数据:AD转换码, 第二列:转换为电压值(单位mV,图片中单位错误,见谅), 第三列:上次AD转换码与本次之差。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

版权声明:本文为CSDN博主「weixin_44224303」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44224303/article/details/122135739

生成海报
点赞 0

weixin_44224303

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

串口不定长接收

一、保留接收区和开启接收的语句    uint8_t buffer[5];HAL_UART_Transmit_IT(&huart1,buffer,3); 二、写入开启空闲中断的语句    __HAL_UART_ENABLE_IT(&huart

基于STM32单片机的电子密码锁设计

一.硬件方案 本设计采用STM32F103C8T6单片机作为主控芯片,结合外围的矩阵按键输入、LCD1602液晶显示、报警、开锁等电路模块实现开锁、上锁、报警、密码更改等功能,设计了一款可以多次修改密码并且具有报警