64kSPS、低功耗、多通道同步、24 位ADC生物电势测量的模拟前端AFE9XX

这篇具有很好参考价值的文章主要介绍了64kSPS、低功耗、多通道同步、24 位ADC生物电势测量的模拟前端AFE9XX。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

AFE94X多通道同步采集,64KSPS,24bit SD_ADC AFE94X
验证驱动,阻塞等待DRDY(仅验证驱动使用),兼容-类比芯片STM32HAL库SPI
https://blog.csdn.net/hhhhwdnmd/article/details/135774192?spm=1001.2014.3001.5501


一、AFE94X是什么?

AFE94X是多通道同步采样 24 位 Δ-Σ 模数转换器(ADC)系列,内置有可编程增益放大器(PGA)、内部基准以及板载振荡器。AFE94x 包含医疗心电图(ECG)和脑电图(EEG)应用中通
常所需的全部功能。凭借高集成度和出色性能,AFE94x能够以大幅缩小的尺寸、显著降低的功耗和整体成本开发可扩展的医疗仪器系统。

二、使用步骤

1.AFE94X.h

/*
    Analogysemi xutong
    2023/02/15
*/
#ifndef __AFE94X_H
#define __AFE94X_H
 
#include "bsp_lpspi.h"
#include "stm32f4xx.h"
 
#define AFE94x_START_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define AFE94x_PWDN_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define AFE94x_DRDY_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define AFE94x_REST_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOB_CLK_ENABLE()
 
/* Definition for AFE94x Pins */
#define AFE94x_START_PIN                     GPIO_PIN_8
#define AFE94x_START_GPIO_PORT               GPIOA
#define AFE94x_DRDY_PIN                    	 GPIO_PIN_12
#define AFE94x_DRDY_GPIO_PORT                GPIOA
#define AFE94x_PWDN_PIN                      GPIO_PIN_11
#define AFE94x_PWDN_GPIO_PORT                GPIOA
#define AFE94x_REST_PIN                      GPIO_PIN_1
#define AFE94x_REST_GPIO_PORT                GPIOB
 
/*command define*/
 
#define AFE94X_WAKEUP  0x02
#define AFE94X_STANDBY 0x04
#define AFE94X_RESET   0x06
#define AFE94X_START   0x08
#define AFE94X_STOP    0x0A

#define AFE94X_RDATAC  0x10
#define AFE94X_SDATAC  0x11
#define AFE94X_RDATA   0x12
#define AFE94X_OFFSETCAL  0x1A

#define AFE94X_RREG    0X20
#define AFE94X_WREG    0X40
#define AFE94X_RREGX   0xE4
#define AFE94X_WREGX   0xE8
//RREG Read n nnnn registers starting at address r rrrr 
//First Byte 001r rrrr (2xh)
//Second Byte 000n nnnn 
//n nnnn = number of registers to be read or written – 1. For example, to read or write three registers, set n nnnn = 0 (0010). r rrrr = the
//starting register address for read and write commands
//WREG 同上
//WREG First Byte (4xh)
/*
    寄存器地址
*/
#define AFE94X_ID           0x00
#define AFE94X_CONFIG1      0x01
#define AFE94X_CONFIG2      0x02
#define AFE94X_CONFIG3      0x03
#define AFE94X_LOFF         0x04

#define AFE94X_CH1SET      0X05
#define AFE94X_CH2SET      0X06
#define AFE94X_CH3SET      0X07
#define AFE94X_CH4SET      0X08
#define AFE94X_CH5SET      0X09
#define AFE94X_CH6SET      0X0A
#define AFE94X_CH7SET      0X0B
#define AFE94X_CH8SET      0X0C
#define AFE94X_RLD_SENSP   0X0D
#define AFE94X_RLD_SENSN   0X0E
#define AFE94X_LOFF_SENSP  0X0F
#define AFE94X_LOFF_SENSN  0X10
#define AFE94X_LOFF_FLIP   0X11

#define LOFF_STATP_Status   0X12
#define LOFF_STATN_Status   0X13

#define AFE94X_GPIO        0X14 
#define AFE94X_PACE        0X15
#define AFE94X_RESV        0X16
#define AFE94X_CONFIG4     0X17
#define AFE94X_WCT1        0X18
#define AFE94X_WCT2        0X19

