STM32F767使用DMA方式采样ADC,多通道异常

2019-07-20 07:09发布

我现在使用stm32f767上一个dma,同时获取adc2上1个通道的数据和adc3上11个通道的数据





ADC_HandleTypeDef hadc2;
ADC_HandleTypeDef hadc3;

DMA_HandleTypeDef hdma_adc2;
DMA_HandleTypeDef hdma_adc3;



/**
  * Enable DMA controller clock
  */
void MX_ADC_DMA_Init(void)
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();




  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
//  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
//  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
//  /* DMA2_Stream2_IRQn interrupt configuration */
//  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
//  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);


}








//初始化ADC
//ch: ADC_channels
//通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
void MY_ADC_Init(void)
{
       
          ADC_ChannelConfTypeDef sConfig;
          MX_ADC_DMA_Init();//DMA 初始化
       
    hadc2.Instance=ADC2;
    hadc2.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV8;   //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
    hadc2.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    hadc2.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    hadc2.Init.ScanConvMode=ENABLE;                      //非扫描模式
    hadc2.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    hadc2.Init.ContinuousConvMode=ENABLE; //DISABLE;                //关闭连续转换
    hadc2.Init.NbrOfConversion= 1;                         //1个转换在规则序列中 也就是只转换规则序列1
    hadc2.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    hadc2.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    hadc2.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    hadc2.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    hadc2.Init.DMAContinuousRequests= ENABLE; //启动DMA请求   //DISABLE;             //关闭DMA请求
    HAL_ADC_Init(&hadc2);


                sConfig.Channel = ADC_CHANNEL_6;
                sConfig.Rank = 1;
                sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
                HAL_ADC_ConfigChannel(&hadc2, &sConfig);




    hadc3.Instance=ADC3;
    hadc3.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV8;   //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
    hadc3.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    hadc3.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    hadc3.Init.ScanConvMode=ENABLE;                      //非扫描模式
    hadc3.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    hadc3.Init.ContinuousConvMode=ENABLE; //DISABLE;                //关闭连续转换
    hadc3.Init.NbrOfConversion=11;                        
    hadc3.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    hadc3.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    hadc3.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    hadc3.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    hadc3.Init.DMAContinuousRequests= ENABLE; //启动DMA请求    DISABLE;             //关闭DMA请求
    HAL_ADC_Init(&hadc3);  
               
                sConfig.Channel = ADC_CHANNEL_4;
                sConfig.Rank = 1;
                sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);


                sConfig.Channel = ADC_CHANNEL_5;
                sConfig.Rank = 2;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
       
                sConfig.Channel = ADC_CHANNEL_6;
                sConfig.Rank = 3;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_7;
                sConfig.Rank = 4;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_8;
                sConfig.Rank = 5;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_9;
                sConfig.Rank = 6;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_10;
                sConfig.Rank = 7;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
               
                sConfig.Channel = ADC_CHANNEL_12;
                sConfig.Rank = 8;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_13;
                sConfig.Rank = 9;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_14;
                sConfig.Rank = 10;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
                sConfig.Channel = ADC_CHANNEL_15;
                sConfig.Rank = 11;
                HAL_ADC_ConfigChannel(&hadc3, &sConfig);
               
}




//ADC底层驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//hadc:ADC句柄
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
       
        if(hadc->Instance == ADC2)
        {
    __HAL_RCC_ADC2_CLK_ENABLE();            //使能ADC2时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                             //开启GPIOA时钟
       
    GPIO_Initure.Pin=GPIO_PIN_6;            //PA6
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
               
               
                /* ADC2 DMA Init */
    /* ADC2 Init */
    hdma_adc2.Instance = DMA2_Stream2;
    hdma_adc2.Init.Channel = DMA_CHANNEL_1;
    hdma_adc2.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc2.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc2.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc2.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_adc2.Init.Mode = DMA_CIRCULAR;// DMA_NORMAL;
    hdma_adc2.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_adc2.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_adc2);
  
    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc2);
               
        }
        else if(hadc->Instance == ADC3)
        {
    __HAL_RCC_ADC3_CLK_ENABLE();            //使能ADC2时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();                             
                __HAL_RCC_GPIOF_CLK_ENABLE();
       
    GPIO_Initure.Pin= GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;            //PC0 2 3
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
               
                GPIO_Initure.Pin= GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;        
    HAL_GPIO_Init(GPIOF,&GPIO_Initure);
               
               
                 /* ADC3 DMA Init */
    /* ADC3 Init */
    hdma_adc3.Instance = DMA2_Stream0;
    hdma_adc3.Init.Channel = DMA_CHANNEL_2;
    hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc3.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc3.Init.Mode = DMA_CIRCULAR;
    hdma_adc3.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_adc3);
    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc3);
               
               
               
        }       
}

初始化如上图所示

uint32_t ADC2_Value[20];
uint32_t ADC3_Value[20];


int main(void)
{
       
    Cache_Enable();                 //打开L1-Cache
    HAL_Init();                                             //初始化HAL库
    Stm32_Clock_Init(432,25,2,9);   //设置时钟,216Mhz
          
    delay_init(216);                //延时初始化
    uart_init(115200);                        //串口初始化
    MY_ADC_Init();                 //ADC初始化
    DAC1_Init();
    LED_Init();                     //初始化LED
          
       


   HAL_ADC_Start_DMA(&hadc2, &ADC2_Value[0], 1);
    HAL_ADC_Start_DMA(&hadc3, &ADC3_Value[0], 11);
    while(1)
    {
                        delay_ms(500);
                       

     }



  在mian函数中启动dma采样


现在ADC3_Value中数据正常,但是ADC2_Value没有采到数据
如果我屏蔽ADC3的初始化,那么ADC2_Value中就会有那个通道的数据了








友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。