STM32移植AD7190驱动详解

简介

AD7190是一款24位模数转换器,该款器件可配置为两路差分输入或四路伪差分输入,具体通道分配可参考模式寄存器。输入电压范围受内部增益影响,最高支持±5V(增益为1,参考电压为5V),输入最好要留有一定裕量。支持片内时钟、外部时钟或外部晶振,输出数据速率受内部可编程增益、采样率、滤波器影响,最高可达4.8kHz,主要应用于压力测量,数据采集等。

内部寄存器

AD7190主要通过操作其内部寄存器完成配置及数据读取工作。下面将讲解主要运用的寄存器及相关位的作用,帮助使用者更容易理解并完成配置工作。

通信寄存器

(RS2, RS1, RS0 = 0,0,0),8位,只写。与AD7190的所有通信均需以对通信寄存器的写操作开始。

/* Communications Register Bit Designations (AD7190_REG_COMM)(RS2, RS1, RS0 = 0,0,0) */
#define AD7190_COMM_WEN         (0 << 7)           // Write Enable.置0,对通信寄存器执行写操作;置1,器件一直停留该位置,不进行后续位的写入
#define AD7190_COMM_WRITE       (0 << 6)           // Write Operation.置0,下一操作对选定的寄存器(RS2, RS1, RS0)执行写操作;
#define AD7190_COMM_READ        (1 << 6)           // Read Operation.置1,执行读写操作
#define AD7190_COMM_ADDR(x)     (((x) & 0x7) << 3) // Register Address.选定寄存器(RS2, RS1, RS0)
#define AD7190_COMM_CREAD       (1 << 2)           // Continuous Read of Data Register.置1(并选择数据寄存器),连续读取数据寄存器,不需要再对通信寄存器执行写操作

/* AD7190 All Register Address (RS2, RS1, RS0)*/
#define AD7190_REG_COMM         0 // Communications Register (WO, 8-bit)
#define AD7190_REG_STAT         0 // Status Register         (RO, 8-bit)只读寄存器
#define AD7190_REG_MODE         1 // Mode Register           (RW, 24-bit
#define AD7190_REG_CONF         2 // Configuration Register  (RW, 24-bit)
#define AD7190_REG_DATA         3 // Data Register           (RO, 24/32-bit)
#define AD7190_REG_ID           4 // ID Register             (RO, 8-bit)
#define AD7190_REG_GPOCON       5 // GPOCON Register         (RW, 8-bit)
#define AD7190_REG_OFFSET       6 // Offset Register         (RW, 24-bit
#define AD7190_REG_FULLSCALE    7 // Full-Scale Register     (RW, 24-bit)

状态寄存器

(RS2, RS1, RS0 = 0,0,0),8位,只读。访问此寄存器必须先写通信寄存器,选择下一操作为读操作。主要读取ADC就绪位AD7190_STAT_RDY,确定是否可以读取数据。

/* Status Register Bit Designations (AD7190_REG_STAT)(RS2, RS1, RS0 = 0,0,0) */
#define AD7190_STAT_RDY         (1 << 7) // Ready.置0,数据写入数据寄存器转换结束,可以读取;读取数据寄存器后或有新转换数据将写入数据寄存器之前置1
#define AD7190_STAT_ERR         (1 << 6) // ADC error bit.启动转换默认置0;数据寄存器钳位为全0或者全1,数据错误,置1
#define AD7190_STAT_NOREF       (1 << 5) // No external reference.置1,选定的基准电压低于阈值,并且转换结果钳位为全1;置0,表示基准有效。使能该位需要将配置寄存器中REFDET位置1
#define AD7190_STAT_PARITY      (1 << 4) // Parity check of the data register.奇偶校验
#define AD7190_STAT_CH2         (1 << 2) // Channel 2.
#define AD7190_STAT_CH1         (1 << 1) // Channel 1.
#define AD7190_STAT_CH0         (1 << 0) // Channel 0.

模式寄存器

(RS2, RS1, RS0 = 0,0,1),24位,可以读写操作。用于选择工作模式、时钟源、滤波器和输出数据速率。运行时如果需要自动切换工作模式,请现将前次模式清零再选择新模式。执行写操作会复位调制器和滤波器。
禁用斩波并选择连续转换模式时,输出数据速率 = (f / 64) / FS;
使能斩波时,输出数据速率 = (f / 64) / (N * FS);
f = 芯片时钟/16;N = sinc滤波器阶数,即后缀;FS = 1~1023;

