嗯,最近做ADC采样,牛牛们勿喷,我知道,这个可能没什么技术含量,不过,菜鸟的我们迈出了第一步,和大家分享的那种感觉,牛牛们要鼓励支持啊
单通道采样,使用了一个ADC。
嗯,废话少说,第一种方式,使用了DMA,略脑残,哈哈
直接上代码了
- /*******************************************************************************
- * Copyright(C),2014,
- * @file Name main.c
- * @author chansane
- * @version V2.0.0
- * @date 09-12-2014
- * @brief
- * @History
- *******************************************************************************/
- #include "adc.h"
- __IO uint16_t ADC3ConvertedValue;
- float ADC3ConvertedVoltage;
- /* 函数名:ADC1_Mode_Config
- * 描述 :配置ADC1的工作模式为DMA模式
- * 输入 : 无
- * 输出 :无
- * 调用 :内部调用
- */
- void ADC3_CH2_DMA_Config(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_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
- /* DMA2 Stream0 channel2 configuration **************************************/
- DMA_InitStructure.DMA_Channel = DMA_Channel_2;
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
- DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
- DMA_InitStructure.DMA_BufferSize = 1;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
- 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_Disable;
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
- DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
- DMA_Init(DMA2_Stream0, &DMA_InitStructure);
- DMA_Cmd(DMA2_Stream0, ENABLE);
- /* Configure ADC3 Channel2 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(GPIOA, &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_12b;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfConversion = 1;
- ADC_Init(ADC3, &ADC_InitStructure);
- /* ADC3 regular channel2 configuration *************************************/
- ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 1, ADC_SampleTime_3Cycles);
- /* Enable DMA request after last transfer (Single-ADC mode) */
- ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
- /* Enable ADC3 DMA */
- ADC_DMACmd(ADC3, ENABLE);
- /* Enable ADC3 */
- ADC_Cmd(ADC3, ENABLE);
-
- ADC_SoftwareStartConv(ADC3);
- }
- /****************************************************
- * @functionName Delay
- * @brief We use this function to delay an sure time periond
- * @param nCount
- * @retval None
- ****************************************************/
- void Delay(__IO uint32_t nCount)
- {
- while(nCount--)
- {
- }
- }
- //Read ADC result,converted to real voltage
- float ADC_READ(void)
- {
- ADC3ConvertedVoltage = ADC3ConvertedValue*3.3/0xFFF;
- return ADC3ConvertedVoltage;
- }
- /******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/
复制代码 嗯,他们说DMA没必要,嗯,那咱就换种查询方式,你需要数据的时候我才给你数据,你不需要的时候我就关闭ADC,节能减排
上代码
- /**
- * @brief ADC3 channel07 with DMA configuration
- * @param None
- * @retval None
- */
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- #include "stm32f4xx.h"
- __IO float ADC3ConvertedVoltage = 0;
- /* 函数名:ADC1_Mode_Config
- * 描述 :配置ADC1的工作模式为DMA模式
- * 输入 : 无
- * 输出 :无
- * 调用 :内部调用
- */
- void ADC3_CH2_Polling_Config(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- ADC_CommonInitTypeDef ADC_CommonInitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- /* Enable ADC3 and GPIO clocks ****************************************/
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
- /* Configure ADC3 Channel2 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);
- /* 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_12b;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfConversion = 1;
- ADC_Init(ADC3, &ADC_InitStructure);
-
- /* ADC3 regular channel2 configuration *************************************/
- ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_28Cycles);
-
- }
- /****************************************************
- * @functionName Delay
- * @brief We use this function to delay an sure time periond
- * @param nCount
- * @retval None
- ****************************************************/
- void Delay(__IO uint32_t nCount)
- {
- while(nCount--)
- {
- }
- }
- //Read ADC result,converted to real voltage
- float ADC_READ(void)
- {
- uint32_t adc_timeout = 10000000;//adc 转换硬件超时时长
-
- ADC_ClearFlag(ADC3,ADC_FLAG_EOC);
- ADC_Cmd(ADC3, ENABLE);
-
- //通过软件将该位置 1 可开始转换,而硬件会在转换开始后将该位清零
- ADC_SoftwareStartConv(ADC3);
-
- while((!ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC)) && (adc_timeout--));//为避免硬件错误导致整个系统瘫痪所以得加上硬件超时
-
- ADC3ConvertedVoltage = ADC_GetConversionValue(ADC3)*3.3/0xFFF;
-
- //ADC_ClearFlag(ADC3,ADC_FLAG_EOC);//规则组通道转换结束后,硬件将该位置 1。通过软件或通过读取 ADC_DR 寄存器将该位清零,上一语句已经读取ADC_DR,本语句可以取消
-
- ADC_Cmd(ADC3, DISABLE);
-
- return ADC3ConvertedVoltage;
- }
复制代码
楼主虽然成功了采集到了数据,但是对一个参数的设置有些疑惑。
关于采样时间的设置ADC_SampleTime_3Cycles,实测,数据测不准,或许是采样保持时间不够?
如果设置为ADC_SampleTime_15Cycles或者ADC_SampleTime_28Cycles,是完全可以的。
那么问题来了,实际应用的时候我用什么最合适呢,有人讲这是采样效率和精度的平衡(心法口诀),可是实际的时候,怎么去找这个平衡点?
各路大神支招
|