yuzhuju-318441 发表于 2017-2-12 23:02:48

STM32F746IGT 多通道ADC搞了一周了,只能求助了

之前用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 = {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;//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;// HAL_ADC_GetValue(&hadc1);
      rt_kprintf("%d ", v);

      }
    rt_kprintf("\r\n");
//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) != HAL_OK)
      {
            return -RT_ERROR;
      }
      if (HAL_ADC_ConfigChannel(&hadc1, (ADC_ChannelConfTypeDef *)&sConfig) != HAL_OK)
      {
            return -RT_ERROR;
      }
//    }

   if(HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&adc_buf, 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, ADC_CH_NUM);
      {
      uint32_t v = adc_buf;//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;// HAL_ADC_GetValue(&hadc1);
      rt_kprintf("%d ", v);

      }
    rt_kprintf("\r\n");

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


int drv_adc1(void)
{
rt_hw_adc_init();


    return 0;
}


//INIT_BOARD_EXPORT(drv_adc1);


yuzhuju-318441 发表于 2017-2-12 23:06:01

怎么改都不会更新啊,编译器也从IAR换到MDK。。。。折腾死了
网上所有的F7 ADC范例都是单通道
难道F7 ADC多通道本身有问题?

wenyangzeng 发表于 2017-2-13 13:59:00

本帖最后由 wenyangzeng 于 2017-2-13 15:21 编辑

这几句改一下试看看

hadc1.Init.EOCSelection          = DISABLE;


hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment    =DMA_MDATAALIGN_HALFWORD;

还有:ADC初始化和DMA初始化的顺序也有讲究的。


shanji 发表于 2017-2-13 15:35:21

st官网应该有多通道的范例,找找看。

xmshao 发表于 2017-2-13 18:01:29

hadc1.Init.EOCSelection          = ADC_EOC_SEQ_CONV;
ADC_EOC_SEQ_CONV===》库注释为未来预留设置,

你这里配置为 ADC_EOC_SINGLE_CONV 测试验证下。

yuzhuju-318441 发表于 2017-2-19 20:45:24

谢谢上面几位支招,不过还是不行,其实调了一个星期,能试过的配置都试过了,现在再次试了一下,还是不行,不知道是ADC不行,还是DMA有问题
现在用个定时器每次采样一个通道,ADC数据倒有更新
页: [1]
查看完整版本: STM32F746IGT 多通道ADC搞了一周了,只能求助了