RT Thread中配置AD7190

发布时间 2023-12-05 20:07:20作者: qsy_edt

​详见RT Thread中配置AD7190-CSDN博客

 编辑

使用前先复位操作

1 SCL空闲时会高电平。

2复位:上电后连续输入40个1(时钟周期)复位到已知状态,并等待500us后才能访问串行接口,用于SCLK噪音导致的同步。

编辑

void AD7190_Reset(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //

    /* 复位 */
    struct rt_spi_message msg;
    rt_uint8_t sendbuf[16]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

    msg.send_buf   = sendbuf;
    msg.recv_buf   = RT_NULL;
    msg.length     = 16;
    msg.cs_take    = 1;
    msg.cs_release = 1;
    msg.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg);

    rt_thread_mdelay(10);   // 必须延迟2ms以上,再进行ad7190操作
    rt_kprintf("AD7190 reset ok\n");
}

一、 特性

特性见手册

编辑

二、寄存器

1.通信寄存器

        8位的只写寄存器,与AD7190的通信都必须以对通信寄存器的写操作开始。

        通信寄存器决定写还是读操作,对哪个寄存器进行操作。

        通过配置好通信寄存器后,对选定的寄存器进行操作完成后,会回到写通信寄存器的状态,也就是每配置一下指定的寄存器,如果下一次还想对其他包括刚配置的寄存器再进行配置,还是需要从写通信寄存器开始,这也是接口的默认状态。

1)通信寄存器的8位

编辑

2)通信寄存器的各个名称和意义

编辑

3)(表15)寄存器的选择

编辑

4)写入示例

7位:0 (必须,使能位)

6位:0 写 、1读

5-3位:100 (选择ID寄存器)其他见表15

2位:1 连续读寄存器

1-0位:00 (必须)

        0101 1100 写入通信寄存器即可连续读数据寄存器,后续不必对通信寄存器进行写操作。

禁用连续读把2位写0就好。

void AD7190_ID_RD(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    //配置通信寄存器连续读命令
    struct rt_spi_message msg1;
    rt_uint8_t CommRegCMD = 0x5C;         //  0101 1100 连续读

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = RTNULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ID REG: %x\n", ID_Reg);

}

2.ADC状态寄存器

        正常使用时没用到,可先不管 。    

         8位的只读寄存器。要访问 必须写通信寄存器,选择下一个操作为读操作,寄存器选择位为000。

1)状态寄存器的8个位

编辑

2)寄存器的各位的名称和意义

编辑

3.模式寄存器

        模式寄存器,24位的可读 写寄存器。

        功能:选择工作模式、输出速率、时钟源

1)模式寄存器的24位

编辑

 2)寄存器的各个位的名称和意义

编辑

编辑

3)(表18)工作模式

编辑

4)写入实例

23-21位:000  (连续转换)   模式选择位(表18) 还有 单次 、空闲、省电、校准 模式选择 

20位:1  状态寄存器的内容在数据寄存器读操作之后传输,多通道可找到对应的通道与数据寄存器的值。0 就禁用

19-18位:10 (内部时钟4.92MHZ)选择时钟源

17-16位:00 (必须)

15位:0  滤波器选择

14位:0 (必须)

13位:0 (奇偶校验位) 用这个需要设置20位 1

12位:0 (必须)

11位:1 单周期转换使能位 (详细见上表)

10位:1  50/60MHZ抑制

9-0位:00 0000 0011  滤波器输出速率选择位

void AD7190_ModeReg_Set(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 操作模式选择寄存器 */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x08;    //0000 1000   ModeReg 写入 命令, 其实就是通信寄存器写入  0X08,0x08,0x04,0x03
    rt_uint8_t ModeReg[3] = {0x08, 0x04, 0x03}; //模式寄存器写入值0000 1000、0000 0100、0000 0011

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = ModeReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ModeREG Set OK!\n");
}

4.配置寄存器

         配置寄存器,24位的可读 写寄存器。

        功能:ADC的单极性、双极性模式、使能或禁用缓冲器、使能或禁用激励电流、增益选择、模拟输入通道选择

1)配置寄存器的24位

编辑

2)配置寄存器各位的名称和意义

编辑

3)(表20)通道选择

编辑

4)写入实例

23位:1 斩波使能位

22-21位:00 (必须)

20位: 0  1 基准电压的输入选择

19-16位:0000 (必须)

15-8位:0x01\0x02  通道选择位

7位:0   激励电流 (1使用)

6位:0  基准电压检测(1使用)

5位:0 (必须)

4位:1 使能模拟端输入的缓冲器

3位:0 极性选择  0 双极性 1 单极性

2-0位:110  (64增效)  增益位选择

