1. AD7793简介:
适合高精度测量应用的低功耗、低噪声的完整模拟前端
内置一个16/24位Σ-Δ型ADC(采样速率 4.17 ~ 470 Hz可调)
含有三路差分模拟输入,内置输入缓冲器
片内集成低噪声可编程仪表放大器(PGA,Gain = 1、2、4、8、16、32、64、128可调)
内置低噪声、低漂移带隙基准电压源
内置可编程激励电流源、熔断电流源、偏置电压发生器(激励电流 10uA、210uA、1mA可调)
四线串行SPI通信接口
2. AD7793应用领域:
热电偶温度测量、热敏电阻测量
力传感器测量
仪器仪表传感器采样
3. 功能框图、应用电路
4. 通信时序
5. 实际波形图
黄 - SCLK ; 蓝 - MOSI
黄 - SCLK ; 蓝 - MISO
黄 - SCLK ; 蓝 - CS
6. stm32F407驱动程序
AD7793.c
#include "AD7793.h"
/*******************************************************************************
* Description : Configure SPI GPIO
*******************************************************************************/
void SPI_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SPI_SCLK_PIN | SPI_MISI_PIN | SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(SPI_GPIO_PORT,&GPIO_InitStructure);
GPIO_PinAFConfig(SPI_GPIO_PORT, GPIO_PinSource10, GPIO_AF_SPI3);
GPIO_PinAFConfig(SPI_GPIO_PORT, GPIO_PinSource11, GPIO_AF_SPI3);
GPIO_PinAFConfig(SPI_GPIO_PORT, GPIO_PinSource12, GPIO_AF_SPI3);
GPIO_InitStructure.GPIO_Pin = SPI_GPIO_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(SPI_GPIO_CS_PORT,&GPIO_InitStructure);
GPIO_SetBits(SPI_GPIO_CS_PORT,SPI_GPIO_CS_PIN); //CS输出高,失能通信
}
/*******************************************************************************
* Description : Configure SPI
*******************************************************************************/
void SPI_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3,ENABLE);
SPI_Cmd(SPI3, DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工模式
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //作为主机使用
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据长度8
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件设置NSS功能
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //波特率预分频值为32,84/32 = 2.625MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI3, &SPI_InitStructure);
SPI_Cmd(SPI3, ENABLE);
}
/*******************************************************************************
* Description : send and receive data
*******************************************************************************/
uint8_t SPI3_TransmitByte(uint8_t TxData)
{
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET); //等待发送区空
SPI_I2S_SendData(SPI3, TxData); //SPIx发送一个Byte数据
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET); //等待接收完一个Byte
return SPI_I2S_ReceiveData(SPI3); //返回接收的数据
}
uint8_t SPI3_Read_OneByte(uint8_t reg)
{
uint8_t i;
SPI_CS_Enable();
SPI3_TransmitByte(reg);
i = SPI3_TransmitByte(0xFF);
SPI_CS_Disable();
return i;
}
/**
* @brief 读取指定寄存器中多个数据
* @param p: 指向SPI设置参数指针
* @param reg: 寄存器地址
* @param pbuf: 指向存储数据的缓存指针
* @param len: 读取长度
*
* @retval 返回结果
*/
void SPI3_Read_buf(uint8_t reg, uint8_t *pbuf, uint8_t len)
{
uint8_t i;
SPI_CS_Enable();
SPI3_TransmitByte(reg);
for(i=0; i<len; i++)
{
pbuf[i] = SPI3_TransmitByte(0xFF);
}
SPI_CS_Disable();
}
/**
* @brief 向指定寄存器中写多个数据
* @param p: 指向SPI设置参数指针
* @param reg: 寄存器地址
* @param pbuf: 指向写数据的缓存指针
* @param len: 写数据长度
*
* @retval 返回结果
*/
void SPI3_Write_buf(uint8_t reg, uint8_t *pbuf, uint8_t len)
{
uint8_t status, i;
SPI_CS_Enable();
SPI3_TransmitByte(reg);
for(i=0; i<len; i++)
{
SPI3_TransmitByte(*pbuf++);
}
SPI_CS_Disable();
}
void AD7793_Reset(void)
{
//连续32个写1脉冲
uint8_t xtemp[3] = {0xFF, 0xFF,0xFF};
SPI3_Write_buf(0xFF, xtemp, 3);
}
/*******************************************************************************
实测AD7793在Gain=64 16.7Hz 65 dB配置下,无抖动位为15Bit
实测AD7793在Gain=64 33.2Hz 配置下,无抖动位为14Bit
*******************************************************************************/
uint8_t xDevice_ID;
void AD7793_Init(void)
{
// uint8_t ModeRegisterMsg[2] = {0x00, 0x0A}; //Continuous Conversion Mode\
// Internal 64 kHz Clock. Internal clock is not available at the CLK pin.\
// Filter Update Rate - 16.7Hz 65 dB (50 Hz and 60 Hz)
uint8_t ModeRegisterMsg[2] = {0x00, 0x07}; //Continuous Conversion Mode\
Internal 64 kHz Clock. Internal clock is not available at the CLK pin.\
Filter Update Rate - 33.2Hz
// uint8_t ConfigRegisterMsg[2] = {0x06, 0x90}; //Bias voltage generator disabled\
// Burnout Current Disable //恒流源失能\
// Bipolar //双极性\
// Gain = 64\
// Internal Reference Selected.//内部参考\
// buffered mode //输入缓冲器使能\
// AIN1(+) – AIN1(–)
uint8_t ConfigRegisterMsg[2] = {0x06, 0x91}; //Bias voltage generator disabled\
Burnout Current Disable //恒流源失能\
Bipolar //双极性\
Gain = 64\
Internal Reference Selected.//内部参考\
buffered mode //输入缓冲器使能\
AIN2(+) – AIN2(–)
uint8_t IoRegisterMsg[1] = {0x00}; //Excitation Current Disabled.
//SPI外设初始化 2.625MHz
SPI_GPIO_Configuration();
SPI_Configuration();
AD7793_Reset();
delay_ms(1);
//读取设备ID寄存器
xDevice_ID = SPI3_Read_OneByte(0x60); //ID register 0xXA(AD7792)/0xXB(AD7793)
if((xDevice_ID & 0x0F) == 0x0B)
{
//进行功能参数配置写入
delay_ms(1);
SPI3_Write_buf(0x08, ModeRegisterMsg, 2); //Mode register
delay_ms(1);
SPI3_Write_buf(0x10, ConfigRegisterMsg, 2); //Config register
delay_ms(1);
SPI3_Write_buf(0x28, IoRegisterMsg, 1); //IO register
delay_ms(1);
}
}
//读AD7793的转换数据寄存器。3字节,无符号
int32_t Read_AD7793_Data(void)
{
uint8_t xStatus=1;
uint8_t xRDY=0x80;
uint8_t xtemp[3];
int32_t adValue=0;
// //每次读取ADC转换值前,先读取状态寄存器的RDY位,是否清0
// while(xRDY)
// {
// xStatus = SPI3_Read_OneByte(0x40); //Status register
// xRDY = xStatus & 0x80;
// vTaskDelay(1);
// }
//读取24位数据寄存器
SPI3_Read_buf(0x58, xtemp, 3); //Data register
adValue = (((int32_t)xtemp[0])<<16) | (((int32_t)xtemp[1])<<8) | (((int32_t)xtemp[2]));
return adValue;
}
//将int32转换为2进制,并用串口打印出来。方便调试查看ADC的无抖动位
void ToBin(int32_t xValue)
{
int8_t i=0;
int32_t Bit_adValue;
uint8_t btemp[26];
/* 按Bit显示 */
Bit_adValue = xValue;
for(i=23;i>-1;i--)
{
btemp[i] = (uint8_t)(Bit_adValue & 0x00000001) + '0';
Bit_adValue = Bit_adValue>>1;
}
btemp[24] = '\r';
btemp[25] = '\n';
RS485_Send_Data(btemp, 26);
}
AD7793.h
#ifndef _AD_7793_H
#define _AD_7793_H
#include "structure.h"
//pin
#define SPI_SCLK_PIN GPIO_Pin_10
#define SPI_MISO_PIN GPIO_Pin_11
#define SPI_MISI_PIN GPIO_Pin_12
#define SPI_GPIO_PORT GPIOC
#define SPI_GPIO_CS_PORT GPIOC
#define SPI_GPIO_CS_PIN GPIO_Pin_9
#define SPI_CS_Enable() GPIO_ResetBits(SPI_GPIO_CS_PORT,SPI_GPIO_CS_PIN) //Chip Select pin set low
#define SPI_CS_Disable() GPIO_SetBits(SPI_GPIO_CS_PORT,SPI_GPIO_CS_PIN) //Chip Select pin set High
uint8_t SPI3_Read_OneByte(uint8_t reg);
void AD7793_Init(void);
int32_t Read_AD7793_Data(void);
void ToBin(int32_t xValue);
#endif
main.c
int32_t AD7793_adValue; //ads1115的adc转换值
int main(void)
{
AD7793_Init();
while(1)
{
AD7793_adValue = Read_AD7793_Data();
delay_ms(100);
}
}
7. 注意事项
(1)上电后必须要复位后才能使用。否则有几率读取的24位ADC转换值不正常。
AD7793_Reset(); -- 连续写32个Bit1就复位成功了
(2)int32_t Read_AD7793_Data(void)。AD7793的ADC转换值为无符号的24Bit数据。
(3)int32_t Read_AD7793_Data(void)。为保证每次ADC转换值均为最近一次,最好将while(xRDY)一段屏蔽的加上。
我的应用中,不需要每次数据均为最新的转换值,只要保证读取过程时间短就行,所以这段屏蔽了。
这个片子做热电偶测温、电桥测量实在太方便。电流源、PGA、ADC全集成。我代码里初始化没用电流源切记。
u1s1,AD7793的数据手册是真的友好,全中文没见到有坑,建议去官网下载。