F4的ADC的转换是12位的,该ADC是一种逐次逼近型模拟数字转换器,它有19个通道,其中包括16个外部信号源和两个内部信号源,还有一个VBAT通道。
ADC主要的特征:
1、12位、10位、8位、6位的分辨率。
2、转换结束,注入转换和模拟看门狗时间产生中断。
3、从通道零到通道19的自动扫描模式。
4、内嵌数据一致对齐
5、可编程的采样时间
6、规则转换和注入转换都可进行外部触发。
7、连续转换模式
8、双重模式(带来个或两个以上的ADC器件)
9、规则通道转换期间有DMA请求。
我本次主要的目的是对三个数据进行DMA的转换。DMA转换的原理是:
因为规则通道转换的值存储在唯一的数据寄存器中,所以转换多通道需要使用DMA,以防止数据被覆盖。注意:只有规则通道转换结束时才可以产生DMA请求。
当模拟电压为3.3v时,对应的数据是ox0fff,是线性的关系,可以根据内存的地址来计算出模拟电压。
ADC使用若干个ADC_CLK周期对输入电压采样,采样的数目周期由ADC_SMPR1和ADC_SMPR寄存器更改。总的转换时间是:
TCONV = 采样时间 + 12.5个周期。
例如:ADC_CLK = 14MHz,采样时间为1.5个周期,则
TCONV = 1.5 + 12.5 =14周期 = 1us.
下面是ADC转换的例程。
#include "stm32f4_discovery.h" //库函数 u16 ADC3ConvertedValue[4]; //ADC_InitTypeDef ADC_InitStructure; void Adc_Init(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable ADC3, DMA2 and GPIO clocks ****************************************/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE); //开启外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); /* DMA2 Stream0 channel0 configuration **************************************/ DMA_InitStructure.DMA_Channel = DMA_Channel_2; //设置DMA通道 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)( &(ADC3->DR)); //外设的地址 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue; //数据内存的地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //读取数据的模式是从外设到内存 DMA_InitStructure.DMA_BufferSize = 3; //有 三个转换通道,所以又3个缓冲区 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //外设地址增长 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址增长 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //一个字节为单位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; //循环转换 DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable ; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4 ; //外设内存增长的方式 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4 ; //内存地址增长的方式 DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_Cmd(DMA2_Stream0, ENABLE); /* Configure ADC3 Channel10 pin as analog input ******************************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure ADC3 Channel11 pin as analog input ******************************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure ADC3 Channel12 pin as analog input ******************************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); /* ADC Common Init **********************************************************/ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC3 Init ****************************************************************/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_10b; //设置ADC转换的精度 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //失能扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐 ADC_InitStructure.ADC_NbrOfConversion = 3; //三个转换通道 ADC_Init(ADC3, &ADC_InitStructure); /* ADC3 regular channel12 configuration *************************************/ ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_15Cycles ); ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 2, ADC_SampleTime_15Cycles ); ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_15Cycles ); /* Enable DMA request after last transfer (Single-ADC mode) */ ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE); /* Enable ADC3 DMA */ ADC_DMACmd(ADC3, ENABLE); //添加 ADC_ContinuousModeCmd(ADC3, ENABLE); /* Enable ADC3 */ ADC_Cmd(ADC3, ENABLE); ADC_SoftwareStartConv(ADC3); }
#include "stm32f4_discovery.h" extern u16 ADC3ConvertedValue[4]; void GPIO_Configuration(void); extern void Adc_Init(void); int main(void) { Adc_Init() ; GPIO_Configuration(); while (1) { int i = 0; u16 adset[10] ; GPIO_SetBits(GPIOE, GPIO_Pin_7); adset[i] = ADC3ConvertedValue[0]; if(adset[i]&0xffff) { GPIO_SetBits(GPIOE, GPIO_Pin_8); } } } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOE, &GPIO_InitStructure); }