STM32F746IGT多通道ADC连续跑不更新

2019-07-14 14:10发布

之前用F1,F2的时候,多通道DMA采样一直很顺
到了F7,就变得好奇怪,在MDK里面设断点运行,ADC数据会更新,但是连续跑的时候,ADC就再也不更新了





/******************************************************************************
* File: drv_adc.c - ADC
*
* Description:
*     ADC
* revision history:
*     version 1.0,written by sainty07,2017-01-20
*
* Copyright 2006-2008, ALL rights reserved..
******************************************************************************/
#include "board.h"
#include "rtthread.h"


static ADC_HandleTypeDef hadc1 = {ADC1};

static rt_timer_t timer_adc1;

static ADC_ChannelConfTypeDef sConfig[] = {
//{ADC_CHANNEL_9,          1, ADC_SAMPLETIME_15CYCLES,  0},
//{ADC_CHANNEL_7,          1, ADC_SAMPLETIME_15CYCLES,  0},
//{ADC_CHANNEL_11,         1, ADC_SAMPLETIME_15CYCLES,  0},
//{ADC_CHANNEL_12,         1, ADC_SAMPLETIME_15CYCLES,  0},
//{ADC_CHANNEL_13,         1, ADC_SAMPLETIME_15CYCLES,  0},
{ADC_CHANNEL_14,         1, ADC_SAMPLETIME_480CYCLES,  0},
{ADC_CHANNEL_15,         2, ADC_SAMPLETIME_480CYCLES,  0},
//{ADC_CHANNEL_VREFINT,    8, ADC_SAMPLETIME_144CYCLES, 0},
//{ADC_CHANNEL_VBAT,       9, ADC_SAMPLETIME_144CYCLES, 0},
//{ADC_CHANNEL_TEMPSENSOR, 9, ADC_SAMPLETIME_480CYCLES, 0},
};

#define ADC_CH_NUM      (sizeof(sConfig)/sizeof(ADC_ChannelConfTypeDef))


volatile uint32_t adc_buf[ADC_CH_NUM] = {0};

void DMA2_Stream0_IRQHandler(void)
{
   // rt_interrupt_enter();
    HAL_DMA_IRQHandler(hadc1.DMA_Handle);

   // rt_interrupt_leave();
}

static void adc_read(void * parameter)
{
    int i;

//HAL_ADC_Start(&hadc1);
   //   if (HAL_OK == HAL_ADC_PollForConversion(&hadc1, 0))
      {
        uint32_t v = adc_buf[0];//HAL_ADC_GetValue(&hadc1);
        rt_kprintf("adc: %d ", v);

      }
      // HAL_ADC_Start(&hadc1);

      //if (HAL_OK == HAL_ADC_PollForConversion(&hadc1, 0))
      {
        uint32_t v = adc_buf[1];// HAL_ADC_GetValue(&hadc1);
        rt_kprintf("%d ", v);

      }
    rt_kprintf(" ");
//hadc1.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
}

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    static DMA_HandleTypeDef hdma_adc1;

    __HAL_RCC_ADC1_CLK_ENABLE();
    __HAL_RCC_DMA2_CLK_ENABLE();

    HAL_IoArrayInit(GPIO_Init_ADC1, GPIO_CFG_NUM(GPIO_Init_ADC1));

    hdma_adc1.Instance                 = ADC1_DMA_STREAM;
    hdma_adc1.Init.Channel             = ADC1_DMA_CHANNEL;
    hdma_adc1.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc1.Init.MemDataAlignment    = DMA_PDATAALIGN_WORD;
    hdma_adc1.Init.Mode                = DMA_CIRCULAR;
    hdma_adc1.Init.Priority            = DMA_PRIORITY_HIGH;
    hdma_adc1.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;

    __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc1);
    HAL_DMA_Init(&hdma_adc1);

    HAL_NVIC_SetPriority(ADC1_DMA_IRQn, NVIC_PRIORITY_ADC1, 0);   
    HAL_NVIC_EnableIRQ(ADC1_DMA_IRQn);
}



static rt_err_t rt_hw_adc_init(void)
{
    volatile ADC_ChannelConfTypeDef ch;
        int i;
    hadc1.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution            = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode          = ENABLE;
    hadc1.Init.ContinuousConvMode    = ENABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.ExternalTrigConv      = ADC_SOFTWARE_START;
    hadc1.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion       = 2;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    hadc1.Init.EOCSelection          = ADC_EOC_SEQ_CONV;

    if (HAL_ADC_Init(&hadc1) != HAL_OK)
    {
        return -RT_ERROR;
    }

   // for (i = 0; i < ADC_CH_NUM; i++)
   // {
    //    ch = ;
    //    ch.Rank = i + 1;
         if (HAL_ADC_ConfigChannel(&hadc1, (ADC_ChannelConfTypeDef *)&sConfig[0]) != HAL_OK)
        {
            return -RT_ERROR;
        }
        if (HAL_ADC_ConfigChannel(&hadc1, (ADC_ChannelConfTypeDef *)&sConfig[1]) != HAL_OK)
        {
            return -RT_ERROR;
        }
//    }

   if(HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&adc_buf[0], ADC_CH_NUM) != HAL_OK)
    {
        return -RT_ERROR;
    }

//HAL_ADC_Start(&hadc1);
//HAL_ADC_Stop(&hadc1);


   // timer_adc1 = rt_timer_create("adc1", adc_read, RT_NULL, 100, RT_TIMER_FLAG_PERIODIC);
   // rt_timer_start(timer_adc1);
    return RT_EOK;
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
  // HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&adc_buf[0], ADC_CH_NUM);
        {
        uint32_t v = adc_buf[0];//HAL_ADC_GetValue(&hadc1);
        rt_kprintf("adc: %d ", v);

      }
      // HAL_ADC_Start(&hadc1);

      //if (HAL_OK == HAL_ADC_PollForConversion(&hadc1, 0))
      {
        uint32_t v = adc_buf[1];// HAL_ADC_GetValue(&hadc1);
        rt_kprintf("%d ", v);

      }
    rt_kprintf(" ");

      hadc1.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
}


int drv_adc1(void)
{
  rt_hw_adc_init();


    return 0;
}


//INIT_BOARD_EXPORT(drv_adc1);
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
ctwewer
1楼-- · 2019-07-14 19:16
 精彩回答 2  元偷偷看……
jufenyi
2楼-- · 2019-07-14 19:48
st官网应该有多通道的范例,找找看。
huazhe
3楼-- · 2019-07-14 20:10
hadc1.Init.EOCSelection          = ADC_EOC_SEQ_CONV;
ADC_EOC_SEQ_CONV===》库注释为未来预留设置,

你这里配置为 ADC_EOC_SINGLE_CONV 测试验证下。
jfgsdfa
4楼-- · 2019-07-15 01:17
谢谢上面几位支招,不过还是不行,其实调了一个星期,能试过的配置都试过了,现在再次试了一下,还是不行,不知道是ADC不行,还是DMA有问题
现在用个定时器每次采样一个通道,ADC数据倒有更新

一周热门 更多>