项目需要选择了AD4111,奈何水平有限,资源又少,几番折腾终于成功了。
一、简单介绍一下AD4111,功能很强大,但是对我来说比较重要的有以下几点。
1.片内2.5 V基准电压源,25°C时精度为±0.12%,温漂为±5 ppm/°C(典型值)
2.温度范围:−40°C至+105°C
3.支持4-20ma电流直接输入
4.内置16MHZ时钟
5.集成模拟前端的24位ADC
二、原理图
三、驱动
AD4111有一个3线或4线SPI接口,该接口与QSPI™、MICROWIRE®和DSP兼容。该接口以SPI模式3工作,在CS接低电平时也能工作。在SPI模式3下,SCLK空闲时为高电平,SCLK的下降沿为驱动沿,上升沿为采样沿。数据在下降/驱动沿输出,在上升/采样沿输入。
1.AD4111复位
在CS = 0且DIN = 1时,写入64个SCLK可以复位串行接口。复位使接口返回到ADC等待主机对通信寄存器执行写操作的状态。该操作会将所有寄存器的内容复位到其上电值。复位后,用户应等待500μs再访问串行接口。
/*
//AD4111复位
//连续64个以上时钟高IN将复位AD4111
*/
AD4111_CS=0; //SPI选中
for(u8 i = 0;i<100;i++)
{
delay_ms(5);
SPI2_ReadWriteByte(0xff);//发送读取ID命令
}
2.读ID
AD4111_Read(ID, (u8*)&value1, 2);
printf("id=0x%x\r\n",value1);
3.设置通道寄存器
/*
//通道寄存器 0
*/
value = 0x81e8;//通道0使能,设置0,Iin0+、Iin0-
// u16 value = 0x8232;//通道0使能,设置0,温度传感器
AD4111_RegWrite(CH0,(u8*)&value,2);
AD4111_Read(CH0, (u8*)&value1, 2);
printf("ch0_reg=0x%x\r\n",value1);
4.设置设置配置寄存器
/*
//设置配置寄存器0
*/
value = 0x20;//单极性编码输出,禁用refbuf0+,禁用REFbuf0-,禁用输入缓冲器,使用内部2.5v基准
// value = 0x320;//单极性编码输出,禁用refbuf0+,禁用REFbuf0-,使能输入缓冲器,使用内部2.5v基准
AD4111_RegWrite(SETUPCON0,(u8*)&value,2);
AD4111_Read(SETUPCON0, (u8*)&value1, 2);
printf("SETUPCON0=0x%x\r\n",value1);
5.设置接口模式寄存器
/*
//接口模式寄存器
*/
value = 0x40;//不使用同步引脚,不改变DOUT引脚强度,禁用dout-reset,禁用连续读取,状态寄存器
//禁用寄存器检查,禁用crc校验,数据长度设定位24
AD4111_RegWrite(IFMODE ,(u8*)&value,2);
AD4111_Read(IFMODE, (u8*)&value1, 2);
printf("IFMODE=0x%x\r\n",value1);
6.设置ADC模式寄存器
/*
//配置ADC模式寄存器
*/
value = 0x8000;//内部基准电压,禁用滤波器速度输出,延时0us,连续转换,内部振荡器
// value = 0x8010;//内部基准电压,禁用滤波器速度输出,延时0us,单次转换,内部振荡器
AD4111_RegWrite(ADCMODE,(u8*)&value,2);
AD4111_Read(ADCMODE, (u8*)&value1, 2);
printf("ADCMODE=0x%x\r\n",value1);
7.监控RDY的电平状态,低电平是读取数据
//读取模拟量值
s16 AD4111_ReadData()
{
u32 AD_REG_value= 0;
u8 temp1 = 0;
u8 temp2 = 0;
u8 temp3 = 0;
u8 temp4 = 0;
SPI2_ReadWriteByte(0x44); //发送读命令
delay_us(20);
temp1 = SPI2_ReadWriteByte(0xff); //接收第一个字节,数据字节高8位
printf("TEMP1 =%x ",temp1);
delay_us(20);
temp2 = SPI2_ReadWriteByte(0xff); //接收第二个字节,数据字节中8位
printf("TEMP2 = %x ",temp2);
delay_us(20);
temp3 = SPI2_ReadWriteByte(0xff); //接收第三个字节,数据字节低8位
printf("TEMP3 = %x ",temp3);
temp4= SPI2_ReadWriteByte(0xff); //接收第四个字节,状态字节
printf("TEMP4 = %x ",temp4);
AD_REG_value =(temp1<<16)+(temp2<<8)+temp3;//数据寄存器的值
printf("模拟量原始数据int=%d\r\n",AD_REG_value);
//计算输出电流值
float eddy_current = 0;
eddy_current = ((AD_REG_value*2.5f*1000)/16777216.0f)/50.0f;//单位ma
printf("模拟量电流值float=%f ma\r\n",eddy_current);//
printf("模拟量电流值S16=%d\r\n",(s16)(eddy_current*1000));//放大1000
return (s16)(eddy_current*1000);//放大1000后用于485通讯
}