#define AFE94X_WCT3        0X1A
#define AFE94X_CONFIG5     0X1C
#define AFE94X_CONFIG6     0X1D
#define AFE94X_CONFIG7     0X1E
#define AFE94X_CONFIG8     0X1F
#define AFE94X_CONFIG9     0X20
#define AFE94X_LOFF_CFCG1  0X21
#define AFE94X_LOFF_CFCG2  0X22
#define AFE94X_LOFF_ACLO1  0X23
#define AFE94X_LOFF_ACLO2  0X24
#define AFE94X_REDR2P      0X25
#define AFE94X_CHMUX_MSB   0X26
#define AFE94X_LOFF_CMP_FLIP 0X27
#define AFE94X_LOFF_SENSN1 0X28
#define AFE94X_LOFF_SENSP1 0X29
#define AFE94X_SRB1_COFIG  0X2A
#define AFE94X_BIAS_DAC    0X2B
#define AFE94X_XOSC_CFG    0X2C
#define AFE94X_LOW_NOISE   0X2E
#define AFE94X_MISC_ANA    0X34
#define AFE94X_MOD_STAT    0X35
#define AFE94X_CMD_STAT    0X36
#define AFE94X_PGAP_OOR    0X37
#define AFE94X_PGAN_OOR    0X28

/*
    寄存器设置
*/
//CONFIG2
#define	EXT_TEST_ON	       0X00	//关闭内部测试信号,外部(默认)
#define	INT_TEST_ON		   0X10
//CONFIG3
#define INT_REF_EN         0X80   //内部基准(default)
#define EXT_REF_EN         0X00   //外部基准
#define AFE94X_REF_2_4V    0X00   //default
#define AFE94X_REF_4V      0X20
#define RLD_REF_PD_EN      0X04   //default
#define RLD_REF_PD_DIS     0X00
#define AFE94X_RLDREF_INT  0X08
#define AFE94X_RLDREF_EXT  0X00   //default
#define AFE94X_RLD_BUF_EN  0X04
#define AFE94X_RLD_BUF_DIS 0X00   //default
#define RLD_LOFF_SENS_EN   0X02
#define RLD_LOFF_SENS_DIS  0X00   //default 
#define RLD_STAT_EN        0X00   //default
#define RLD_STAT_DIS       0X01
//LOFF
#define AFE94X_COMP_95_5   0X00
#define AFE94X_COMP_92_7   0X20
#define AFE94X_COMP_90_8   0X40
#define AFE94X_COMP_87_12  0X60
#define AFE94X_COMP_85_15  0X80
#define AFE94X_COMP_80_20  0XA0
#define AFE94X_COMP_75_25  0XC0
#define AFE94X_COMP_70_30  0XE0
#define LEAD_CURRENT_9NA   0X00
#define LEAD_CURRENT_18NA  0X03
#define LEAD_CURRENT_27NA  0X04
#define LEAD_CURRENT_40NA  0X0C
#define FLEAD_AC_LEAD      0X01
#define FLEAD_DC_LEAD      0X03
//CHXSET
#define AFE94X_CH_PD       0X80  //Channel power-down
#define AFE94X_CH_EN       0X00  //Normal operation
#define AFE94X_PGA_1       0X10
#define AFE94X_PGA_2       0X20
#define AFE94X_PGA_3       0X30
#define AFE94X_PGA_4       0X40
#define AFE94X_PGA_6       0X00 //default
#define AFE94X_PGA_8       0X40
#define AFE94X_PGA_12      0X60
#define AFE94X_PGA_24      0X70
#define	MUX_Normal_input   0X00	//普通电极输入(默认)
#define	MUX_Input_shorted  0X01	//输入短路
#define MUX_RLD_Test       0x02
#define	MUX_Test_signal    0X05	//测试信号输入
#define	MUX_RLD_DRP		   0X06		
#define	MUX_RLD_DRN		   0X07			
#define	MUX_RLD_DRPM	   0X00	//CHX_MUX_MSB must set	CHX_MUX_MSB|MUXn = 1000	
#define	MUX_RSP_RESP       0X01 //CHX_MUX_MSB must set  CHX_MUX_MSB|MUXn = 1001
#define MUX_AFE_BYPASS     0X02 //CHX_MUX_MSB must set  CHX_MUX_MSB|MUXn = 1010
//CONFIG4
#define AFE94X_SHOT_MODE   0X20
#define AFE94X_CONT_MODE   0X00 //default
#define AFE94X_COMP_PDEN   0X02 
#define AFE94X_COMP_PDDIS  0X00 //default
#define WCT_RLD_CONNECT    0X01 
//WCT1
#define PD_WCTA_DIS        0X00 //default
#define PD_WCTA_EN         0X08
#define WCTA_AIN1P_Amp     0X00
#define WCTA_AIN1N_Amp     0X01
#define WCTA_AIN2P_Amp     0X02
#define WCTA_AIN2N_Amp     0X03
#define WCTA_AIN3P_Amp     0X04
#define WCTA_AIN3N_Amp     0X05
#define WCTA_AIN4P_Amp     0X06
#define WCTA_AIN4N_Amp     0X07
//WCT2
#define PD_WCTC_DIS        0X00 //default
#define PD_WCTC_EN         0X80
#define PD_WCTB_DIS        0X00
#define PD_WCTB_EN         0X40 //default
#define WCTB_AIN1P_Amp     0X00
#define WCTB_AIN1N_Amp     0X08
#define WCTB_AIN2P_Amp     0X10
#define WCTB_AIN2N_Amp     0X18
#define WCTB_AIN3P_Amp     0X20
#define WCTB_AIN3N_Amp     0X28
#define WCTB_AIN4P_Amp     0X30
#define WCTB_AIN4N_Amp     0X38
#define WCTC_AIN1P_Amp     0X00
#define WCTC_AIN1N_Amp     0X01
#define WCTC_AIN2P_Amp     0X02
#define WCTC_AIN2N_Amp     0X03
#define WCTC_AIN3P_Amp     0X04
#define WCTC_AIN3N_Amp     0X05
#define WCTC_AIN4P_Amp     0X06
#define WCTC_AIN4N_Amp     0X07
//WCT3
#define WCT_SW7_OFF        0X00 //default
#define WCT_SW7_ON         0X80
#define WCT_SW6_OFF        0X00 //default
#define WCT_SW6_ON         0X40 
#define WCT_SW5_OFF        0X00 //default
#define WCT_SW5_ON         0X20
#define WCT_SW4_OFF        0X00 //default
#define WCT_SW4_ON         0X10
#define WCT_SW4_EN         0X08
#define WCT_SW4_DIS        0X00 //default
#define WCT_BUF_LOW        0X04 //default
#define WCT_BUF_HIGH       0X00
#define WCT_BYPASS_BUF     0X01
//CONFIG5
#define INT_OSC_2M         0X00 //default Internal OSC frequency 2M
#define INT_OSC_1M         0X40 //Internal OSC frequency 1M
#define INT_OSC_0_5M       0X80 //Internal OSC frequency 512K
#define INT_OSC_0_2M       0XC0 //Internal OSC frequency 216K
#define AFE94X_HS_MODE     0X02
#define AFE94X_LP_MODE     0X01
//L0FF_CGF2
#define RLD_COMP_95_5      0X00 //default
#define RLD_COMP_92_7      0X04
#define RLD_COMP_90_8      0X08
#define RLD_COMP_87_12     0X0C
#define RLD_COMP_85_15     0X10
#define RLD_COMP_80_20     0X14
#define RLD_COMP_75_25     0X18
#define RLD_COMP_70_30     0X38
#define LEAD_Debounce_DIS  0X00 //default
#define LEDA_Debounce_117  0x01
//CHMUX_MSB
#define CH8_MUX_MSB        0X80
#define CH7_MUX_MSB   	   0X40
#define CH6_MUX_MSB   	   0X20
#define CH5_MUX_MSB        0X10
#define CH4_MUX_MSB    	   0X08
#define CH3_MUX_MSB        0X04
#define CH2_MUX_MSB        0X02
#define CH1_MUX_MSB        0X01

