STM32开发 | AD7606并行多路采集数据

1、原理图设计参考

在这里插入图片描述

2、引脚说明

引脚说明
AVCC模拟电源电压 4.75 V至5.25 V
AGND模拟地
OS0/OS1/OS2过采样模式选择
PAR/SER/BYTE并行/串行/并行字节接口选择
STBY待机模式
RANGE模拟输入范围选择(±10V 或 ±5V)
CONVST-A / CONVST-B开始转换引脚,一般并联在具有PWM功能的引脚上
RESET复位引脚
RD/SCLK并行接口模式为读取控制引脚(RD) / 串行接口模式下为时钟输入(SCLK)
CS片选,低电平有效
BUSY输出繁忙,低电平时可读取数据
FRSTDATA数字输出,表示何时回读数据
REF基准电压选择
DB0~DB1516位读取数据输出

3、参考代码

#include <stdio.h>
#include <string.h>
#include "stm32f10x.h"
#include "ad7606.h"

//AD7606引脚配置
void AD7606_GPIOConfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
	// 允许修改RTC和后备寄存器
	PWR_BackupAccessCmd(ENABLE);
	//关闭外部低速时钟,PC14+PC15可以用作普通IO
   	RCC_LSEConfig(RCC_LSE_OFF); 
   	//关闭入侵检测功能,PC13作为普通IO
   	BKP_TamperPinCmd(DISABLE);
	
	//----------------------------- AD7606 DATA GPIO ------------------------------
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	// 禁止修改RTC和后备寄存器
	PWR_BackupAccessCmd(DISABLE);
	//------------------------------------ End ------------------------------------

	//ADCS->PB3, OS0->PB7, OS1->PB6, OS2->PB5
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	//ADREAD->PD2
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	// COVA->PA8, COVB->PA11, ADRESET->PA13
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//ADFIRST->PA14
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//过采样率设置
void AD7606_SetOS(AD7606_OS_E ucOS)
{
	switch (ucOS)
	{
		case AD_OS_NO: OS2_0(); OS1_0(); OS0_0(); break;
		case AD_OS_X2: OS2_0(); OS1_0(); OS0_1(); break;
		case AD_OS_X4: OS2_0(); OS1_1(); OS0_0(); break;
		case AD_OS_X8: OS2_0(); OS1_1(); OS0_1(); break;
		case AD_OS_X16: OS2_1(); OS1_0(); OS0_0(); break;
		case AD_OS_X32: OS2_1(); OS1_0(); OS0_1(); break;
		case AD_OS_X64: OS2_1(); OS1_1(); OS0_0(); break;
		default: OS2_0(); OS1_0(); OS0_0(); break;
	}
}

//AD7606初始化
void AD7606Initialization(void)
{
	delay_ms(1);
	AD7606_RESET_0
	AD7606_SetOS(AD_OS_NO);
	AD7606_CS_0
	AD7606_RD_1
	delay_ms(1);
	AD7606Reset();
}

//AD7606重置
void AD7606Reset(void)
{
	AD7606_RESET_1;
	delay_us(1);
	AD7606_RESET_0;
	delay_us(1);
}

//读取数据
void AD7606ReadSample(void)
{
	uint8_t i;
	char ad_buffer[20] = {0};
	short ad_value[4] = {0};

	for(i = 0; i < 4; i++)
	{
		AD7606_RD_0
		__NOP();
		
		ad_buffer[i] = READ_AD_DATA;
		
		AD7606_RD_1;
		__NOP();
	}
	sprintf(ad_buffer, "%d %d %d %d ", ad_buffer[0], ad_buffer[1], ad_buffer[2], ad_buffer[3]);
	USART2_SendStr(ad_buffer);
}

