数模转换器(ADC):AD7606+GD32F407固件参考代码

该文章已生成可运行项目,

项目上使用到该转换芯片,写点笔记,希望对大家有帮助。我接触这个芯片也就几天,整体来说,没寄存器,很好控制。但是我的代码仅提供思路,现在没有板子,不能验证。刚入职的硬件开发岗萌新,先写这么多,有机会再更新,如有错误地方请各位指正,谢谢。

1. 芯片关键参数介绍

        AD7606支持8通道模拟输入;7种过采样率设置;SPI/QSPI™/MICROWIRE™/DSP多种通信协议;模拟输入范围选择;参考电压选择。

  •   Pin OS0~PinOS2用于控制过采样率选择,OS2是MSB控制位,OS0是LSB控制位。可以根据需要选择硬件或者软件的方式控制过采样,真值表如下:

  •  Pin6(PAR_N/SER/BYTE SEL)管脚用于选择通信方式,我这里用的是并行方式,直接将管脚接地即可。数据吞吐量大,GPIO口不够用则改用字节传输或者串行模式。
  • Pin7(STBY_N)用于选择省电模式,不在意功耗直接拉高即可,如果需要切换芯片工作模式,则需要配合使用RANG引脚。
  • Pin8(RANG)用于选择输入电压范围,RANG=0,输入电压范围是±5 V;RANG=1,输入电压范围是±10 V。
  • Pin9和Pin10(CONVST A, CONVST B)用于控制转换选择,A对应1234,B对应5678,通常直接将AB短接,一起控制,逻辑1表示开始转换,逻辑0表示未转换。
  • Pin12(RD_N/SCLK),并行模式下是读数据控制信号,低电平有效;串行模式下是时钟输出控制引脚。
  • Pin13(CS_N),片选引脚,并行模式下通常将其与Pin12短接,低电平有效。
  • Pin14(BUSY),在CONVST A, CONVST B的上升沿跳转为高电平,表示开始转换;所有通道转换结束后才转为低电平;下降沿表明数据已存储在输出寄存器。
  • Pin15(FRSTDATA):目前我觉得没用的引脚

    2. 时序分析 

        首先是读数据的时机,可以在转换结束之后在读取本次转换结果,也可以在转换的过程中读取上一次的转换结果,分别对应下面图片中的Figure 2和Figure 3。区别在于前者在BUSY为低之后才拉低CS管脚开始读数据,而后者则是在BUSY期间就拉低了CS管脚进行读数据。注意:手册提到,在BUSY高时读取的任何数据必须在BUSY下降沿发生之前完成。当BUSY信号高时,CONVST A或CONVST B上的上升沿没有影响。

        下面是并行模式下读取数据的时序图,为了方便,直接将CS和RD管脚短接,一起控制数据读取过程。另外,根据该时序图和手册说明,FRSTDATA仅表示通道1的数据读取情况。

3. 参考代码

 #管脚定义,根据自己的电路图做调整

uint16_t ADC_Data[8];

//尽量将控制Pins和数据Pins分别接到同名GPIO口
#define		ADC_DataPort					GPIOB			//16 bits并行数据端口
#define		ADC_CtrlPort					GPIOC			//其它的必要控制端口

//关键控制Pins
#define		ADC_RANG						GPIO_PIN_9		//输入电压范围选择;0:+-5V;1:+-10V
#define		ADC_STBY						GPIO_PIN_8		//下电模式选择;低电平有效;默认电平:1
#define		ADC_OS0							GPIO_PIN_7      //默认电平:0
#define		ADC_OS1							GPIO_PIN_6      //默认电平:0
#define		ADC_OS2							GPIO_PIN_5      //默认电平:0
#define		ADC_RD							GPIO_PIN_4      //读取和片选控制信号;低电平有效;默认电平:1
#define		ADC_RESET						GPIO_PIN_3      //复位信号;高电平有效;默认电平:0
//#define		ADC_FRSTDATA					GPIO_PIN_2      //低电平有效;默认电平:0
#define		ADC_BUSY						GPIO_PIN_1      //转换状态信号;输入0:转换结束;1:正在转换
#define		ADC_CONVST_AB					GPIO_PIN_0      //开始转换信号;高电平有效;默认电平:0

//用于设置over sampling率
#define		ADC_SetOS0()					gpio_bit_set(ADC_CtrlPort, ADC_OS0)
#define		ADC_SetOS1()					gpio_bit_set(ADC_CtrlPort, ADC_OS1)
#define		ADC_SetOS2()					gpio_bit_set(ADC_CtrlPort, ADC_OS2)
#define		ADC_ResetOS0()					gpio_bit_reset(ADC_CtrlPort, ADC_OS0)
#define		ADC_ResetOS1()					gpio_bit_reset(ADC_CtrlPort, ADC_OS1)
#define		ADC_ResetOS2()					gpio_bit_reset(ADC_CtrlPort, ADC_OS2)