//GPIO
#define GPIOD_GPIO1        0X10
#define GPIOD_GPIO2        0X20
#define GPIOD_GPIO3        0X40
#define GPIOD_GPIO4        0X80
#define GPIO_IN_GPIO1      0X01
#define GPIO_IN_GPIO2      0X02
#define GPIO_IN_GPIO3      0X04
#define GPIO_IN_GPIO4      0X08
#define GPIO_OUT_GPIO1     0X00
#define GPIO_OUT_GPIO2     0X00
#define GPIO_OUT_GPIO3     0X00
#define GPIO_OUT_GPIO4     0X00
//LOFF_CFG1
#define RLD_COMP_EN
#define CUR_LEVEL

//RLD_DAC
#define RLD_DAC_EN         0X80
#define RLD_DAC_DIS        0X00
#define RLD_REF_AVDD       0X00
#define RLD_REF_AREEP      0X40
/*
  通道选择
  channel select
*/
#define AFE94X_AIN1        0
#define AFE94X_AIN2        1
#define AFE94X_AIN3        2
#define AFE94X_AIN4        3
#define AFE94X_AIN5        4
#define AFE94X_AIN6        5
#define AFE94X_AIN7        6
#define AFE94X_AIN8        7

//写命令
void AFE9XX_Command(uint8_t Com);
//获取芯片的ID号
uint8_t AFE9XX_GetChipID(void);
 
