ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

菜鸟张明要飞系列

2021-10-16 16:31:23  阅读:212  来源: 互联网

标签:系列 菜鸟 张明 Send 指令 IIC 寄存器 Byte define


今天介绍一下ads119的使用方法。

使用到的实验条件:Ads1119、0.9寸OLED、tms28335、数字电源、6位半万用表

在使用stm32或dsp内置集成ad模块时会遇到一点点问题,如不能测试差分电压、在程序较复杂时测量不准确、位数太低等等问题。为追求更好的电压检测效果,通常会使用外置高精度ad芯片。

文章目录


ADS1119的介绍

  1. 简单使用,只有2个8位寄存器;
  2. 可编程增益:Gain=1 或Gain=4,测试小信号可以更准确;
  3. 轨至轨输入缓冲区,输入阻抗很大,这说明在利用电阻分压测试大电压时,阻抗匹配的问题不需要考虑;
  4. 24位ad,23个数据位,1个符号位,可以测试负压;
  5. 单次转换和连续转换选择以及采样速率可编程;
  6. IIC接口,支持三种IIC模式,即标准、快速、超快模式;
  7. 16引脚,2.3-5.5V输入电压范围,VREF=2.048V,5ppm/度(Part Per Million),超低温漂;
  8. Δ − − ∑ \Delta--\sum Δ−−∑型ad转换器
  9. …(见ads119手册);

这里值得说一下的是,支持的三种IIC模式。我们在使用IIC大多都是采用的模拟IIC,这时的频率是由我们设置SCL,SDA高低电平以及延时来决定的,而芯片手册中所说的是指硬件IIC,硬件IIC这里不讨论。

一、硬件电路?

硬件电路较为简单,参[在这里插入图片描述,参考芯片手册即可,这里不讨论,直接上图
ads1119电路图

  1. IIC上拉电阻的选取,电阻选大了,会造成延时,选小了,损耗较大。这里可以参考恩智浦(NXP)的IIC上拉电阻选取的相关文档,这里选取的是10k;
  2. 这里用段子做了温度测量、差分选择,是为了后续使用跳线帽来实现;
  3. 在进行大电压测量时,由于ads1119的输入阻抗很大,经过电阻分压不需要接跟随器,但为了安全起见,需要接两个钳位二极管(强烈推荐),但这里集成了两个钳位二极管;
    ads1119集成2个钳位二极管
    [外链图片转存中…/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指令

`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.程序设计步骤

  1. 上电后使用IIC RESET指令将ads1119复位,确保ads1119上电后寄存器是默认设置
  2. 写寄存器命令WREG配置寄存器,需要配置的参数有输入接口MUX[2:0]、增益、基准电压、采样率、工作模式,为确保相应的参数已正确写入
  3. 使用读寄存器将写入寄存器的数据读出来,看是否写入。这一步可以省略
  4. 然后START/SYNC命令启动转换,循环检测DRDY信号是否低电平,为低则RDATA命令读取转换结果。
  5. 发送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)

标签:系列,菜鸟,张明,Send,指令,IIC,寄存器,Byte,define
来源: https://blog.csdn.net/for_good_love/article/details/120799784

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有