今天介绍一下ads119的使用方法。
使用到的实验条件:Ads1119、0.9寸OLED、tms28335、数字电源、6位半万用表
在使用stm32或dsp内置集成ad模块时会遇到一点点问题,如不能测试差分电压、在程序较复杂时测量不准确、位数太低等等问题。为追求更好的电压检测效果,通常会使用外置高精度ad芯片。
ADS1119的介绍
- 简单使用,只有2个8位寄存器;
- 可编程增益:Gain=1 或Gain=4,测试小信号可以更准确;
- 轨至轨输入缓冲区,输入阻抗很大,这说明在利用电阻分压测试大电压时,阻抗匹配的问题不需要考虑;
- 24位ad,23个数据位,1个符号位,可以测试负压;
- 单次转换和连续转换选择以及采样速率可编程;
- IIC接口,支持三种IIC模式,即标准、快速、超快模式;
- 16引脚,2.3-5.5V输入电压范围,VREF=2.048V,5ppm/度(Part Per Million),超低温漂;
-
Δ
?
?
∑
\Delta--\sum
Δ??∑型ad转换器
- …(见ads119手册);
这里值得说一下的是,支持的三种IIC模式。我们在使用IIC大多都是采用的模拟IIC,这时的频率是由我们设置SCL,SDA高低电平以及延时来决定的,而芯片手册中所说的是指硬件IIC,硬件IIC这里不讨论。
一、硬件电路?
硬件电路较为简单,参[在这里插入图片描述,参考芯片手册即可,这里不讨论,直接上图
- IIC上拉电阻的选取,电阻选大了,会造成延时,选小了,损耗较大。这里可以参考恩智浦(NXP)的IIC上拉电阻选取的相关文档,这里选取的是10k;
- 这里用段子做了温度测量、差分选择,是为了后续使用跳线帽来实现;
- 在进行大电压测量时,由于ads1119的输入阻抗很大,经过电阻分压不需要接跟随器,但为了安全起见,需要接两个钳位二极管(强烈推荐),但这里集成了两个钳位二极管;
[外链图片转存中…/imgqbg.csdnimg.cn/a3f3cc3a45d54b08b5ed40042bd2f306.png)
二、使时序分析
1.芯片地址选择
显然根据数据手册上的真值表,地址=0x80(write),0x81(read)
2.数据传输协议
IIC协议较容易,这里不介绍IIC,ads1119的数据传输协议如下图 相关代码如下:
void Write_Command(unsigned char Data) { IIC_Start(); IIC_Send_Byte(0x80);//发送地址/0=W/1=R IIC_Wait_Ack(); IIC_Send_Byte(Data); IIC_Wait_Ack(); IIC_Stop(); }
3.ads1119指令
**RESET指令:**这个命令将设备重置为默认状态,执行此命令后,不需要延时。在设备开始进行ad测量时,这个reset指令时必须的。 void Power_Reset(void) { Write_Command(0x06); } **START指令:**在单次转换模式下,START命令用于启动单次转换或重置数字滤波器,然后启动一次新的转换。当设备工作在连续转换模式下时,必须发出这个指令才能启动转换;发送这个指令可以直接重置数字滤波器并启动连续转换。 void ReStart(void) { Write_Command(0x08); }
**POWERDOWN指令:**这个指令是关闭设备(但能保存所有寄存器的值),进入省电模式。 void PowerDown(void) { Write_Command(0x02); }
**RDATA指令:**这个指令将最近的转换结果加载到输出移位寄存器。
unsigned long ReadConDataSeq(void) { unsigned char i = 0; unsigned long ReadData = 0; unsigned long Data[3]={0,0,0}; IIC_Start(); IIC_Send_Byte(0x80);//write IIC_Wait_Ack(); //ReadReg(0);//read 0 register IIC_Send_Byte(0x10); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0x81);//read IIC_Wait_Ack(); //read conversion data sequence for(;i < 3 ;i++) { Data[i] |= IIC_Read_Byte(1);//read with ack } ReadData = (Data[2] << 0) | (Data[1] << 8) | (Data[0] << 16); IIC_Stop(); return ReadData; } **RREG指令:**这个指令可以读取寄存器的值,通常是断点调试是查看是否将数据写入 unsigned char ReadRegSeq(void) { unsigned char RegVal = 0; IIC_Start(); IIC_Send_Byte(0x80); IIC_Wait_Ack(); IIC_Send_Byte(0x20); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0x81);//read IIC_Wait_Ack(); RegVal = IIC_Read_Byte(0); IIC_Stop(); return RegVal; }//read register sequence
**WREG指令:**这个指令将数据写入寄存器 void WriteRegSeq(unsigned char SetData) { IIC_Start(); IIC_Send_Byte(0x80); IIC_Wait_Ack(); //WriteReg(); IIC_Send_Byte(0x40); IIC_Wait_Ack(); IIC_Send_Byte(SetData);//register configure IIC_Wait_Ack(); IIC_Stop(); }
OK,基本指令已经全部写完了。下面看看寄存器的配置
4.寄存器
为方便使用,一般我们采用宏体或这结构体定义,这里的寄存器较少,我们使用宏体即可 //DRDY low leverl is active #define DRDY_SETH GpioDataRegs.GPBSET.bit.GPIO34 = 1 #define DRDY_SETL GpioDataRegs.GPBCLEAR.Bit.GPIO34 = 1 #define DRDY GpioDataRegs.GPBDAT.bit.GPIO34
// set channel #define AIN0TOAIN1 0x00 //AINP to AINN //default #define AIN2TOAIN3 0x20 #define AIN1TOAIN2 0x40 #define AIN0TOAGND 0x62 #define AIN1TOAGND 0x80 #define AIN2TOAGND 0xA0 #define AIN3TOAGND 0xC0 #define SHORTHALFAVDD 0xE0 //set gain #define GAIN4 0x10 #define GAIN1 0x00 //default //set sample rate #define SPS20 0x00//default #define SPS90 0x04 #define SPS330 0x08 #define SPS1000 0x0C //set convert mode #define SINGLE 0x00//default #define CONTINUE 0x02 //set VREF #define INTVREF 0x00 #define EXTVREF 0x01
5.程序设计步骤
- 上电后使用IIC RESET指令将ads1119复位,确保ads1119上电后寄存器是默认设置
- 写寄存器命令WREG配置寄存器,需要配置的参数有输入接口MUX[2:0]、增益、基准电压、采样率、工作模式,为确保相应的参数已正确写入
- 使用读寄存器将写入寄存器的数据读出来,看是否写入。这一步可以省略
- 然后START/SYNC命令启动转换,循环检测DRDY信号是否低电平,为低则RDATA命令读取转换结果。
- 发送PWOERDOWN指令,结束
程序伪码和代码如下 unsigned long ADSStep(unsigned char SetData) { unsigned char RegData = 0; unsigned long ReadData = 0; DRDY_SETH; IIC_Start(); IIC_Send_Byte(0x80); Power_Reset(); WriteRegSeq(SetData);//configure register RegData = ReadRegSeq();//read the configured reg to test whether the figure is right ReStart(); while(DRDY);//waiting for DRDY is low //DELAY_US(100); ReadData = ReadConDataSeq();//ReadData is used for test PowerDown(); return ReadData; } 至此,我们所有的ads1119相关代码全部配置完毕。 接下来,我们调用这个函数 #define VREF 2.048 #define MAXCODE 0x7fffff DATA = ADSStep(AIN1TOAGND | GAIN1 | SPS20 | CONTINUE | INTVREF); ADVal = ADData * VREF / MAXCODE ;
//这里注意,为避免手动数据类型转换,一定要先*VREF,否则会导致读取的时候一直是0,这是因为ADData/MAXCODE的整数型运算==0,这里我被坑了一点点时间。
这里没有考虑ad采样的软件滤波算法,这不是今天的重点。 下面一起来看看ad的转化结果吧。和6位半的万用表相比,相差约0.2~0.3mV。由于使用的只是简单的低通滤波、无软件滤波、杜邦线较长等问题,测试到这个精度也是可以了。 通过本次的学习,对ad芯片的时序操作有了一定的了解。 链接: [https://download.csdn.net/download/for_good_love/25971233]
(=!=)第一次用这个编译器(0_0)
|