//获取寄存器值
uint8_t AFE9XX_GetReg(uint8_t Rreg);
//获取多个寄存器值
void AFE9XX_ReadMultiReg(uint8_t StartReg,uint8_t RegNum,uint8_t *Data);
//写入寄存器值
void AFE9XX_WriteReg(uint8_t Wreg,uint8_t Data);
//写多个寄存器的值
void AFE9XX_WriteMultiReg(uint8_t StartReg,uint8_t RegNum,uint8_t *Data);
//获取所有寄存器值
void AFE9XX_GetAllReg(void);
//设定通道并且获取ADC的值
// CH设置为 0或者设通道0/1
void AFE9XX_GetADC_Value(uint8_t AIN_P,uint8_t AIN_N,uint8_t *Rxdata);
//初始化AFE9XX
void AFE9XX_Init(void);
//获取通道ADC值
float AFE9xx_GetValue(uint8_t AIN_CH,uint8_t AFE94X_REF,uint8_t *Rxdata);
//获取所有通道ADC值
void AFE94X_GetAllValue(uint8_t AFE94X_REF,uint8_t *Rxdata,float *Voltage);
//获取内部温度传感器值
float AFE9XX_GetTempture(uint8_t *Rxdata);
//获取设备噪声值
float AFE9XX_Noise_Test(uint8_t *Rxdata);
//电源测试
float AFE9XX_PWR_Test(uint8_t *Rxdata);
//直流导联脱落
void AFE9XX_DCLEAD_OFF(uint8_t *Rxdata);
//内部信号测试
void AFE9XX_SINGLE_TEST(uint8_t *Rxdata);
void TEST_RLD_SINGLE(uint8_t *Rxdata);
#endif

2.AFE94X.c

代码如下(示例):文章来源地址https://www.toymoban.com/news/detail-858026.html