void AD7190_ConfigReg_Set(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 配置 配置寄存器*/
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x10;          //  ConfigReg 写入 命令, 其实就是通信寄存器写入 0001 0000
    rt_uint8_t ConfigReg[3] = {0x80, 0x02, 0x16}; //配置寄存器写入 1000 0000、0000 0010、0001 0110 / 0x02通道选择位

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = ConfigReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
//    rt_kprintf("AD7190 ConfigREG Set OK!\n");
}

5.数据寄存器

        24位的只读寄存器,存储ADC的转换结果。

        当模式寄存器中的DAT_STA位设置为1时,状态寄存器的内容将附加到各24位的转换结果上。状态寄存器的三个LSB(CHD2至CHD0)可确定转换结果的来源通道。

6.ID寄存器

        8位的只读寄存器,存储着AD7190的识别码,即ID。

void AD7190_ID_RD(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD = 0x60;         //  ID_Reg_Read_CMD 命令, 其实就是通信寄存器写入 0110 0000
    rt_uint8_t ID_Reg     = 0x00;

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = RT_NULL;
    msg2.recv_buf   = &ID_Reg;
    msg2.length     = 1;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ID REG: %x\n", ID_Reg);

}

7.GPOCON寄存器

        8位的 读 写寄存器。

        功能:使能 通用数字输出

1)GPOCON寄存器的8位

编辑

2)寄存器的各位名称和意义

编辑

3)输入实例

void AD7190_GPOCONReg_Set(rt_uint8_t bpsw)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x28;          //0010 1000   ModeReg 写入 命令, 其实就是通信寄存器写入  0X08,0x08,0x04,0x03
    rt_uint8_t GPOCONReg = 0x00 ;            //GPOCON寄存器写入值

    if( bpsw == 1)
        GPOCONReg = 0x40; //电桥打开
    else
        GPOCONReg = 0x00;
//    GPOCONReg = GPOCONReg | (bpsw << 2);

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = &GPOCONReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 1;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 GPOCON Set OK!\n");
}

8.失调寄存器 

保存adc的失调校准系数

9.满量程寄存器

保存adc的满量程校准系数

 

10.使用案例

AD7190.h

#ifndef HARDWARE_AD7190_H_
#define HARDWARE_AD7190_H_

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define AD7190_BPSW_ON     1   // 电桥打开
#define AD7190_BPSW_OFF    0

///-------------------------------------------------------
void AD7190_ID_RD(void);
void AD7190_Reset(void);
void AD7190_ConfigReg_Set(void);
void AD7190_ConfigReg_Read(void);
void AD7190_ConfigReg_Switch(void);
void AD7190_ModeReg_Set(void);
void AD7190_ModeReg_Read(void);

void AD7190_GPOCONReg_Set(rt_uint8_t bpsw);

void AD7190_Init(void);
rt_uint32_t AD7190_DataReg_RD(void);



#endif /* HARDWARE_AD7190_H_ */

AD7190.c

#ifndef HARDWARE_AD7190_C_
#define HARDWARE_AD7190_C_


#include <AD7190.h>

#define AD7190_SPI_DEVICE_NAME     "spi10"   /* SPI 设备名称 */  // 和myspi.c里面驱动一致
struct rt_spi_device *spi_dev_ad7190;     /* SPI 设备句柄 */

//初始复位
void AD7190_Reset(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //

    /* 复位 */
    struct rt_spi_message msg;
    rt_uint8_t sendbuf[16]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

    msg.send_buf   = sendbuf;
    msg.recv_buf   = RT_NULL;
    msg.length     = 16;
    msg.cs_take    = 1;
    msg.cs_release = 1;
    msg.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg);

    rt_thread_mdelay(10);   // 必须延迟2ms以上,再进行ad7190操作
    rt_kprintf("AD7190 reset ok\n");
}


//读取ID值
void AD7190_ID_RD(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD = 0x60;         //  ID_Reg_Read_CMD 命令, 通信寄存器写入 0110 0000
    rt_uint8_t ID_Reg     = 0x00;

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = RT_NULL;
    msg2.recv_buf   = &ID_Reg;
    msg2.length     = 1;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ID REG: %x\n", ID_Reg);

}



//设置配置寄存器
void AD7190_ConfigReg_Set(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x10;          //  ConfigReg 写入 命令, 通信寄存器写入 0001 0000
    rt_uint8_t ConfigReg[3] = {0x80, 0x02, 0x16}; //配置寄存器写入 1000 0000、0000 0010、0001 0110 / 0x02通道选择位

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = ConfigReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
//    rt_kprintf("AD7190 ConfigREG Set OK!\n");
}

