前言

  • 上一篇 文章 主要介绍了对该ADC芯片的三种读写操作模式的时序解读。
    接下来介绍一下对寄存器的操作。

寄存器介绍

  • 寄存器总览:
    在这里插入图片描述

  • 输入配置:
    在这里插入图片描述

从上图可以看到,是一个14bit长度的寄存器。


相关配置部分代码

#define MS5182N_RB		(1) //0: 数据结束是回读当前配置 | 1: 不回读配置内容。       
#define MS5182N_SEQ	    (0) //0:禁用|1:序列扫描期间更新配置|2:扫描 IN0 至 INx(由 CFG[9:7]设置),然后扫描温度。|3:扫描 IN0 至 IN[7:0      
#define MS5182N_REF		(7) //0:内部基准(2.5V) | 1:预留 | 2:外部基准并使能温感|3:外部基准带缓冲器并使能温感|6:外部基准并禁用温感 |7:外部基准带缓冲器并禁用温感
#define MS5182N_BW		(1) //0:1/4带宽 | 1:全带宽
#define MS5182N_CFG     (1) //0:保持当前配置  |  1:覆盖更新配置

/*
**00x:双极性差分对,INx(-)以Vref/2±0.1为参考
**010:双极性,INx(-)以COM=Vref/2±0.1为参考
**011:温度传感器,
**10x:单极性差分对,INx(-)以GND±0.1为参考
**110:单极性,INx以COM=GND±0.1为参考
**111:单极性,INx以GND为参考
*/
			 
/*寄存器配置*/
#define MS5182N_REG_DAT_CFG(mode,ch)  (((MS5182N_CFG<<13)|(mode<<10)|(ch<<7)|(MS5182N_BW<<6)|(MS5182N_REF<<3)|(MS5182N_SEQ<<1)|MS5182N_RB))//根据芯片手册左移2位末位补0  
/*
**双极性模式下:
**REG[9-7]:配置值为偶数时:IN0,IN2为正通道
**REG[9-7]:配置值为奇数时:IN1,IN3为正通道
即:
**读CH=0/CH=2,就是把当前通道设置为正通道
**读CH=1/CH=3,就是把当前通道设置为正通道
**相应的那另外一个通道就设置为负通道了。
**负通道都是以Vref/2±0.1为参考:看[上图2-输入配置]
简言之:差分模式下,读的是设置当前为正通道后的差分数据。
*/
#define MS5182N_REG_DAT_CONV_CFG(mode,ch)    (((unsigned short int)MS5182N_REG_DAT_CFG(mode,ch))<<2)

/*电压转换*/	
#define MS5182N_VREF_SPAN           (4.096)//测量参考电压跨度:4.096V
#define MS5812N_VOLTAGE_CONVERT(x)  ((MS5182N_VREF_SPAN*(double)x)/65536.0)//转换公式 16bit :转换系数为2^16+1=0xffff+1=65536

typedef enum
{
	UNIPOLAR_GND_MODE=7U,/*单极性:INx以GND±0.1V引脚电压为参考*/
	UNIPOLAR_COM_MODE=6U,/*单极性:INx以COM=GND±0.1V引脚电压为参考*/
	UNIPOLAR_DIFF_MODE=5U,/*(4/5)单极性差分:INx(-)以GND±0.1V引脚电压为参考*/
    TEMP_MODE=3U,
	BIPOLAR_COM_MODE=2U,    /*双极性:INx(-)以GND±0.1V电压为参考*/		
	BIPOLAR_DIFF_MODE=1U,	/*(0/1)双极性差分:INx(-)=VREF/2±0.1V电压为参考*/			
}pmode_em;

typedef enum
{
  RAC_TIMING_MODE=0,//16bit
  RSC_TIMING_MODE,  //8bit
  RDC_TIMING_MODE,  //16bit
}tmode_em;

#define TOTAL_CH_NUM (4)/*ADC通道数目*/

RAC模式配置

/*
 **MS5182N初始化
 */
void ms518x_init(ms518x_st *const me)
{
	me->spi.init(); 
	me->spi.sck(0);// 
	me->spi.cs(0);	 	
	m581x_read_dat(me,0x00,RAC_TIMING_MODE);
	m581x_read_dat(me,0x00,RAC_TIMING_MODE);	//上电后两次无效(哑:UNDEFINED)转换  	
}
/*
**RAC时序模式读取(16bit模式)
*/