#过采样率设置

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

        case 2:  // 001
            ADC_ResetOS2(); 
            ADC_ResetOS1(); 
            ADC_SetOS0();
            break;

        case 4:  // 010
            ADC_ResetOS2(); 
            ADC_SetOS1(); 
            ADC_ResetOS0();
            break;

        case 8:  // 011
            ADC_ResetOS2(); 
            ADC_SetOS1(); 
            ADC_SetOS0();
            break;

        case 16: // 100
            ADC_SetOS2(); 
            ADC_ResetOS1(); 
            ADC_ResetOS0();
            break;

        case 32: // 101
            ADC_SetOS2(); 
            ADC_ResetOS1(); 
            ADC_SetOS0();
            break;

        case 64: // 110
            ADC_SetOS2(); 
            ADC_SetOS1(); 
            ADC_ResetOS0();
            break;

        default: // default case
            ADC_ResetOS2(); 
            ADC_ResetOS1(); 
            ADC_ResetOS0();
            break;
    }
}

#AD7606初始化

/*!
    \brief        ADC初始化配置
    \param[in]    无
    \param[out]   无
    \retval       无
*/
void AD7606_Init(void)
{
	rcu_periph_clock_enable(ADC_DataPort | ADC_CtrlPort);
	
	//数据输入引脚配置
	gpio_mode_set(ADC_DataPort, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_ALL);
	
	//输入反馈信号
	gpio_mode_set(ADC_CtrlPort, GPIO_MODE_INPUT, GPIO_PUPD_NONE, ADC_BUSY);
	
	//输出控制信号:默认低电平的信号
	gpio_mode_set(ADC_CtrlPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, ADC_RANG | ADC_OS0 | ADC_OS1 | ADC_OS2 | ADC_RESET | ADC_CONVST_AB);
	gpio_output_options_set(ADC_CtrlPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ADC_RANG | ADC_OS0 | ADC_OS1 | ADC_OS2 | ADC_RESET | ADC_CONVST_AB);
	
	//输出控制信号:默认高电平的信号
	gpio_mode_set(ADC_CtrlPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, ADC_STBY | ADC_RD);
	gpio_output_options_set(ADC_CtrlPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ADC_STBY | ADC_RD);
	
	//上电复位ADC芯片
	gpio_bit_set(ADC_CtrlPort, ADC_RESET);
	delay_1ms(1);
	gpio_bit_reset(ADC_CtrlPort, ADC_RESET);
}

#AD7606转换的开始和结束

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

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

#省电模式选择

void AD7606_SwitchPowerDownMode(uint8_t Mode)
{
    switch(Mode)
    {
        case 1  : 
            gpio_bit_reset(ADC_CtrlPort, ADC_STBY); 
            gpio_bit_set(ADC_CtrlPort, ADC_RANG);
            break; 

        case 0  : 
            gpio_bit_reset(ADC_CtrlPort, ADC_STBY); 
            gpio_bit_reset(ADC_CtrlPort, ADC_RANG);
            break; 

        default : 
            gpio_bit_reset(ADC_CtrlPort, ADC_STBY); 
            gpio_bit_set(ADC_CtrlPort, ADC_RANG);
            break; 
    }
}

#读取转换结果

uint16_t* AD7606_ReadData(void)
{	
	//开始单次转换
	AD7606_StartConv();
	
	//等待转换结束
	while(gpio_input_bit_get(ADC_CtrlPort, ADC_BUSY));
	
	//结束转换准备读取数据寄存器中的数据
	AD7606_StopConv();
	
	//读取数据:并行模式读取数据
	for(uint8_t i = 0; i < 8; i ++)
		{
            //这两个延时有点长了,或许不需要延时也许,30ns的时间内即可读完一个通道数据
			gpio_bit_reset(ADC_CtrlPort, ADC_RD);
            //delay_1ms(1);
			ADC_Data[i] = gpio_input_port_get(ADC_DataPort);
			delay_1ms(1);            
			gpio_bit_set(ADC_CtrlPort, ADC_RD);			
		}
	
	return ADC_Data;
}
/*!
	\brief        ADC复位
    \param[in]    无				  
    \param[out]   无
    \retval       无
*/
void AD7606_Reset(void)
{
	gpio_bit_set(ADC_CtrlPort, ADC_RESET);
	
	delay_1ms(1);			//最小50 ns
	
	gpio_bit_reset(ADC_CtrlPort, ADC_RESET);
}

本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值