/* Mode Register Bit Designations (AD7190_REG_MODE)(RS2, RS1, RS0 = 0,0,1) */
#define AD7190_MODE_SEL(x)      (((x) & 0x7) << 21) // Operation Mode Select.工作模式选择 0~7
#define AD7190_MODE_DAT_STA     (1 << 20)           // Status Register transmission.置1,状态寄存器的内容将与每次从数据寄存器读取的数据一同传输,即24位数据后加8位状态寄存器数据,方便开启多通道时,区分读取的数据归属通道
#define AD7190_MODE_CLKSRC(x)   (((x) & 0x3) << 18)  // Clock Source Select.选择时钟源 0~3
#define AD7190_MODE_SINC3       (1 << 15)           // SINC3 Filter Select.置1,选择sinc3;置0,选择sinc4
#define AD7190_MODE_ENPAR       (1 << 13)           // Parity Enable.置1,使能状态寄存器中奇偶校验
#define AD7190_MODE_SCYCLE      (1 << 11)           // Single cycle conversion.置1,在一个转换周期内建立
#define AD7190_MODE_REJ60       (1 << 10)           // 50/60Hz notch filter.
#define AD7190_MODE_RATE(x)     ((x) & 0x3FF)       // Filter Update Rate Select.滤波器输出数据速率选择位 1~1023

配置寄存器

(RS2, RS1, RS0 = 0,1,0),24位,可读写。用来配置ADC极性、缓冲器、激励电流、增益和模拟输入通道。

/* Configuration Register Bit Designations (AD7190_REG_CONF)(RS2, RS1, RS0 = 0,1,0) */
#define AD7190_CONF_CHOP        (1 << 23)            // CHOP enable.置1,斩波使能;置0,斩波禁用
#define AD7190_CONF_REFSEL      (1 << 20)            // REFIN1/REFIN2 Reference Select.外部基准电压选择位
#define AD7190_CONF_CHAN(x)     (((x) & 0xFF) << 8)  // Channel select.通道选择 
#define AD7190_CONF_BURN        (1 << 7)             // Burnout current enable.
#define AD7190_CONF_REFDET      (1 << 6)             // Reference detect enable.置1,使能状态寄存器中基准电压检测
#define AD7190_CONF_BUF         (1 << 4)             // Buffered Mode Enable.
#define AD7190_CONF_UNIPOLAR    (1 << 3)             // Unipolar/Bipolar Enable.置1,单极性模式;置0,双极性模式
#define AD7190_CONF_GAIN(x)     ((x) & 0x7)          // Gain Select.增益选择 0、3~7

数据寄存器

(RS2, RS1, RS0 = 0,1,1),24位,只读。存放ADC转换结果,读取该寄存器后,状态寄存器中AD7190_STAT_RDY自动置1。

ID寄存器

(RS2, RS1, RS0 = 1,0,0),8位,只读。存储AD7190识别码,后四位一定为0b’0100。上电时读取该寄存器可以检测AD7190是否连接正常。

GPOCON寄存器

(RS2, RS1, RS0 = 1,0,1),8位,可读写。使能通用数字输出。

失调寄存器

(RS2, RS1, RS0 = 1,1,0),24位,可读写。保存ADC失调校准系数,各通道均有专用失调寄存器。启动内部或系统零电平校准时,默认值(0x800000)会被自动覆盖。写入失调寄存器时,AD7190须处于省电模式或空闲模式。

满量程寄存器

(RS2, RS1, RS0 = 1,1,1),24位,可读写。保存ADC满量程校准系数,各通道均有专用满量程寄存器。写入满量程寄存器时,AD7190须处于省电模式或空闲模式。

复位

上电会自动执行复位。也可手动复位,在手册中有多次提及,即连续写入至少40个逻辑1,可以使AD7190的电路、内部配置和串行接口等复位为默认值。手动启动复位后,需要等待至少500us才能访问寄存器。

数据输出编码:

单极性模式 = (224 x AIN x gain)/Vref;
双极性不同于单极性,双极性可以输入正负电压,负满量程时为0x000000,差分输入为0时0x800000,正满量程时为0xFFFFFF。
所以输出码 = 223 x [(AIN x gain/Vref) + 1];
AIN为模拟输入电压;gain为内部增益设置

