芯片介绍
AD7192是一片24位的转换芯片,芯片内部有个4.92MHz的时钟可作为ADC的采样时钟源,数据输出速率可选为4.7Hz-4.8KHz之间
芯片内部框图
如图:
- 芯片可配置四个伪差分输入,每个输入就是一个通道
- 芯片允许启用多个通道,启用多个通道时,芯片会顺序依次转换启用的通道(串行转换,耗时),在每次通道切换时,ADC必须允许完整的稳定时间来生成有效的转换
- 所有有效通道读取有效转换所需时间:tSETTLE × 有效通道数;tSETTLE = 4/fADC;fADC – 数据输出速率;模式寄存器的后十位可以控制数据输出速率
- 多通道启用时还可选择单次转换或者连续转换
- 启用多通道转换必须将状态寄存器的内容附加到数据寄存器内容里,组成32位寄存器,开启附加转换,需将模式寄存器中的位DAT_STA置1
片内寄存器
寄存器 | 位数 | 读写 |
---|---|---|
通信寄存器 | 8 | 写 |
状态寄存器 | 8 | 读 |
模式寄存器 | 24 | 读写 |
配置寄存器 | 24 | 读写 |
数据寄存器 | 24 | 读 |
ID寄存器 | 8 | 读 |
GPOCON寄存器 | 8 | 读写 |
偏移寄存器 | 24 | 读写 |
满刻度寄存器 | 24 | 读写 |
通信寄存器
状态寄存器
模式寄存器
配置寄存器
其余寄存器
使用记录
基于多通道连续转换
#define WEN 0x00 //写使能
#define WEN_DIS 0x80 //写失能
#define RW_W 0x00 //写操作
#define RW_R 0x40 //读操作
#define CREAD_EN 0x04 //连续读取使能
#define CREAD_DIS 0x00 //连续读取失能
片内寄存器定义
#define REG_COM_STA 0x00 //状态/通信寄存器:00000 000
#define REG_MODE 0x01 //模式寄存器:00000 001
#define REG_CONF 0x02 //配置寄存器:00000 010
#define REG_DATA 0x03 //数据寄存器:00000 011
#define REG_ID 0x04 //ID寄存器:00000 100
#define REG_GPOCON 0x05 //GPOCON寄存器:00000 101
#define REG_OFFSET 0x06 //偏移寄存器:00000 110
#define REG_FS 0x07 //满量程寄存器:00000 111
AD7192芯片初始化流程:
- 复位 – 往通信寄存器连续写入40位1,及5个0xff
- 内部零电平校准
- 内部满量程校准
- 模式寄存器和配置寄存器配置写入
- 读取数据
复位
/**
-
@brief AD7192复位
-
@param
-
@retval
*/
void AD7192SoftwareReset()
{
unsigned char WriteBuf[1];
unsigned char i;SPI_CS_LOW();
WriteBuf[0] = 0xFF; // 填充8位1
for(i=0; i<5; i++) // 循环5次,4*8=40位1
{
SPI_TEMP_SendByte(WriteBuf[0]);
}
SPI_CS_HIGH();
}
内部零电平校准
/**
-
@brief AD7192内部零电平校准
-
@param
-
@retval
*/
void AD7192InternalZeroScaleCalibration()
{
AD7192Registers[REG_MODE] = 0;
AD7192Registers[REG_CONF] = 0;
AD7192Registers[REG_CONF] = CHOP_DIS|REF_IN1|AIN4_COM|AIN3_COM|AIN2_COM|BURN_DIS|REFDET_DIS|BUF_DIS|UB_BI|GAIN_1; // Gain = 1
WriteToAD7192ViaSPI(REG_CONF, 1, AD7192Registers, REG_CONF);AD7192Registers[REG_MODE] = MODE_INZCL|DAT_STA_EN|INCLK_MCLK2EN|SINC_3|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x080;
WriteToAD7192ViaSPI(REG_MODE, 1, AD7192Registers, REG_MODE);SPI_CS_LOW();
while(GPIO_ReadInputDataBit(GPIOB, TEMP_SPI_MISO_PIN)== 1){;}
SPI_CS_HIGH();
}
内部满量程校准
/**
-
@brief AD7192内部满量程校准
-
@param
-
@retval
*/
void AD7192InternalFullScaleCalibration()
{
AD7192Registers[REG_MODE] = 0;
AD7192Registers[REG_CONF] = 0;
AD7192Registers[REG_CONF] = CHOP_DIS|REF_IN1|AIN4_COM|AIN3_COM|AIN2_COM|BURN_DIS|REFDET_DIS|BUF_DIS|UB_BI|GAIN_1; // Gain = 1
WriteToAD7192ViaSPI(REG_CONF, 1, AD7192Registers, REG_CONF);AD7192Registers[REG_MODE] = 0;
AD7192Registers[REG_MODE] = MODE_INFCL|DAT_STA_EN|INCLK_MCLK2EN|SINC_3|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x080;
WriteToAD7192ViaSPI(REG_MODE, 1, AD7192Registers, REG_MODE);SPI_CS_LOW();
while(GPIO_ReadInputDataBit(GPIOB, TEMP_SPI_MISO_PIN)== 1){;}
SPI_CS_HIGH();
}
模式寄存器和配置寄存器配置写入
AD7192Registers[REG_MODE] = MODE_CONT|DAT_STA_EN|INCLK_MCLK2EN|SINC_3|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x14;
AD7192Registers[REG_CONF] = CHOP_DIS|REF_IN1|AIN2_COM|AIN3_COM|AIN4_COM|BURN_DIS|REFDET_DIS|BUF_DIS|UB_UNI|GAIN_1;
WriteToAD7192ViaSPI(REG_MODE, 2, AD7192Registers, REG_MODE); // 将配置的参数写入寄存器
unsigned char WriteToAD7192ViaSPI(const unsigned char RegisterStartAddress, const unsigned char NumberOfRegistersToWrite, uint32_t *DataBuffer, const unsigned char OffsetInBuffer)
{
unsigned char WriteBuf[4];
unsigned char i;
SPI_CS_LOW();
for(i=0; i<NumberOfRegistersToWrite; i++)
{
WriteBuf[0] = WEN|RW_W|((RegisterStartAddress + i)<<3)|CREAD_DIS;
WriteBuf[1] = DataBuffer[RegisterStartAddress + i]>>16;
WriteBuf[2] = DataBuffer[RegisterStartAddress + i]>>8;
WriteBuf[3] = DataBuffer[RegisterStartAddress + i];
SPI_TEMP_SendByte(WriteBuf[0]);
SPI_TEMP_SendByte(WriteBuf[1]);
SPI_TEMP_SendByte(WriteBuf[2]);
SPI_TEMP_SendByte(WriteBuf[3]);
}
SPI_CS_HIGH();
return 0;
}
读取数据
ad_data = AD7192ReadConvertingData();
channel = ad_data & 0xf; //取低4位通道值
ad_data = ad_data>>8; //移除低8位状态位
GatherVoltage=(float)ad_data/16777215; // 24位ADC
GatherVoltage = GatherVoltage*5000; // 5V参考电压,转换为电压值
/**
-
@brief 读取转换数据
-
@param
-
@retval DataBuffer:转换结果值
*/
uint32_t AD7192ReadConvertingData()
{
unsigned char WriteBuf[4];
unsigned char ReadBuf[4];
unsigned long int DataBuffer;SPI_CS_LOW(); //片选信号拉低
WriteBuf[0] = WEN|RW_R|((REG_DATA)<<3)|CREAD_DIS;
SPI_TEMP_SendByte(WriteBuf[0]); //在读数据之前先写通信寄存器,确认下一步操作是读操作
WriteBuf[0] = NOP;
WriteBuf[1] = NOP;
WriteBuf[2] = NOP;
WriteBuf[3] = NOP;while(GPIO_ReadInputDataBit(GPIOB, TEMP_SPI_MISO_PIN)== 1){;} // waiting the 1st RDY failling edge
if ((AD7192Registers[REG_MODE] & DAT_STA_EN) == DAT_STA_EN)
{
ReadBuf[0] = SPI_TEMP_ReadByte();
ReadBuf[1] = SPI_TEMP_ReadByte();
ReadBuf[2] = SPI_TEMP_ReadByte();
ReadBuf[3] = SPI_TEMP_ReadByte();
DataBuffer = ReadBuf[0];
DataBuffer = (DataBuffer<<8) + ReadBuf[1];
DataBuffer = (DataBuffer<<8) + ReadBuf[2];
DataBuffer = (DataBuffer<<8) + ReadBuf[3];
}
else
{
ReadBuf[0] = SPI_TEMP_ReadByte();
ReadBuf[1] = SPI_TEMP_ReadByte();
ReadBuf[2] = SPI_TEMP_ReadByte(); //do not transfer the status contents after read data register
DataBuffer = ReadBuf[0];
DataBuffer = (DataBuffer<<8) + ReadBuf[1];
DataBuffer = (DataBuffer<<8) + ReadBuf[2];
}
return DataBuffer;
}