stm32F4驱动AD7793程序-ADC模拟前端-应用详解,应该是最全了

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的数据手册是真的友好,全中文没见到有坑,建议去官网下载。

 

  • 9
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
分享AD7793测量PT100的应用心得分享,用AD7793测量PT100的部分程序,见附件下载AD7793测试程序中文资料。经测试PT100全程温度测量范围内精度达到0.2度,至于干扰嘛,按照官方资料的硬件滤波方法效果还可以。因为涉及公司项目,所以代码不便完全公开,SPI使用的是RTT的底层硬件驱动(参考RealTouch),这里提供的代码主要是借鉴其中顶层应用部分,当然得需要软件标定。如果你感兴趣的话完全可以在这个基础上编写自已的底层驱动。对了,cpu用的stm32f103。 硬件简单描述:硬件可以参考官方资料中的提到的3线制应用,使用AD7793内部电流源,不过我采用的是4线制,效果应该更好些吧。 问题解答: 1. AD7793上电后采集正常,数据到时很稳定,过段时间后就没有数据输出了,AD一直处于转换中,不知道LZ遇到这种问题了没? 我想可能还是时序不太严谨容易出问题,当然这跟应用程序部分也可能有关系。就是软件驱动得做大量测试,硬件驱动如果用在嵌入式就涉及到同步问题。我使用的方法如下,感觉到目前为止7793工作还是挺稳定的。 其一:我现在使用RTT的底层硬件驱动,觉得就是人家编好硬件驱动还是严谨些吧。还有我在硬件上做个检测PT100是否挂载电路,如果检测不到就让7793复位。 其二:软件解决方法:就是一旦数据读取错误,就发复位命令,重新驱动。 可能感兴趣的项目设计: 基于AD7793的温度测量系统电路+PCB源文件,下载链接:https://www.cirmall.com/circuit/2490/detail?3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值