//频率设置
void PWM_ModeConfig(uint32_t frequency)
{
	uint32_t arr_value, psc_value;

    //初始化结构体
	GPIO_InitTypeDef	GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

    //开启端口时钟以及复位时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
    //开启定时器时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    //引脚配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/*
	 * PWM(Hz) = 72MHz / ((ARR + 1) * (PSC + 1))
	 * ARR(arr_value) -> TIM_Period
	 * PSC(psc_value) -> TIM_Prescaler
	 */
	psc_value = 72 - 1;
	arr_value = SystemCoreClock / (psc_value + 1) / frequency - 1;
	
    //计数值,TIM_Period + 1
	TIM_TimeBaseStructure.TIM_Period = arr_value;
    //预分频值,TIM_Perscaler + 1
	TIM_TimeBaseStructure.TIM_Prescaler = psc_value;
    //时钟分频因子
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    //计数器计数模式,向上计数
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    //初始化定时器
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    //PWM模式
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    //输出使能
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    //输出通道电平极性配置
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

    //输出比较通道1
	TIM_OCInitStructure.TIM_Pulse = 4;
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

    //输出比较通道4
	TIM_OCInitStructure.TIM_Pulse = 4;
	TIM_OC4Init(TIM1, &TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

    //允许或禁止在定时器工作时向ARR的缓冲器中写入新值
	TIM_ARRPreloadConfig(TIM1, ENABLE);

    //使能定时器
	TIM_Cmd(TIM1, ENABLE);

	//主输出使能,只有在使用高级定时器时有效
	TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

//busy中断配置
void AD7606_Busy_IRQ(void)
{
	EXTI_InitTypeDef   EXTI_InitStructure;
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;

	/* Enable GPIOA clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//禁用调试接口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource15);

	EXTI_InitStructure.EXTI_Line = EXTI_Line15;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

4、头文件

#ifndef _AD7606_H_
#define _AD7606_H_

#include "stm32f10x.h"

#define READ_AD_DATA   GPIO_ReadInputData(GPIOC)

#define OS0_1()			GPIO_SetBits(GPIOB, GPIO_Pin_6);
#define OS0_0()			GPIO_ResetBits(GPIOB, GPIO_Pin_6);
#define OS1_1()			GPIO_SetBits(GPIOB, GPIO_Pin_5);
#define OS1_0()			GPIO_ResetBits(GPIOB, GPIO_Pin_5);
#define OS2_1()			GPIO_SetBits(GPIOB, GPIO_Pin_4);
#define OS2_0()			GPIO_ResetBits(GPIOB, GPIO_Pin_4);

#define AD7606_CS_1				GPIO_SetBits(GPIOB, GPIO_Pin_3);
#define AD7606_CS_0				GPIO_ResetBits(GPIOB, GPIO_Pin_3);
#define AD7606_RD_1				GPIO_SetBits(GPIOD, GPIO_Pin_2);
#define AD7606_RD_0				GPIO_ResetBits(GPIOD, GPIO_Pin_2);


#define AD7606_RESET_1			GPIO_SetBits(GPIOA, GPIO_Pin_13);
#define AD7606_RESET_0			GPIO_ResetBits(GPIOA, GPIO_Pin_13);
#define AD7606_CONVST_1			GPIO_SetBits(GPIOA, GPIO_Pin_8 | GPIO_Pin_11);
#define AD7606_CONVST_0			GPIO_ResetBits(GPIOA, GPIO_Pin_8 | GPIO_Pin_11);

#define AD7606_BUSY_STATE			GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15)
#define AD7606_FRSTDATA_STATE		GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)

typedef enum
{
	AD_OS_NO = 0,
	AD_OS_X2 = 1,
	AD_OS_X4 = 2,
	AD_OS_X8 = 3,
	AD_OS_X16 = 4,
	AD_OS_X32 = 5,
	AD_OS_X64 = 6
	
}AD7606_OS_E;

void AD7606Initialization(void);
void AD7606Reset(void);
void AD7606ReadSample(void);
void AD7606_GPIOConfig(void);
void AD7606_PWM_ModeConfig(uint32_t frequency);
void AD7606_SetOS(uint8_t _ucOS);
void AD7606_Busy_IRQ(void);
void AD7606_IRQ_Disable(void);
void AD7606_IRQ_Enable(void);

#endif /*_AD7606_H*/

串口发送可查看此篇文章

5、应用

#include "stm32f10x.h"
#include "ad7606.h"

int main(void)
{	
	AD7606Initialization();
	//频率设置20k
	AD7606_PWM_ModeConfig(20000);
	//设置并进入中断
	AD7606_Busy_IRQ();

	while(1)
	{

	}
}

//中断服务函数
void EXTI15_10_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line15) != RESET)
	{
		AD7606ReadSample();
    	EXTI_ClearITPendingBit(EXTI_Line15);
	}
}

6、中文参考资料下载

链接:https://pan.baidu.com/s/1l4AseVGhHjZcd0mLW5btLQ
提取码:a0ko

  • 13
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值