文章目录
- 1 前言
- 2 AD7793驱动程序
- 2.1 spi访问接口
- 2.2 寄存器和常用配置值
- 2.3 初始化
- 2.4 原始数据获取
- 2.5 阻值换算
- 3 使用
- 4 完整工程代码
1 前言
前面文章主要描述AD7793分别与两线、三线、四线RTD连接电路原理图,及相关阻值计算方法。本文简要说明AD7793驱动程序,如何通过代码精确获取到当前RTD阻值。得到RTD阻值,进而可以通过查表法,对RTD【阻值—温度】表匹配,获得当前温度值。
相关文章:
【RTD】铂电阻测温原理与具体方法
【RTD】AD7793三线式铂电阻PT100/PT1000应用
【RTD】AD7793四线式铂电阻PT100/PT1000应用
【RTD】AD7793两线式铂电阻PT100/PT1000应用
【RTD】AD7793驱动程序
【RTD】二分法查找和分段线性插值算法在RTD中应用
2 AD7793驱动程序
测试平台:
- MCU:STM32F1
- SPI:SPI1(PAA、PA6、PA7)
- CS:PA1
- 支持:两线、三线、四线RTD
2.1 spi访问接口
spi总线借助原有的封装接口(详情参考该文章),只需指定片选函数即可。
static void ad7793_spi_cs(uint8_t state)
{
if (state)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
}
int8_t ad7793_init(struct spi_bus_device *spi_bus)
{
GPIO_InitTypeDef GPIO_InitStructure;
if (NULL == spi_bus)
{
return -1;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
GPIO_SetBits(GPIOA, GPIO_Pin_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ad7793_spi_dev[0].spi_cs = ad7793_spi_cs;
ad7793_spi_dev[0].spi_bus = spi_bus;
return 0;
}
调用spi总线接口实现AD7793 寄存器访问接口,后续读写寄存器都通过下面函数实现。更改为私有spi或者第三方驱动接口,只需更改里面的spi函数即可
static uint8_t ad7793_spi_write(uint8_t addr, uint8_t *pbuf, uint8_t size)
{
spi_send_then_send(&ad7793_spi_dev[0], &addr, 1, pbuf, size);
return size;
}
static uint8_t ad7793_spi_write_byte(uint8_t addr, uint8_t data)
{
ad7793_spi_write(addr, &data, 1);
return 0x01;
}
static uint8_t ad7793_spi_write_word(uint8_t addr, uint16_t data)
{
uint8_t buf[2] = {0};
buf[0] = (data>>8)&0xff;
buf[1] = data&0xff;
ad7793_spi_write(addr, &buf[0], 2);
return 0x02;
}
static uint8_t ad7793_spi_write_3byte(uint8_t addr, uint32_t data)
{
uint8_t buf[3] = {0};
buf[0] = (data>>16)&0xff;
buf[1] = (data>>8)&0xff;
buf[2] = data&0xff;
ad7793_spi_write(addr, &buf[0], 3);
return 0x03;
}
static uint8_t ad7793_spi_read(uint8_t addr, uint8_t *pbuf, uint8_t size)
{
spi_send_then_recv(&ad7793_spi_dev[0], &addr, 1, pbuf, size);
return size;
}
2.2 寄存器和常用配置值
我们把寄存器和常用寄存器配置值通过宏定义出来,后续配置时,通过“或”("|")的方式进行快速配置,并且提高可读性。
#define REG_COMM_STA 0x00
#define REG_MODE 0x08
#define REG_CONFIG 0x10
#define REG_DATA 0x18
#define REG_ID 0x20
#define REG_IO 0x28
#define REG_IMBL 0x30
#define REG_FULL 0x38
#define READ_EN 0x40
#define CONTINUE_READ 0x20
#define CONTINUE_CONVER 0x0000
#define SINGLE_CONVER 0x2000
#define IDLE_MODE 0x4000
#define LOW_POWER_MODE 0x6000
#define IZL_CALIBRATION 0x8000
#define IFC_CALIBRATION 0xA000
#define SZL_CALIBRATION 0xC000
#define SFC_CALIBRATION 0xE000
#define CURRENT_OUT1_1 0x00
#define CURRENT_OUT1_2 0x04
#define CURRENT_OUT1 0x08
#define CURRENT_OUT2 0x0C
#define CURRENT_10UA 0x01
#define CURRENT_210UA 0x02
#define CURRENT_1MA 0x03
#define BIPOLAR 0x0000
#define UNIPOLAR 0x1000
#define GAIN_1 0x0000
#define GAIN_2 0x0100
#define GAIN_4 0x0200
#define GAIN_8 0x0300
#define GAIN_16 0x0400
#define GAIN_32 0x0500
#define GAIN_64 0x0600
#define GAIN_128 0x0700
#define OUTER_VREF 0x0000
#define INNER_VREF 0x0080
#define NO_BUF 0x0000
#define USE_BUF 0x0010
#define AIN_CH1 0x0000
#define AIN_CH2 0x0001
#define AIN_CH3 0x0002
2.3 初始化
AD7793寄存器初始化,决定后续数据计算的过程。基本而且关键的配置包括:
- 抑制比
- 检测极性
- 放大器增益
- ADC参考源
- 检测通道
- 激励恒流源输出
static void ad7793_register_init(void)
{
uint16_t mode = 0x00;
ad7793_spi_read(REG_ID, &s_ad7793_info.id, 1);
ad7793_spi_write_word(REG_MODE, 0x000A);
if (s_ad7793_info.mode&MODE_UNIPOLAR)
{
mode |= MODE_UNIPOLAR;
}
else if (s_ad7793_info.mode&MODE_BIPOLAR)
{
mode |= MODE_BIPOLAR;
}
if (s_ad7793_info.gain > GAIN_128)
{
s_ad7793_info.gain = GAIN_128;
}
mode |= s_ad7793_info.gain;
ad7793_spi_write_word(REG_CONFIG, mode|OUTER_VREF|NO_BUF|AIN_CH1);
ad7793_spi_write_byte(REG_IO, CURRENT_OUT1_1|CURRENT_210UA);
}
2.4 原始数据获取
从数据寄存器读取的数据即为实际检测的AD值。读取数据前,应先查询状态寄存器,根据状态寄存器判断数据转换完毕,才执行读取数据寄存器,确保数据有效性。
int8_t ad7793_read_data(int32_t *ad_value)
{
int8_t ret = 0;
uint8_t temp = 0;
uint8_t buf[3] = {0};
ad7793_spi_read(REG_COMM_STA|READ_EN, &temp ,1);
if (0xbf == (temp|0xbf))
{
ad7793_spi_read(REG_DATA|READ_EN, &buf[0] ,3);
*ad_value = ((buf[0]<<16) | (buf[1]<<8) | buf[2])&0xffffff;
}
else
{
ret = -1;
}
return ret;
}
2.5 阻值换算
该函数作了自适应,根据选定的模式进行计算。支持:
- 两线、三线、四线RTD
- 增益大小
- 单极性、双极性
- 参考电阻【Ref】阻值
int8_t ad7793_read_resistance(float *resistance)
{
int8_t ret = 0;
int32_t ad_value = 0;
uint8_t gain = 0;
if (0 != ad7793_read_data(&ad_value))
{
return -1;
}
gain = 0x01<<(s_ad7793_info.gain>>8);
if (s_ad7793_info.mode&MODE_BIPOLAR)
{
*resistance = (float)s_ad7793_info.ref *(ad_value/0x7fffff-1) / gain;
}
else if (s_ad7793_info.mode&MODE_UNIPOLAR)
{
*resistance = (float)s_ad7793_info.ref * ad_value / 0xffffff / gain;
}
if (s_ad7793_info.mode&MODE_3LINE_RTD)
{
*resistance *= 2;
}
return ret;
}
3 使用
驱动程序支持两线、三线、四线RTD,使用前只需根据原理图和相关参数指定struct _ad7793_info
的参数即可,芯片id参数无需指定,初始化时从id寄存器获取。
struct _ad7793_info
{
uint8_t mode;
uint16_t ref;
uint16_t gain;
uint8_t id;
};
例子,一个四线RTD测量例子:
static struct _ad7793_info s_ad7793_info =
{
.mode = MODE_BIPOLAR|MODE_4LINE_RTD,
.ref = 2000,
.gain = GAIN_1,
};
实际使用过程,还需根据具体电路、测量数据等,调整增益、电流大小、抑制参数等等,以达到最佳测量效果。
4 完整工程代码
【1】https://github.com/Prry/drivers-for-mcu
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)