AD7606使用指南与参考代码

2024/10/29 V1.0:代码仅供参考,暂时没有上板验证,部分功能待完善,也有部分功能可以去除,比如硬件设定好采样率,不考虑省电模式。如有错误,还请指正,谢谢!

        使用的是GD32F407芯片,使用SPI串行模式进行读取数据,对于并行操作,可以参考写的另外一篇,里面也对重要的管脚进行了简单说明,以官方手册为准。自己可以根据实际需求对其进行移植,主要是对Pin、GPIO、spi初始化进行更改。https://blog.youkuaiyun.com/magicssss/article/details/143205014icon-default.png?t=O83Ahttps://blog.youkuaiyun.com/magicssss/article/details/143205014

        使用SPI串行模式读取数据,该模式下AD7606_Pin6接逻辑高;DB[15:9] and DB[6:0]需要接地;DB7是1234通道数据先输出,DB8是5678通道数据先输出,通常只需要接一个输出口即可,如果接DB7,则输出数据依次为12345678通道,如果接DB8则输出顺序为56781234。对于AD7606,只有数据输出,没有数据输入,因此MCU的MOSI管脚不接。

        SPI模式下的时序如下,SPI工作在模式3,空闲时刻SCLK为高电平,时钟上升沿采集数据线上的信号,下降沿将移位寄存器的数据放置到信号线上。

宏定义部分

        为了方便更改,关键的控制pin尽量链接到同名的GPIO_Port,做不到就老实更改初始化的部分;注意开启自己使用的SPIx时钟源。

#include "gd32f4xx.h"                   // Device header
#include "systick.h"

uint16_t AD7606_Data[8];

//尽量将控制Pins和数据Pins分别接到同名GPIO口
#define		AD7606_SPI							SPI1
#define		AD7606_CtrlPort						GPIOD			//其它的必要控制端口
#define		AD7606_DataPort						GPIOB			//SPI相关端口以及输入信号
	
//GPIOB
#define		AD7606_DoutA						GPIO_PIN_14		//MISO
#define		AD7606_SCLK							GPIO_PIN_13		//SCLK
#define		AD7606_BUSY							GPIO_PIN_15		//转换状态信号;输入0:转换结束;1:正在转换
//GPIOD
#define		AD7606_STBY							GPIO_PIN_1		//下电模式选择;低电平有效;默认电平:1
#define		AD7606_OS0							GPIO_PIN_2      //默认电平:0
#define		AD7606_OS1							GPIO_PIN_3      //默认电平:0
#define		AD7606_OS2							GPIO_PIN_4      //默认电平:0
#define		AD7606_CS							GPIO_PIN_5     //读取和片选控制信号;低电平有效;默认电平:1
#define		AD7606_RESET						GPIO_PIN_6     //复位信号;高电平有效;默认电平:0
#define		AD7606_RANG							GPIO_PIN_7      //输入电压范围选择;0:+-5V;1:+-10V
#define		AD7606_CONVST_AB					GPIO_PIN_8      //开始转换信号;高电平有效;默认电平:0

//用于设置over sampling率
#define		AD7606_SetOS0()						gpio_bit_set(AD7606_CtrlPort, AD7606_OS0)
#define		AD7606_SetOS1()						gpio_bit_set(AD7606_CtrlPort, AD7606_OS1)
#define		AD7606_SetOS2()						gpio_bit_set(AD7606_CtrlPort, AD7606_OS2)
#define		AD7606_ResetOS0()					gpio_bit_reset(AD7606_CtrlPort, AD7606_OS0)
#define		AD7606_ResetOS1()					gpio_bit_reset(AD7606_CtrlPort, AD7606_OS1)
#define		AD7606_ResetOS2()					gpio_bit_reset(AD7606_CtrlPort, AD7606_OS2)

初始化函数

/*!
    \brief        AD7606初始化配置
    \param[in]    无
    \param[out]   无
    \retval       无
*/
void AD7606_Init(void)
{
	//开启外设时钟,根据走线进行更改
	rcu_periph_clock_enable(RCU_GPIOB | RCU_GPIOD);
	rcu_periph_clock_enable(RCU_SPI1);
	
	//反馈信号引脚配置
	gpio_mode_set(AD7606_DataPort, GPIO_MODE_INPUT, GPIO_PUPD_NONE, AD7606_BUSY);
	
	//SCLK和MISO(DoutA)配置
	gpio_af_set(AD7606_DataPort, GPIO_AF_5, AD7606_DoutA | AD7606_SCLK);
	gpio_mode_set(AD7606_DataPort, GPIO_MODE_AF, GPIO_PUPD_NONE, AD7606_DoutA | AD7606_SCLK);
	gpio_output_options_set(AD7606_DataPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AD7606_DoutA | AD7606_SCLK);
	
	//输出控制信号:默认低电平的信号
	gpio_mode_set(AD7606_CtrlPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, AD7606_RANG | AD7606_OS0 | AD7606_OS1 | AD7606_OS2 | AD7606_RESET | AD7606_CONVST_AB);
	gpio_output_options_set(AD7606_CtrlPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AD7606_RANG | AD7606_OS0 | AD7606_OS1 | AD7606_OS2 | AD7606_RESET | AD7606_CONVST_AB);
	
	//输出控制信号:默认高电平的信号
	gpio_mode_set(AD7606_CtrlPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, AD7606_STBY | AD7606_CS);
	gpio_output_options_set(AD7606_CtrlPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AD7606_STBY | AD7606_CS);
	
	spi_parameter_struct spi_initstructure;
	spi_initstructure.device_mode = SPI_MASTER;
	spi_initstructure.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
	spi_initstructure.frame_size = SPI_FRAMESIZE_16BIT;
	spi_initstructure.nss = SPI_NSS_SOFT;
	spi_initstructure.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;		//模式3
	spi_initstructure.prescale = SPI_PSC_32;
	spi_initstructure.endian = SPI_ENDIAN_MSB;
	
	spi_init(AD7606_SPI, &spi_initstructure);
	
	spi_enable(AD7606_SPI);
	
	//上电复位AD7606芯片
	gpio_bit_set(AD7606_CtrlPort, AD7606_RESET);
	delay_1ms(1);
	gpio_bit_reset(AD7606_CtrlPort, AD7606_RESET);
}

