MS5182N(AD7682)驱动开发调试总结(二)
MS5182N(AD7682)驱动开发调试
·
前言
- 上一篇 文章 主要介绍了对该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内部加了偏置电压),实现正负电压都可以输入。
-
示例步骤:
- 以 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) 的差分数据;
- 即配置差分模式时,读哪个通道,哪个通道就配置正通道,对应的另一个是负通道,且读的那个通道是两个通道的差分值数据。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献3条内容
所有评论(0)