unsigned  int ms518x_rac_mode(ms518x_st *const me,const unsigned short int reg_cfg)
{
	unsigned int dat = 0xFFFF;
	static unsigned short int tmp_reg_cfg;

    if(tmp_reg_cfg!=reg_cfg)/*配置发生更新,先执行两次读去(但不采用)之前配置所产生的数据*/
	{
		tmp_reg_cfg=reg_cfg;	
		me->spi.cs(0);   
		sspi_rw_m0(&me->spi,tmp_reg_cfg);  //写第N次配置	读N-2次数据			 
		me->spi.cs(1);//3
		me->spi.delay_us(5);	
		me->spi.cs(0);//4
		sspi_rw_m0(&me->spi,tmp_reg_cfg);//写第N+1次配置	读N-1次数据
		me->spi.cs(1);//5
		me->spi.delay_us(5);		
    }
	me->spi.cs(0); /*读配置的数据*/
	dat = sspi_rw_m0(&me->spi,tmp_reg_cfg);//读第N次数据 写第N+2次配置	
	me->spi.cs(1);					 
	me->spi.delay_us(5);

	return dat;
}

/*
**数据读取
*/
unsigned  int m581x_read_dat(ms518x_st *const me,const unsigned short int reg_cfg,tmode_em mode)
{
	unsigned short int adc_dat=0;
	
   if(RAC_TIMING_MODE==mode)//RAC模式
   {
	  adc_dat = ms518x_rac_mode(me,reg_cfg);
   }
   else if(RSC_TIMING_MODE==mode)//RSC模式
   {
      adc_dat = ms518x_rsc_mode(me,reg_cfg);
   }

   return adc_dat;	 
}

/*
**全通道数据转换读取
*/
void ms518x_all_ch_conv(ms518x_st *const me,const pmode_em pmode, unsigned short int *ch_dat_buff)
{
	for(unsigned char i=0;i<TOTAL_CH_NUM;i++)
	{
	  const unsigned short int reg_dat = MS5182N_REG_DAT_CONV_CFG(pmode,i);/*寄存器配置值*/
	  ch_dat_buff[i]=m581x_read_dat(me,reg_dat,RSC_TIMING_MODE);			
	}	
}

/*
**指定单通道读取
*/
unsigned short int ms518x_sigle_ch_conv(ms518x_st *const me,const pmode_em pmode,const unsigned char ch)
{
	unsigned short int dat_buff=0;
	const unsigned short int reg_dat = MS5182N_REG_DAT_CONV_CFG(pmode,ch);/*寄存器配置值*/
	const unsigned short int dat_buff=m581x_read_dat(me,reg_dat,RSC_TIMING_MODE);				
	return  dat_buff;
}


正负电压测量特别说明:

  • 单极性模式下:ADC输出的数据是二进制原码;双极性模式下:ADC输出的数据则是二进制补码。

  • 假若使用该ADC欲测正负电压的数据,按手册说明,在双极性模式下,其ADC支持-2.048V~+2.048V输入范围.
    其实ADC的共模输入电压范围还是0 ~ +4.096V,只是双极性模式下,将中性参考电位点的电压由单极性的0V,改为了双极性下的Vref/2(ADC内部加了偏置电压),实现正负电压都可以输入。
    * [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HflP5WJQ-1665211163539)(ad7682_tf.png)]

  • 示例步骤:

    • IN0/IN1 通道配置为 双极性差分对模式(即: INx(-)=VREF/2±0.1V电压为参考),
    • 设置 IN0(+) 正输入通道),设置 IN1(-) 负输入通道),
    • IN1(-) 负责用来采集输入电压,将 IN0(+) 通道直接接到 GND(0V)
      • 注:因为我只有一个单端输入信号,但是信号是有要测正负电压的,所以需要将此端直接置0电位,相当于变成单端采集了(这样我的采样范围可以是最大的±2.048V),也可以按照需求接到一个偏置电位,但是输入范围响应的就有所变化,但是无论如何变化,共模输入最大值不得超过4.096V,否则超过了ADC极限,就有损坏的风险
    • 读取 IN0(+) 数据(即此时配置为 IN0(+) 正输入通道),读取的是 (VIN0-VIN1) 的差分数据(嗯,是的,你没看错!!!);
      因为 VIN0=0,假如 IN1(-) 输入值是:-1.5V,则读取到 IN0(+) 上数据是 1.5V
    • 电路设计如下:
      在这里插入图片描述
    • 其实也可以将 IN1 接地,IN0 作为输入采集端,再读 IN1 的数据(即此时即设置了 IN1(+) 正输入通道),即读取的是 (VIN1-VIN0) 的差分数据;
    • 即配置差分模式时,读哪个通道,哪个通道就配置正通道,对应的另一个是负通道,且读的那个通道是两个通道的差分值数据。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