STM32F4 ADC (单通道采集、多通道采集、双重交错模式、规则同步模式、三重模式)

这篇博客主要展示了如何在STM32F4微控制器上实现ADC的多种采集模式,包括单通道、多通道、双重交错模式、规则同步模式以及三重模式,并提供了详细的C语言程序示例,适用于电源电压测量等应用。
摘要由CSDN通过智能技术生成

话不多说,直接上程序,详情请看注释

//-------------.c 文件----------------------------------------------------------------------------------------------------------------------------------

 

#include "adc.h"
#include "usart.h"

__IO uint32_t ADC_TripleModeConveredValue[3];

__IO uint16_t ADC_MultiModeConveredValue[8];

__IO uint16_t RegSimultModeConveredValue[4];

__IO uint32_t ADC_DualModeConveredValue;

__IO uint16_t ADC_VBATMeasureValue;

double Single_ADCx_Value = 0;

//DMA2(CH0 CH4)-------------->ADC1
//DMA2(CH2 CH3)-------------->ADC2
//DMA2(CH0 CH1)-------------->ADC3

单通道采集

#if defined  (ADC_Single_Channel) //单通道采集

void ADC_Single_Config(void)
{
	ADC_InitTypeDef        ADC_InitStructure;
	ADC_CommonInitTypeDef  ADC_CommonInitStructure;
	GPIO_InitTypeDef       GPIO_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_Single_GPIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_Single_ADCx,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin  = ADC_Single_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;   //模拟输入
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(ADC_Single_PORT,&GPIO_InitStructure);
	
	ADC_CommonInitStructure.ADC_Mode      = ADC_Mode_Independent; //独立模式
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;   //ADC最大时钟是36MHz 故要在这里分频 84/4 = 21
	ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_Disabled;   //只有在双重模式或者三重模式时才会设置
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟,仅适用于双重模式或者三重模式
	ADC_CommonInit(&ADC_CommonInitStructure);
	
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;             //使能连续转换
	ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_NbrOfConversion    = 1;                  //转换通道
	ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;       //分辨率: 12位
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //失能扫描模式,多通道采集才会用得到
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
//	ADC_InitStructure.ADC_ExternalTrigConv   = //采用软件触发,故这里不需要
	ADC_Init(Single_ADCx,&ADC_InitStructure);
	
	//配置ADCx 通道转换顺序和转换周期
	ADC_RegularChannelConfig(Single_ADCx,ADC_Single_Channel_x,1,ADC_SampleTime_56Cycles);
	
	//使能ADCx转换结束中断,在每次转换结束之后读取数据
	ADC_ITConfig(Single_ADCx,ADC_IT_EOC,ENABLE);
	
	//使能ADCx
	ADC_Cmd(Single_ADCx,ENABLE);
	
	//开启软件转换
	ADC_SoftwareStartConv(Single_ADCx);

}
void ADC_Single_NVIC_Config(void)
{
	NVIC_InitTypeDef       NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_InitStructure.NVIC_IRQChannel    = ADC_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
}


void ADC_IRQHandler(void)
{
	uint16_t val;
	if(ADC_GetFlagStatus(Single_ADCx,ADC_FLAG_EOC) == SET)
	{
		ADC_ClearITPendingBit(Single_ADCx,ADC_FLAG_EOC);
		
		val = ADC_GetConversionValue(Single_ADCx);
		Single_ADCx_Value = (double)val*3.3/4096;
		
		printf("\r\nADCx single value : %lf\n\r",Single_ADCx_Value);
	
	}
}

 

多通道采集

#elif defined (ADC_Multi_Channel) 
//多通道采集,采集8个通道的数据

void Multi_ADC_GPIO_Config(void)
{
	GPIO_InitTypeDef       GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
	                               GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;     //或者GPIO_Mode_AIN
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

}

void ADC_Multi_Config(void)
{
	ADC_InitTypeDef        ADC_InitStructure;
	ADC_CommonInitTypeDef  ADC_CommonInitStructure;
	DMA_InitTypeDef        DMA_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_x,ENABLE);
	
	DMA_InitStructure.DMA_Mode    = DMA_Mode_Circular;           //循环采集
	DMA_InitStructure.DMA_Channel = DMA_Channel_x;               //通道  三重模式只需使能 ADC1 的 DMA 通道。
	DMA_InitStructure.DMA_DIR     = DMA_DIR_PeripheralToMemory;  //外设到内存
	DMA_InitStructure.DMA_Priority   = DMA_Priority_High;        //数据流优先级
	DMA_InitStructure.DMA_BufferSize = 8;                        //设定待传输数据通道
	DMA_InitStructure.DMA_FIFOMode      = DMA_FIFOMode_Disable;  //失能FIFO模式
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
	
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_MultiModeConveredValue;
	DMA_InitStructure.DMA_MemoryBurst     = DMA_MemoryBurst_Single;      //ADC是直接传输,要选单次模式
	DMA_InitStructure.DMA_MemoryDataSize  = DMA_MemoryDataSize_HalfWord; //储存器数据宽度 
	DMA_InitStructure.DMA_MemoryInc       = DMA_MemoryInc_Enable;        //地址自增 与 DMA_BufferSize 联系,1 --> 不自增

	DMA_InitStructure.DMA_PeripheralBaseAddr = MultiMode_ADC_ADDR;             //ADC1地址基地址 + ADC1数据寄存器偏移地址  
	DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;     //ADC是直接传输,要选单次模式
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度 
	DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;      //无需设置为储存地址自增模式
	DMA_Init(DMAx_Stream_x,&DMA_InitStructure);
	
	DMA_Cmd(DMAx_Stream_x,ENABLE);
	
	RCC_APB2PeriphClockCmd(MultiMode_ADCx_CLK,ENABLE);
	
	ADC_StructInit(&ADC_InitStructure);
	
	ADC_CommonInitStructure.ADC_Mode      = ADC_Mode_Independent;      //独立模式
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;        //4分频
	ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_Disabled;//
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
	ADC_CommonInit(&ADC_CommonInitStructure);
	
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;             //使能连续转换
	ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_NbrOfConversion    = 8;                  //转换通道
	ADC_InitStructure.ADC_Resolution   = ADC_Resolution_12b;       //分辨率: 12位
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;  //使能扫描模式,多通道采集才会用得到
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
//	ADC_InitStructure.ADC_ExternalTrigConv   = //采用软件触发,故这里不需要
	ADC_Init(MultiMod
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值