//配置寄存器更换通道
void AD7190_ConfigReg_Switch(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x10;          //  ConfigReg 写入 命令0001 0000
    rt_uint8_t ConfigReg[3] = {0x80, 0x01, 0x17}; //配置寄存器写入 1000 0000、0000 0001、0001 0111 / 0x01通道选择位 128增益

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = ConfigReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
//    rt_kprintf("AD7190 ConfigREG Set OK!\n");
}

//读取配置信息
void AD7190_ConfigReg_Read(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x50; //  ConfigReg 写入 命令 | 0x40, 次高位写1,读取  0101 0000
    rt_uint8_t ConfigReg[3] ;

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = RT_NULL;
    msg2.recv_buf   = ConfigReg;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ConfigREG read: %02X,%02X,%02X\n",ConfigReg[0] ,ConfigReg[1] ,ConfigReg[2] );
}

//设置模式寄存器
void AD7190_ModeReg_Set(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 操作模式选择寄存器 */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x08;    //0000 1000   ModeReg 写入 命令0X08,0x08,0x04,0x03
    rt_uint8_t ModeReg[3] = {0x08, 0x04, 0x03}; //模式寄存器写入值0000 1000、0000 0100、0000 0011

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = ModeReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ModeREG Set OK!\n");

}

//校准
//calibration校准 内部零电平校准 0x88、内置满量程校准0xA8、系统零电平校准0xC8、系统满量程校准0xE8
void AD7190_Calibration(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x08;    //0000 1000   ModeReg 写入 命令0X08,0x08,0x04,0x03
    rt_uint8_t ModeReg[3] = {0x88, 0x04, 0x03}; //模式寄存器写入值0000 1000、0000 0100、0000 0011

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = ModeReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ModeREG Set OK!\n");
}

//模式寄存器读取
void AD7190_ModeReg_Read(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x48; // 0100 1000  ModeReg 写入 命令  0X08,0x08,0x04,0x03
    rt_uint8_t ModeReg[3];

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = RT_NULL;
    msg2.recv_buf   = ModeReg;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 ModeREG read: %02X,%02X,%02X\n",ModeReg[0] ,ModeReg[1] ,ModeReg[2] );
}

//设置模式寄存器
void AD7190_GPOCONReg_Set(rt_uint8_t bpsw)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //
    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x28;          //0010 1000  
    rt_uint8_t GPOCONReg = 0x00 ;            //GPOCON寄存器写入值

    if( bpsw == 1)
        GPOCONReg = 0x40; //电桥打开
    else
        GPOCONReg = 0x00;
//    GPOCONReg = GPOCONReg | (bpsw << 2);


    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = &GPOCONReg;
    msg2.recv_buf   = RT_NULL;
    msg2.length     = 1;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
    rt_kprintf("AD7190 GPOCON Set OK!\n");
}

//AD7190初始化
void AD7190_Init(void)
{
    AD7190_Reset();                         //复位
    AD7190_ID_RD();                         //ID寄存器
    AD7190_ConfigReg_Set();                 //配置寄存器
    AD7190_Calibration();                  //校准
    AD7190_ModeReg_Set();                   //模式寄存器
    AD7190_GPOCONReg_Set(AD7190_BPSW_ON);   //GPOCON寄存器(使能通用数字输出)
}

//读取AD7190的数据寄存器
rt_uint32_t AD7190_DataReg_RD(void)
{
    spi_dev_ad7190 = (struct rt_spi_device *)rt_device_find(AD7190_SPI_DEVICE_NAME);  //

    /* 发送命令读取ID */
    struct rt_spi_message msg1, msg2;
    rt_uint8_t CommRegCMD   = 0x58;          //0101 1000  DATAReg 读取 命令
    rt_uint8_t DataReg[3];
    rt_uint32_t lw_ADC_value;

    msg1.send_buf   = &CommRegCMD;
    msg1.recv_buf   = RT_NULL;
    msg1.length     = 1;
    msg1.cs_take    = 1;
    msg1.cs_release = 0;
    msg1.next       = &msg2;

    msg2.send_buf   = RT_NULL;
    msg2.recv_buf   = DataReg;
    msg2.length     = 3;
    msg2.cs_take    = 0;
    msg2.cs_release = 1;
    msg2.next       = RT_NULL;

    rt_spi_transfer_message(spi_dev_ad7190, &msg1);
//    rt_kprintf("AD7190 DataREG read: %02X,%02X,%02X\n",DataReg[0] ,DataReg[1] ,DataReg[2] );

    lw_ADC_value = ( (rt_uint32_t)DataReg[0] <<16 ) + ( (rt_uint32_t)DataReg[1] << 8) +  (rt_uint32_t)DataReg[2];
    //rt_kprintf("ADC=%d\n",lw_ADC_value);

    return lw_ADC_value;
}

//=====================------------------------------








#endif /* HARDWARE_AD7190_C_ */