复位函数

/*!
	\brief        AD7606复位
    \param[in]    无				  
    \param[out]   无
    \retval       无
*/
void AD7606_Reset(void)
{
	gpio_bit_set(AD7606_CtrlPort, AD7606_RESET);
	
	delay_1ms(1);			//最小50 ns
	
	gpio_bit_reset(AD7606_CtrlPort, AD7606_RESET);
}

采样率设置函数

/*!
    \brief        AD7606过采样选择
    \param[in]    OS: 过采样率选择
                  可选择参数:0、2、4、8、16、32、64
    \param[out]   无
    \retval       无
*/
void AD7606_SetOversampling(uint8_t OS)
{
    switch(OS)
    {
        case 0:  // 000
            AD7606_ResetOS2(); 
            AD7606_ResetOS1(); 
            AD7606_ResetOS0();
            break;

        case 2:  // 001
            AD7606_ResetOS2(); 
            AD7606_ResetOS1(); 
            AD7606_SetOS0();
            break;

        case 4:  // 010
            AD7606_ResetOS2(); 
            AD7606_SetOS1(); 
            AD7606_ResetOS0();
            break;

        case 8:  // 011
            AD7606_ResetOS2(); 
            AD7606_SetOS1(); 
            AD7606_SetOS0();
            break;

        case 16: // 100
            AD7606_SetOS2(); 
            AD7606_ResetOS1(); 
            AD7606_ResetOS0();
            break;

        case 32: // 101
            AD7606_SetOS2(); 
            AD7606_ResetOS1(); 
            AD7606_SetOS0();
            break;

        case 64: // 110
            AD7606_SetOS2(); 
            AD7606_SetOS1(); 
            AD7606_ResetOS0();
            break;

        default: // default case
            AD7606_ResetOS2(); 
            AD7606_ResetOS1(); 
            AD7606_ResetOS0();
            break;
    }
}

启动与结束转换函数

/*!
    \brief        AD7606开始转换
	\param[in]    无
    \param[out]   无
    \retval       无
*/
void AD7606_StartConv(void)
{
	gpio_bit_set(AD7606_CtrlPort, AD7606_CONVST_AB);
}

/*!
    \brief        AD7606结束转换
	\param[in]    无
    \param[out]   无
    \retval       无
*/
void AD7606_StopConv(void)
{
	gpio_bit_reset(AD7606_CtrlPort, AD7606_CONVST_AB);
}

设置下电模式函数

/*!
    \brief        ADC省电模式选择
	\param[in]    Mode:
				  1:备用--->该模式下最大工作电流8 mA
					 STBY=0; RANG=1

				  0:下电--->该模式下最大工作电流6 μA,需要reset才能退出
					  STBY=0; RANG=1
    \param[out]   无
    \retval       无
*/
void AD7606_SwitchPowerDownMode(uint8_t Mode)
{
    switch(Mode)
    {
        case 1  : 
            gpio_bit_reset(AD7606_CtrlPort, AD7606_STBY); 
            gpio_bit_set(AD7606_CtrlPort, AD7606_RANG);
            break; 

        case 0  : 
            gpio_bit_reset(AD7606_CtrlPort, AD7606_STBY); 
            gpio_bit_reset(AD7606_CtrlPort, AD7606_RANG);
            break; 

        default : 
            gpio_bit_reset(AD7606_CtrlPort, AD7606_STBY); 
            gpio_bit_set(AD7606_CtrlPort, AD7606_RANG);
            break; 
    }
}

读取转换结果函数

        该函数仅读取转换的结果,未进行转换!!!!!!!!

/*!
    \brief        AD7606读取数据
	\param[in]    无
    \param[out]   数组指针
    \retval       并行模式下读取数据
*/
uint16_t* AD7606_ReadData(void)
{	
	//开始单次转换
	AD7606_StartConv();
	
	//等待转换结束
	while(gpio_input_bit_get(AD7606_CtrlPort, AD7606_BUSY));
	
	//结束转换准备读取数据寄存器中的数据
	AD7606_StopConv();
	
	//读取数据:SPI模式读取数据
	for(uint8_t i = 0; i < 8; i ++)
		{
			gpio_bit_reset(AD7606_CtrlPort, AD7606_CS);
						
			// 确保 SPI 发送缓冲区为空,可以发送数据
			while (RESET == spi_i2s_flag_get(AD7606_SPI, SPI_FLAG_TBE));

			// 向 SPI 发送 16 位数据以启动读取(通常为 dummy data,比如 0xFFFF)
			spi_i2s_data_transmit(AD7606_SPI, 0xFFFF);
			
			// 等待 SPI 接收缓冲区非空,表示已经接收到数据
			while (RESET == spi_i2s_flag_get(AD7606_SPI, SPI_FLAG_RBNE));
			
			// 读取 SPI 接收缓冲区中的 16 位数据
			AD7606_Data[i] = spi_i2s_data_receive(AD7606_SPI);
			
			delay_1ms(1);
			
			gpio_bit_set(AD7606_CtrlPort, AD7606_CS);			
		}
	
	return AD7606_Data;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值