佚名通过本文主要向大家介绍了stm32f072rbt6,stm32 adc dma,adc dma,stm32f4 adc dma,stm32 adc dma多通道等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: 求助!关于STM32F072RBT6的ADC(DMA中断)多通道采集问题
描述:
描述:
具体配置如代码所示。我的目的是想读到4路通道的AD值,分别是通道0(PA0),通道1(PA1),通道9(PB1),通道10(PC0)。遇到的问题是,如果配置ADC的扫描方向为向上扫描,则通道0和通道1的值读出来是对的,但是通道9和通道10读出来的值是错的,而且值是相同的,如果配置成向下扫描,则通道9,10的值是对的,通道0,1的值是错的而且值相同。 也就是最多只能读出两路通道的正确AD值,想读第三路或第四路通道的AD值时读出来的值是错误的,并且错误的值还是相同的。求解,谢谢!
#include "adc.h"
/*****************************************************************************************************************************/
#define ADC1_DR_Address 0x40012440
#define AD_Count 10 //AD滤波采样次数
#define AD_Channel_Num 4 //AD 采集的通道数
u16 ADCresults[AD_Channel_Num][AD_Count];//AD采集值
u32 AD_Data[AD_Channel_Num]; //AD采集值的平均值
volatile u16 ADC_ConvertedValue[AD_Count][AD_Channel_Num];//用于存储DMA传输的数据
u8 flag_ADC = 0;
/*****************************************************************************************************************************/
static void ADC1_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOA| RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC , ENABLE);
/* Configure PA.0 PA.1 as analog input */
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure); // PA0,PA1,输入时不用设置速率
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOB, &GPIO_InitStructure); // PB1,输入时不用设置速率
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); // PC0,输入时不用设置速率
}
/**
* @brief 配置ADC1的工作模式
* @param 无
* @retval 无
*/
static void ADC1_Mode_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
/*设置ADC分频因子为4 ,ADC最大时间不能超过14M*/
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
/* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC1 DeInit */
ADC_DeInit(ADC1);
/*初始化ADC结构体,此句必须加,不加的话多路ADC数据会交换*/
ADC_StructInit(&ADC_InitStructure);
/*配置ADC分辨率为12位*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
/*开启连续转换*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/*禁止触发检测,使用软件触发*/
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
/*ADC采集数据右对齐*/
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/*向上扫描*/
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
/*ADC初始化*/
ADC_Init(ADC1, &ADC_InitStructure);
/*配置采样通道及时间*/
ADC_ChannelConfig(ADC1 ,ADC_Channel_0 |ADC_Channel_1 |ADC_Channel_9| ADC_Channel_10 , ADC_SampleTime_239_5Cycles);
/* ADC 校准 */
ADC_GetCalibrationFactor(ADC1);
/* 循环模式下的 ADC DMA 请求 */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
/* 使能 ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 等待 ADCEN 标志 */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
/* ADC1 常规软件启动转换 */
ADC_StartOfConversion(ADC1);
}
/**
* @brief DMA 工作方式配置
* @param 无
* @retval 无
*/
void ADC1_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 使能DMA时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
/* 复位DMA1_Channel1 */
DMA_DeInit(DMA1_Channel1);
/*DMA外设ADC基地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
/*DMA内存基地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
/*外设作为数据传输源*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*DMA通道的DMA缓存的大小*/
DMA_InitStructure.DMA_BufferSize = AD_Channel_Num * AD_Count;
/*外设地址寄存器不变*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/*内存地址寄存器递增*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/*外设取值大小设置为半字*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
/*数据大小设置为半字*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
/*DMA循环模式,即完成后重新开始覆盖*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*DMA优先级设置为高*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/*DMA通道x禁用内存到内存传输*/
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/*DMA初始化*/
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/*清除一次DMA中断标志*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
/*使能DMA传输完成中断*/
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
/*选择DMA1通道中断*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
/*中断使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/*优先级设为0 */
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
/*使能 DMA 中断*/
NVIC_Init(&NVIC_InitStructure);
/* DMA1 Channel1&