1.AD7799介绍
AD7799结构图如下所示:
其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示:
注意:
如果REG_CONFIG的REF_DET开启的话,那么输入AD值电压低于0.5V时,则差分输入ad值就无法检测了,如下图所示:
2.AD7799差分信号的输入模式
如下图所示,差分输入电压有3种模式:
注意:
单端输入电压(AIN-接地,只有正电压)则支持任意范围,比如In-Amp模式下,单端输入如果为10mv的话,也能检测到.
2.1 Unbuffered Mode非缓冲模式
该模式可测的AD值可以在 -30mV ~ (AVDD+30mv)范围之间,如果开了双极型模式(双极型模式通过将REG_CONFIG的U/B位设0实现),则也可以测-(AVDD+30mv)~30mV之间AD值.
也就是说假如我们要测的AD值位于-100mV~100mV之间,则用这个模式.
该模式优缺点:可测范围最大,但是精度误差不是很高
2.2 Buffered Mode缓冲模式
缓冲的作用就是减少测的AD误差,并且功耗相应地会增高点,该模式主要是测100mV~( AVDD-100mV)之间.
该模式优缺点:可测范围比Unbuffered小一点,并且精度误差高一点
2.3 In-Amp 高增益模式
需要将REG_CONFIG的Gain调到4及以上才是该模式,否则的话,就会根据REG_CONFIG的BUF位来自动判断是Buffered Mode还是Unbuffered Mode.
并且AD值必须位于300mv~(AVDD+1100mv)之间,否则的话该模式是无法检测AD值的,之前笔者就是测差分输入的正负20mV,却一直没有反应,后来才发现是处于这个模式的原因.
该模式优缺点:可测范围可以通过设置Gain来设置测试范围,比如VREF为3V,Gain=4,则可测量程为正负600mv.
注意:
当使用Buffered Mode或者In-Amp模式时,需要将REG_CONFIG的BO位开启,介绍如下图所示:
3.代码效果
串口截图如下:
通过电压发生器不停修改AD值时,可以看到万用表和串口打印的数据相差不大:
PS:由于GIF录制的像素位数太低,所以不清晰
4.代码实现
支持硬件SPI1或者GPIO模拟方式
代码通过宏AD7799_INTERFACE_MODE判断,能够支持硬件SPI1或者GPIO模拟方式,如下图所示:
通过宏定义VREF参考电压,以及GAIN增益值
如下图所示,只需修改下面宏,就可以实现转换电压数据自动转换:
实现通道1和通道2来回切换
串口发送select 1,表示选择通道1:
发送select 2,则表示选择通道2.
4.1初始化过程
/*ad7799初始化*/
AD7799_gpio_init();
while(!AD7799_Init())
{
LED0 = !LED0;
delay_ms(50);
}
LED0 = 1;
AD7799_Calibrate(); //通道校准
AD7799_SetGain(AD7799_CHIP_GAIN);
AD7799_SetBurnoutCurren(0); //关闭BO
AD7799_SetBufMode(0); //由于我们要测的电压低于100mV,所以设置为Unbuffered Mode
AD7799_SetChannel(ChannelBuf[0]); //通道设置.
AD7799_SetMode(AD7799_MODE_CONT,5); //默认双极性 频率为5
AD7799_SetReference(0); //关闭参考检测,因为我们的 AD7799_RefmV 参考电压低于0.5V
4.2 上面的函数如下所示:
void AD7799_gpio_init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = AD_CS_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(AD_CS_GPIO, &GPIO_InitStructure); //CS片选
#if ( AD7799_INTERFACE_MODE == AD7799_INTERFACE_SPI1 )
//spi1 mode SPI1_Init(); SPI1_SetSpeed(SPI_BaudRatePrescaler_2); #else
//gpio模拟spi mode GPIO_InitStructure.GPIO_Pin = AD_DI_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(AD_DI_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = AD_SCK_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(AD_SCK_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = AD_DO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(AD_DO_GPIO, &GPIO_InitStructure); spi_AD7799_init(); #endif AD7799_Reset(); } void AD7799_SetGain(unsigned long gain) { unsigned long command; command = AD7799_GetRegisterValue(AD7799_REG_CONF,2); command &= ~AD7799_CONF_GAIN(0xFF); command |= AD7799_CONF_GAIN(gain); AD7799_SetRegisterValue( AD7799_REG_CONF, command, 2 ); } void AD7799_SetBurnoutCurren(u8 enable)//设置BO { unsigned long command; command = AD7799_GetRegisterValue(AD7799_REG_CONF,2); command &= ~0X2000; if(enable) command |= 0X2000; AD7799_SetRegisterValue( AD7799_REG_CONF, command, 2 ); } void AD7799_SetBufMode(u8 enable) //设置buf { unsigned long command; command = AD7799_GetRegisterValue(AD7799_REG_CONF,2); command &= ~0X10; if(enable) command |= 0X10; AD7799_SetRegisterValue( AD7799_REG_CONF, command, 2 ); } void AD7799_SetChannel(unsigned long channel) { unsigned long command; command = AD7799_GetRegisterValue(AD7799_REG_CONF,2); command &= ~AD7799_CONF_CHAN(0xFF); command |= AD7799_CONF_CHAN(channel); AD7799_SetRegisterValue( AD7799_REG_CONF, command, 2 ); } void AD7799_SetMode(unsigned long mode,u8 rate) { unsigned long command; command = AD7799_GetRegisterValue(AD7799_REG_MODE,2); command &= ~AD7799_MODE_SEL(0xFF); command |= AD7799_MODE_SEL(mode); command &= 0XFFF0; command |= rate; //设置频率
AD7799_SetRegisterValue( AD7799_REG_MODE, command, 2 ); } void AD7799_SetReference(unsigned char state) { unsigned long command = 0; command = AD7799_GetRegisterValue(AD7799_REG_CONF,2); command &= ~AD7799_CONF_REFDET(1); command |= AD7799_CONF_REFDET(state); AD7799_SetRegisterValue(AD7799_REG_CONF, command, 2); } void AD7799_SetRegisterValue(unsigned char regAddress, unsigned long regValue, unsigned char size) { unsigned char data[5] = {0x03, 0x00, 0x00, 0x00, 0x00}; data[0] = AD7799_COMM_WRITE | AD7799_COMM_ADDR(regAddress); if(size == 1) { data[1] = (unsigned char)regValue; } if(size == 2) { data[2] = (unsigned char)((regValue & 0x0000FF) >> 0); data[1] = (unsigned char)((regValue & 0x00FF00) >> 8); } if(size == 3) { data[3] = (unsigned char)((regValue & 0x0000FF) >> 0); data[2] = (unsigned char)((regValue & 0x00FF00) >> 8); data[1] = (unsigned char)((regValue & 0xFF0000) >> 16); } AD7799_CS_LOW; SPI_Write(data,(1 + size)); AD7799_CS_HIGH; } unsigned long AD7799_GetRegisterValue(unsigned char regAddress, unsigned char size) { unsigned char data[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; unsigned long receivedData = 0x00; data[0] = AD7799_COMM_READ | AD7799_COMM_ADDR(regAddress); AD7799_CS_LOW; SPI_Write(data,1); SPI_Read(data,size); AD7799_CS_HIGH; if(size == 1) { receivedData += (data[0] << 0); } if(size == 2) { receivedData += (data[0] << 8); receivedData += (data[1] << 0); } if(size == 3) { receivedData += (data[0] << 16); receivedData += (data[1] << 8); receivedData += (data[2] << 0); } return receivedData; }
4.3 获取通道电压代码如下所示:
while(1) { if(Serial_Post_ChannelValue!=0XFF) //0:不选择 1~2:更改通道 { CurrentChannelValue = Serial_Post_ChannelValue; Serial_Post_ChannelValue =0XFF; if(CurrentChannelValue && CurrentChannelValue<=2) //1~2 { AD7799_SetChannel(ChannelBuf[CurrentChannelValue-1]);//通道设置. 0~1 delay_ms(10); AD7799_GetRegisterValue(AD7799_REG_DATA,3);//清空之前的AD } else if(CurrentChannelValue == 0) { printf("%s value0 0 0 \r\n",Board_Name); } } if(CurrentChannelValue) //选择了通道? { for(i=0;i<2;i++) //获取每个通道数据
if(CurrentChannelValue == (i+1)) { while( !AD7799_Ready()) //1~2 { delay_ms(5); } ADValues[i]= analyzeAD7799_Data(AD7799_GetRegisterValue(AD7799_REG_DATA,3)); } else ADValues[i] = 0.0000; printf("%s 当前通道为:%d %.3fmV %.3fmV \r\n",Board_Name,CurrentChannelValue,ADValues[0],ADValues[1]); } LED0 =!LED0; delay_ms(100); }
具体下载地址:https://download.csdn.net/download/qq_37997682/11240699