话不多说,直接上程序,详情请看注释
//-------------.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