详解STM32移植AD7190驱动步骤
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为内部增益设置
使用流程:
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;
}
/* 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);
/* 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);
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,®isterWord,1,0xFFFF);
}
调试问题点:
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位计算时高位数据溢出。
作者:unfair269