#include "AFE94X.h"
//初始化AF94X
void AFE9XX_Init(void)
{
  //拉PWDN和RST
	GPIO_InitTypeDef GPIO_Initure;
    AFE94x_START_GPIO_CLK_ENABLE();           //开启START时钟
	AFE94x_PWDN_GPIO_CLK_ENABLE();            //开启PWDN时钟
	AFE94x_DRDY_GPIO_CLK_ENABLE();            //开启DRDY时钟
	AFE94x_REST_GPIO_CLK_ENABLE();            //开启REST时钟
	
    GPIO_Initure.Pin=AFE94x_DRDY_PIN;         //DRDY
    GPIO_Initure.Mode=GPIO_MODE_INPUT;  
    GPIO_Initure.Pull=GPIO_PULLUP;          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     
    HAL_GPIO_Init(AFE94x_DRDY_GPIO_PORT,&GPIO_Initure);
	
	GPIO_Initure.Pin=AFE94x_PWDN_PIN;          //PWDN
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
    GPIO_Initure.Pull=GPIO_PULLUP;          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     
    HAL_GPIO_Init(AFE94x_PWDN_GPIO_PORT,&GPIO_Initure);
	
	GPIO_Initure.Pin=AFE94x_START_PIN;         //START
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
    GPIO_Initure.Pull=GPIO_PULLUP;          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     
    HAL_GPIO_Init(AFE94x_START_GPIO_PORT,&GPIO_Initure);
	
    GPIO_Initure.Pin=AFE94x_REST_PIN;           //REST
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
    GPIO_Initure.Pull=GPIO_PULLUP;          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     
    HAL_GPIO_Init(AFE94x_REST_GPIO_PORT,&GPIO_Initure);
	
	HAL_GPIO_WritePin(AFE94x_PWDN_GPIO_PORT,AFE94x_PWDN_PIN,1);  //拉高PWDN
	HAL_GPIO_WritePin(AFE94x_REST_GPIO_PORT,AFE94x_REST_PIN,0);  //拉低REST
	HAL_Delay(1);
	HAL_GPIO_WritePin(AFE94x_REST_GPIO_PORT,AFE94x_REST_PIN,1);  //拉低REST
	HAL_GPIO_WritePin(AFE94x_START_GPIO_PORT,AFE94x_START_PIN,0);//START
	
	AFE9XX_Command(AFE94X_RESET);

}
//获取芯片的ID号
uint8_t AFE9XX_GetChipID(void)
{
    uint8_t ID;
    ID=AFE9XX_GetReg(AFE94X_ID);
    return ID;
}
//获取芯片寄存器值
uint8_t AFE9XX_GetReg(uint8_t Rreg)
{
   uint8_t TxData[3];
   uint8_t RxData[3];
   uint8_t Reg_Val=0;
	//寄存器地址小于0X1F
   if(Rreg <= 0X1F)
   {
		//读取命令,选择要读取的寄存器
		TxData[0]=AFE94X_RREG|Rreg;
		//读取单个寄存器
		TxData[1]=0x00;
		Lpspi_Read(3,TxData,RxData);
		//返回寄存器值
   }
   //寄存器地址大于0X1F
   else
   {
	   //获取CONFIG8寄存器Value
		Reg_Val=AFE9XX_GetReg(AFE94X_CONFIG8);
		//写入CONFIG8寄存器地址偏移命令,
		TxData[0]=AFE94X_WREG|AFE94X_CONFIG8;
		//选择要写入的的寄存器
		TxData[1]=0x00;
		//读取写入寄存器
		TxData[2]=Reg_Val|0x80;  //SET ADDR_OFFSET
		Lpspi_Write(3,TxData);
	   
	   //读取命令,
		TxData[0]=AFE94X_RREG|Rreg;
		//选择要读取的寄存器
		TxData[1]=0x00;
		//开始读取
		Lpspi_Read(3,TxData,RxData);
		//返回寄存器值
	   
	   //清除CONFIG8寄存器地址偏移位,
		TxData[0]=AFE94X_WREG|AFE94X_CONFIG8;
		//选择要写入的的寄存器
		TxData[1]=0x00;
		//读取写入寄存器
		TxData[2]=Reg_Val&0X7F;  //Clear ADDR_OFFSET
		Lpspi_Write(3,TxData);  
   }
    return RxData[2];
}
//写单个芯片寄存器值
void AFE9XX_WriteReg(uint8_t Wreg,uint8_t Data)
{
    uint8_t TxData[3];
	uint8_t Reg_Val=0;
	//寄存器地址小于0X1F
	if(Wreg<=0x1F)
	{
		//写入命令,
		TxData[0]=AFE94X_WREG|Wreg;
		//选择要写入的的寄存器
		TxData[1]=0x00;
		//读取写入寄存器
		TxData[2]=Data;
		Lpspi_Write(3,TxData);
	}
	//寄存器地址大于0X1F
	else
	{
		//获取CONFIG8寄存器Value
		Reg_Val=AFE9XX_GetReg(AFE94X_CONFIG8);
		//写入CONFIG8寄存器地址偏移命令,
		TxData[0]=AFE94X_WREG|AFE94X_CONFIG8;
		//选择要写入的的寄存器
		TxData[1]=0x00;
		//读取写入寄存器
		TxData[2]=Reg_Val|0x80;  //SET ADDR_OFFSET
		Lpspi_Write(3,TxData);
		//写入命令,
		TxData[0]=AFE94X_WREG|Wreg;
		//选择要写入的的寄存器
		TxData[1]=0x00;
		//读取写入寄存器
		TxData[2]=Data;
		Lpspi_Write(3,TxData);
		
		//清除MISC_ANA寄存器地址偏移位,
		TxData[0]=AFE94X_WREG|AFE94X_CONFIG8;
		//选择要写入的的寄存器
		TxData[1]=0x00;
		//读取写入寄存器
		TxData[2]=Reg_Val&0X7F;  //Clear ADDR_OFFSET
		Lpspi_Write(3,TxData);
	}
    
}
//写多个芯片寄存器值
//StartReg 起始寄存器地址
//RegNum 要写的寄存器数量
//*Data  寄存器参数传入
void AFE9XX_WriteMultiReg(uint8_t StartReg,uint8_t RegNum,uint8_t *Data)
{
    uint8_t TxData[52];
    uint8_t i;
    //写入命令,
    TxData[0]=AFE94X_WREGX;
	TxData[1]=StartReg;
    //选择要写入的的寄存器
    TxData[2]=RegNum-1;
    for(i=1;i<=RegNum;i++)
    {
       //将指针数据赋值给Txdata
       TxData[2+i]=*Data;
       //指向下个数据地址
       Data++;
    }
    //最终发送多少个数据
    Lpspi_Write(3+RegNum,TxData);
}
//读多个芯片寄存器值
//StartReg 起始寄存器地址
//RegNum 要写的寄存器数量
//*Data  寄存器参数传出
void AFE9XX_ReadMultiReg(uint8_t StartReg,uint8_t RegNum,uint8_t *Data)
{
    //读取寄存器
    uint8_t TxData[24]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    //读取命令,
    TxData[0]=AFE94X_RREGX;
	TxData[1]=StartReg;
    //选择要写入的的寄存器
    TxData[2]=RegNum-1;
    //最终接收多少个数据
    Lpspi_Read(3+RegNum,TxData,Data);
}
//发送AFE9XX 数据指令 如SDATAC或者RDATAC
//详情见头文件command define部分
void AFE9XX_Command(uint8_t Com)
{
    uint8_t TxData[1];
	TxData[0]=Com;
    Lpspi_Write(1,TxData);
}
//测量固有噪声
//返回噪声值
float AFE9XX_Noise_Test(uint8_t *Rxdata)
{
	//set->pga=1 and Input shorted (for offset or noise measurements) 
	uint8_t Chset[]={0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	uint32_t AD_Value=0;
	float Voltage;
	//停止连续读数据
	AFE9XX_Command(AFE94X_SDATAC);
	//PGA_Gain set 1
	AFE9XX_WriteMultiReg(AFE94X_CH1SET,8,Chset);
	//singel shot mode
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_SHOT_MODE);
	//SET 250SPS
	AFE9XX_WriteReg(AFE94X_CONFIG1,0x06);
	AFE9XX_WriteReg(AFE94X_CONFIG2,0x00);
	//设置内部基准默认基准2.4V
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
	//select single Channel Value
	AD_Value = (Rxdata[3]<<16|Rxdata[4]<<8|Rxdata[5]);
	//MSB=1->采集数据为负数
	if((AD_Value>>16)&0X80)        
	{
		AD_Value = ~AD_Value;
		AD_Value = AD_Value&0X7FFFFF;
	}
	Voltage = (AD_Value*(2.4/8388607))*1000;
	return Voltage;
	
}	
//测量内部测试信号1mv(VREF->2.4V)
void AFE9XX_SINGLE_TEST(uint8_t *Rxdata)
{
	//Select Test sigle
	uint8_t Chset[]={0X05,0X05,0015,0X05,0X05,0X05,0X05,0X05,0X05,0X05};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	//停止连续数据传输
	AFE9XX_Command(AFE94X_SDATAC);
	AFE9XX_WriteMultiReg(AFE94X_CH1SET,8,Chset);
	AFE9XX_WriteReg(AFE94X_CONFIG2,0x10);
	//设置内部基准
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF_2_4V);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
}
//电源测量
float AFE9XX_PWR_Test(uint8_t *Rxdata)
{
	//SET PGA=1 AND 
	uint8_t CHSET[]={0X13,0X13,0X13,0X13,0X13,0X13,0X13,0X13};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	uint32_t AD_Value=0;
	float Voltage;
	//停止连续读数据
	AFE9XX_Command(AFE94X_SDATAC);
	//PGA_Gain set 1
	AFE9XX_WriteMultiReg(AFE94X_CH1SET,8,CHSET);
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_SHOT_MODE);
	AFE9XX_WriteReg(AFE94X_CONFIG1,0x06);
	AFE9XX_WriteReg(AFE94X_CONFIG2,0x00);
	//设置内部基准4V
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF_4V);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
	//select single Channel Value
	AD_Value = (Rxdata[3]<<16|Rxdata[4]<<8|Rxdata[5]);
	if((AD_Value>>16)&0X80)        //MSB=1->采集数据为负数
	{
		AD_Value = ~AD_Value;
		AD_Value = AD_Value&0X7FFFFF;
	}
	Voltage = (AD_Value*(4.0/8388607))*1000;
	return Voltage;
}
void AFE9XX_DCLEAD_OFF(uint8_t *Rxdata)
{
	//Select loff channel
	uint8_t PGA_Gain[]={0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	//停止连续数据传输
	AFE9XX_Command(AFE94X_SDATAC);
	//使能直流导联脱落,设置比较阈值
	AFE9XX_WriteReg(AFE94X_LOFF,AFE94X_COMP_70_30|FLEAD_DC_LEAD);
	//内部比较器上电
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_COMP_PDEN);
	//选择使能导联脱离通道
	AFE9XX_WriteReg(AFE94X_LOFF_SENSN,0XFF);
	AFE9XX_WriteReg(AFE94X_LOFF_SENSP,0XFF);
	//设置内部基准
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF_4V);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
}
//读温度传感器
//返回温度值℃
float AFE9XX_GetTempture(uint8_t *Rxdata)
{
	uint8_t PGA_Gain[]={0X14,0X14,0X14,0X14,0X14,0X14,0X14,0X14};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	uint32_t AD_Value=0;
	float Temp_Value;
	//停止连续读数据
	AFE9XX_Command(AFE94X_SDATAC);
	//PGA_Gain set 1
	AFE9XX_WriteMultiReg(AFE94X_CH1SET,8,PGA_Gain);
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_SHOT_MODE);
		
	AFE9XX_WriteReg(AFE94X_CONFIG1,0x06);
	AFE9XX_WriteReg(AFE94X_CONFIG2,0x00);
	//设置内部基准
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF_2_4V);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
	//select single Channel Value
	AD_Value = (Rxdata[3]<<16|Rxdata[4]<<8|Rxdata[5]);
	if((AD_Value>>16)&0X80)        //MSB=1->采集数据为负数
	{
		AD_Value = ~AD_Value;
		AD_Value = AD_Value&0X7FFFFF;
		
	}
	Temp_Value = (((AD_Value*(2.4/8388607))*1000000-143200)/481)+25;
	return Temp_Value;
}	
//读单个ADC通道电压值(PGA=1)
//AIN_Channel 要读ADC通道
//AFE94X_REF 内部基准选择
//返回单通道ADC电压值(mv)
float AFE9xx_GetValue(uint8_t AIN_CH,uint8_t AFE94X_REF,uint8_t *Rxdata)
{
	uint8_t PGA_Gain[]={0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	uint32_t AD_Value=0;
	float Voltage;
	//停止连续读数据
	AFE9XX_Command(AFE94X_SDATAC);
	//PGA_Gain set 1
	AFE9XX_WriteMultiReg(AFE94X_CH1SET,8,PGA_Gain);
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_SHOT_MODE);
	AFE9XX_WriteReg(AFE94X_CONFIG1,0x06);
	AFE9XX_WriteReg(AFE94X_CONFIG2,0x00);
	//设置内部基准4V
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
	//select single Channel Value
	AD_Value = (Rxdata[3+(AIN_CH*3)]<<16|Rxdata[4+(AIN_CH*3)]<<8|Rxdata[5+(AIN_CH*3)]);
	//MSB=1->采集数据为负数
	if((AD_Value>>16)&0X80)        
	{
		AD_Value = ~AD_Value;
		AD_Value = AD_Value&0X7FFFFF;
	}
	//内部基准选择2.4V
	if(AFE94X_REF==AFE94X_REF_2_4V)
	{
		Voltage = (AD_Value*(2.4/8388607))*1000;
	}
	//内部基准选择4V
	else if(AFE94X_REF==AFE94X_REF_4V)
	{
		Voltage = (AD_Value*(4.0/8388607))*1000;
	}
	//外部基准
	else if(AFE94X_REF == EXT_REF_EN)
	{
		//Voltage = (AD_Value*(LSB)*1000;
	}
	return Voltage;
}
//读多通道ADC电压值(PGA=1)
//AFE94X_REF 基准选择
// * AFE94X_REF_2_4V 
// * AFE94X_REF_4V 
// * AFE94X_EXT_REF
//Voltage 返回多通道ADC电压值(mv)
void AFE94X_GetAllValue(uint8_t AFE94X_REF,uint8_t *Rxdata,float *Voltage)
{
	uint8_t PGA_Gain[]={0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10};
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	uint32_t AD_Value=0;
	//停止连续读数据
	AFE9XX_Command(AFE94X_SDATAC);
	//PGA_Gain set 1,MUX Normal input
	AFE9XX_WriteMultiReg(AFE94X_CH1SET,8,PGA_Gain);
	//单次模式
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_SHOT_MODE);
	//设置采样率
	AFE9XX_WriteReg(AFE94X_CONFIG1,0x06);
	//设置内部基准
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF);
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
	for(int i=0;i<8;i++)
	{
		AD_Value = (Rxdata[3+(i*3)]<<16|Rxdata[4+(i*3)]<<8|Rxdata[5+(i*3)]);
		 //MSB=1->采集数据为负数
		if((AD_Value>>16)&0X80)       
		{
			AD_Value = ~AD_Value;
			AD_Value = AD_Value&0X7FFFFF;
		}
		//内部基准选择2.4V
		if(AFE94X_REF==AFE94X_REF_2_4V)
		{
			Voltage[i] = (AD_Value*(2.4/8388607))*1000;
		}
		//内部基准选择4V
		else if(AFE94X_REF==AFE94X_REF_4V)
		{
			Voltage[i] = (AD_Value*(4.0/8388607))*1000;
		}
		//外部基准
		else if(AFE94X_REF==EXT_REF_EN)
		{
			//Voltage[i] = (AD_Value*(LSB)*1000;
		}
	}
}
//右腿驱动
void TEST_RLD_SINGLE(uint8_t *Rxdata)
{
	uint8_t Txdata[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	uint32_t AD_Value=0;
	//停止连续读数据
	AFE9XX_Command(AFE94X_SDATAC);
	//channel 1-3 PGA_Gain set 1,MUX Normal input
	AFE9XX_WriteReg(AFE94X_CH1SET,AFE94X_PGA_1|MUX_Normal_input);
	AFE9XX_WriteReg(AFE94X_CH2SET,AFE94X_PGA_1|MUX_Normal_input);
	AFE9XX_WriteReg(AFE94X_CH3SET,AFE94X_PGA_1|MUX_Normal_input);
	//channel 1-3 connect RLD
	AFE9XX_WriteReg(AFE94X_RLD_SENSP,0X07);
	AFE9XX_WriteReg(AFE94X_RLD_SENSN,0X07);
	AFE9XX_WriteReg(AFE94X_CONFIG3,0X1C);
	//set channel 4-5
	AFE9XX_WriteReg(AFE94X_CH4SET,AFE94X_CH_PD|AFE94X_PGA_1|MUX_RLD_DRN);
	AFE9XX_WriteReg(AFE94X_CH5SET,AFE94X_CH_PD|AFE94X_PGA_1|MUX_RLD_Test);
	//单次模式
	AFE9XX_WriteReg(AFE94X_CONFIG4,AFE94X_SHOT_MODE);
	//设置采样率
	AFE9XX_WriteReg(AFE94X_CONFIG1,0x06);
	//设置内部基准
	AFE9XX_WriteReg(AFE94X_CONFIG3,INT_REF_EN|AFE94X_REF_2_4V );
	//启动转换
	AFE9XX_Command(AFE94X_START);
	//连续读数据
	AFE9XX_Command(AFE94X_RDATAC);
	//等待DRDY
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12));
	Lpspi_Read(27,Txdata,Rxdata);
}

