Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

STM32F7 ADC+DMA+TIM2

Пт май 06, 2016 19:40:47

Добрый день.
Помогите разобраться с проблемой.
Задача: по событию от таймера запускать преобразования 8-ми регулярных каналов АЦП, а по окончанию преобразований забирать данные с помощью DMA(попадать в прерывание DMA). События генерировать с частотой 1кГц, т.е. выборка данных раз в мс.
Сейчас проблема в запуске АЦП по событию от таймера. Не могу понять в чём причина. Пробовал запускать АЦП вручную - всё нормально.


Код:
ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc3;
uint16_t adc_buf[8];



void GPIO_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStruct;

   /* GPIO Ports Clock Enable */
   __GPIOA_CLK_ENABLE();
   __GPIOB_CLK_ENABLE();
   __GPIOC_CLK_ENABLE();
   __GPIOD_CLK_ENABLE();
   __GPIOE_CLK_ENABLE();
   __GPIOF_CLK_ENABLE();
   __GPIOG_CLK_ENABLE();
   __GPIOH_CLK_ENABLE();
      
   /* DMA controller clock enable */
   __HAL_RCC_DMA2_CLK_ENABLE();
   
    /* Peripheral clock enable */
    __ADC3_CLK_ENABLE();
 
    /**ADC3 GPIO Configuration   
    PF3     ------> ADC3_IN9
    PF4     ------> ADC3_IN14
    PF5     ------> ADC3_IN15
    PF6     ------> ADC3_IN4
    PF7     ------> ADC3_IN5
    PF8     ------> ADC3_IN6
    PF9     ------> ADC3_IN7
    PF10     ------> ADC3_IN8
    */
    GPIO_InitStruct.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;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);      
}


void init_tim2(void)      
{   
    TIM_ClockConfigTypeDef sClockSourceConfig;
   TIM_MasterConfigTypeDef sMasterConfig;

    // Peripheral clock enable
    __TIM2_CLK_ENABLE();

    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 1080-1;      
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 100;                           // 1кГц
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_Base_Init(&htim2);
   
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);

   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
   HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);

   HAL_TIM_Base_Start(&htim2);
}


void init_adc3(void)
{
   ADC_ChannelConfTypeDef sConfig;
   
   // Настройка АЦП
   hadc3.Instance = ADC3;
   hadc3.Init.ClockPrescaler          = ADC_CLOCKPRESCALER_PCLK_DIV4;
   hadc3.Init.Resolution             = ADC_RESOLUTION12b;
   hadc3.Init.ScanConvMode           = ENABLE;
   hadc3.Init.ContinuousConvMode       = DISABLE;
   hadc3.Init.NbrOfConversion           = 8;
   hadc3.Init.DiscontinuousConvMode    = DISABLE;
   hadc3.Init.NbrOfDiscConversion      = 1;      
   hadc3.Init.ExternalTrigConvEdge    = ADC_EXTERNALTRIGCONVEDGE_RISING;
   hadc3.Init.ExternalTrigConv       = ADC_EXTERNALTRIGCONV_T2_TRGO;
   hadc3.Init.DataAlign              = ADC_DATAALIGN_RIGHT;
   hadc3.Init.DMAContinuousRequests    = ENABLE;
   hadc3.Init.EOCSelection          = EOC_SEQ_CONV;   
   HAL_ADC_Init(&hadc3);

   // Настройка регулярных каналов
   sConfig.Channel = ADC_CHANNEL_4;
   sConfig.Rank = 1;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);

   sConfig.Channel = ADC_CHANNEL_5;
   sConfig.Rank = 2;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);

   sConfig.Channel = ADC_CHANNEL_6;
   sConfig.Rank = 3;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);

   sConfig.Channel = ADC_CHANNEL_7;
   sConfig.Rank = 4;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);

   sConfig.Channel = ADC_CHANNEL_8;
   sConfig.Rank = 5;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);

   sConfig.Channel = ADC_CHANNEL_9;
   sConfig.Rank = 6;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);
 
   sConfig.Channel = ADC_CHANNEL_14;
   sConfig.Rank = 7;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);

   sConfig.Channel = ADC_CHANNEL_15;
   sConfig.Rank = 8;
   sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
   HAL_ADC_ConfigChannel(&hadc3, &sConfig);
}
   
void init_dma(void)
      
    // Peripheral DMA 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_HALFWORD;
    hdma_adc3.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc3.Init.Mode       = DMA_CIRCULAR;
    hdma_adc3.Init.Priority    = DMA_PRIORITY_LOW;
    hdma_adc3.Init.FIFOMode    = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_adc3);

    __HAL_LINKDMA(&hadc3,DMA_Handle,hdma_adc3);

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

    HAL_ADC_Start_DMA(&hadc3, (uint32_t*)&adc_buf , 8);
}
Ответить