使用流程:

  • 上电初始化SPI,复位AD7190,读取ID寄存器,获取芯片ID,确保芯片已连接,为接下来写寄存器做准备。
unsigned char AD7190_Init(void)
{
  uint32_t regVal = 0;

  AD7190_Reset();
  /* Allow at least 500 us before accessing any of the on-chip registers. */
  HAL_Delay(1);
  regVal = AD7190_GetRegisterValue(AD7190_REG_ID, 1);
  printf("ad7190 ID:%#x\n",regVal);
  if( (regVal & AD7190_ID_MASK) == ID_AD7190)
  {
	  return 1;
  }
  else
  return 0;
}
  • 写入通信寄存器0x08,选中模式寄存器,写入数据0x108001。连续转换模式,使能读取数据寄存器后可继续读取一字节状态寄存器而不需要重新写入通信寄存器读取,选择外部晶振,选择sinc3滤波器,关闭奇偶校验位,关闭单周期转换,关闭60Hz陷波,速率选择10。
  /* Set Mode Register */
  //0001 0000 1000 0000 0000 1010
  command1 = AD7190_MODE_SEL(AD7190_MODE_CONT) | AD7190_MODE_DAT_STA|
             AD7190_MODE_CLKSRC(AD7190_CLK_EXT_MCLK1_2) |
			 AD7190_MODE_SINC3 | AD7190_MODE_RATE(10);
  printf("Mod Register = %#x\n",command1);
  AD7190_SetRegisterValue(AD7190_REG_MODE, command1, 3);
  • 写入通信寄存器0x10,选中配置寄存器,写入0x800100。斩波使能,基准电压源选择REFIN1(+)和REFIN1(-),通道选择正输入AIN1、负输入AIN2,禁用激励电流,关闭基准电压检测,关闭模拟输入端缓冲器,选择双极性工作即差分,增益选择128。
  /* Set Configuration Register*/
  //1000 0000 0000 0001 0000 0111
  command2 = AD7190_CONF_CHOP | AD7190_CONF_REFSEL0 | AD7190_CONF_BIPOLAR |
		  	 AD7190_CONF_CHAN(AD7190_CH_AIN1P_AIN2M) |
			/* AD7190_CONF_CHAN(AD7190_CH_AIN3P_AIN4M) | */ //可以只选择一路差分
			 AD7190_CONF_GAIN(AD7190_CONF_GAIN_128);
  printf("Con Register = %#x\n",command2);
  AD7190_SetRegisterValue(AD7190_REG_CONF, command2, 3);
  • 写入通信寄存器0x5c,选中数据寄存器,即可连续读取24数据+8位状态,每次读取需等待状态寄存器首位为0,如果使能多个输入通道会循环输出已开启通道的转换数据。
void AD7190_Continuous_ReadData(unsigned char cread)
{
  unsigned char registerWord=0;

  if(cread == 1)
  {
    registerWord = 0x5C;
  }
  else
  {
    AD7190_WaitRdyGoLow();
    registerWord = 0x58;//why 0x5e?
  }
  HAL_SPI_Transmit(&hspi1,&registerWord,1,0xFFFF);
}
  • 根据8位状态位确定数据所指向的输入通道,根据实际需求将各通道数据通过各自转换函数(按需求自定义),转换为最终所需要的结果。

调试问题点:

Q:AD7190连续读取数据没有变化?
A:1、函数括号漏掉;2、AD7190进入了省电模式,在单次转换模式下,只可启动一次,在完成转换后自动处于省电模式,所以只有第一次是真实数据,后续为未知固定值,每次使用单次转换时需清除省电模式,再重新写入单次转换。

weight_count = AD7190_Get_ADC_Data();//AD7190_Get_ADC_Data()为读取函数,后面括号不可缺少
printf("weight:%#x\n",weight_count);

command = (command & 0x1fffff) | AD7190_MODE_SEL(AD7190_MODE_SINGLE);//清除前次工作模式

Q:串口输出浮点型数据,结果为“inf”或“0.00”?
A:显示“inf”表示数据超出浮点数的表示范围。INF表示“无穷大”,NAN表示“无效数字”;结果一直为“0.00”,可能数据格式为整型,在数据处理时,乘以浮点数“1.0”或将其中的常数用小数表示即可。

Q:数值取平均值计算误差较大,明显计算错误?
A:计算时将输出数据后面的通道编号去除,并将数据右移至24位格式再计算,防止32位计算时高位数据溢出。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值