到了这里,关于64kSPS、低功耗、多通道同步、24 位ADC生物电势测量的模拟前端AFE9XX的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32入门笔记08_ADC模数转换器+案例: ADC单通道&ADC多通道

    ADC(Analog-Digtal Converter) 模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量, 建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC, 1us转换时间 输入电压范围: 0~3.3V, 转换结果范围: 0~4095 18个输入通道, 可测量16个外部和2个内部信号源 规则组和注入组

    2024年02月04日
    浏览(52)
  • ADC噪声全面分析 -02- ADC 噪声测量方法和相关参数

    在解释如何测量 ADC 噪声之前,重要的是要了解,当您查看 ADC 数据表规格时,相关指标参数表征对象是 ADC,而不是设计的电子系统。因此,ADC 制造商测试 ADC 噪声的方式和测试系统本身应该展示 ADC 的能力,而不是测试系统的限制。 因此,在不同系统或不同条件下使用 ADC

    2024年02月07日
    浏览(39)
  • STM32双路ADC注入通道和规则通道采样

    电机控制使用四路注入通道采集,参考ST官方库,使用定时器10us触发一次,使用ADC1和ADC2各2路注入通道。 需要一路ADC进行规则采样油门信号,使用中断的话会和注入通道中断放在同一个函数里面 ,我不喜欢,所以使用了DMA中断。 PreKnowledge: 规则通道:最多16个规则通道,采样

    2024年04月14日
    浏览(48)
  • STM32ADC单通道转换

    ADC功能初始化主要分三部分,GPIO初始化、ADC模式初始化与NVIC初始化。 1.1初始化GPIO 1.2 初始化ADC模式 1.3 初始化NVIC 中断函数命名为ADC1_2_IRQHandler即可,换ADC通道的话名字也要换。

    2024年03月09日
    浏览(65)
  • 如何使用ADC测量我们设备的锂电池电压

    电路设计: 首先当我们想知道设备还有多少电的时候,我们就需要有一个电压监测电路  通常我们会想到通过两个电阻分压的方式来获取电压,通过两个电阻分压,连接到单片机的ADC引脚。ADC测到的电压,就是锂电池电压的一半 因为锂电池的电压范围大概在2.7V到4.2V之间,所

    2024年02月01日
    浏览(43)
  • stm32_ADC电源、通道、工作模式

    0、ADC功能框图 1、ADC的电源 1.1、工作电源 VSSA=VSS,VDDA=VDD,简单来说,通常stm32是3.3V,ADC的工作电源也是3.3V; 1.2、参考电压 VREF+和VREF-并不一定引出,取决于封装,如果没有引出则VREF+连接到VDDA、VREF-连接到VSSA。 在不要求精度的情况下,VREF+可直接接到VDDA,想要精确测量,

    2024年02月12日
    浏览(41)
  • STM32 hal库使用笔记(五)ADC—单通道/双通道DMA传输

    实现目的:利用ADC采集光敏传感器/烟雾传感器的值,并利用串口打印 实验平台:正点原子精英版 一、简介 1.DMA的介绍 参考:STM32 hal库使用笔记(四)DMA—内存到内存/内存到外设_乱码小伙的博客-CSDN博客 2.ADC简介      ADC(Analog-Digital Converter)模拟-数字转换器 ADC可以将引脚

    2024年02月03日
    浏览(59)
  • ES7210 高性能四通道音频ADC

     ES7210  是一款用于麦克风阵列应用的高性能、低功耗 4 通道音频模数转换器,同时具备声学回声消除 (AEC) 功能,非常适合音乐和语音应用。 该设备支持标准音频时钟(64Fs, 128Fs, 256Fs, 384Fs, 512Fs等),USB时钟 (12/24 MHz),以及一些常见的非标准音频时钟(25mhz, 26mhz等)。 根据串行音

    2024年01月18日
    浏览(41)
  • STM32 ADC单/多通道采样+DMA搬运

    通过介绍我们可以了解到,ADC是12位的转换器,所以采样值范围是0~4095。18个通道可同时进行转换,也可以单独转换某个通道。 使用ADC的流程应为: 初始化IO口。 我这里使用的是PA1进行采样,也就是ADC1的通道1 初始化ADC。 转换、获取采样值。 多通道的时候我们一般用DMA来搬

    2024年02月14日
    浏览(51)
  • 实验(六):ADC应用:独立模式单通道采集实验

    实验目的: 1. 学习对ADC基础功能的使用; 2. 掌握KEIL5的仿真与调试。 任务: 1.   根据要求编写程序,并写出原理性注释; 2. 将检查程序运行的结果,分析一下是否正确; 3. 完成所建工程的验证调试。 贴片滑动变阻器的动触点通过连接至STM32 芯片的ADC 通道引脚。当我们使

    2024年02月15日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包