STM32l431: ADC + DMA + Timer = fel
Postat: 1 april 2020, 22:45:29
Jag blir tokig på detta.
Har satt upp Tim6 för att trigga ADC och via DMA2 spara ned 100 ADC värden i en buffer. Allt verkar funkar, DMA räknaren minskar och jag får DMA interrupt, men bara första värdet sparas i arrayen, resten blir 0 (init värden). Nån som ser var jag missat?
Jag har använt cubeMX för genera initiering och sedan lagt till kod för att köra.
Har satt upp Tim6 för att trigga ADC och via DMA2 spara ned 100 ADC värden i en buffer. Allt verkar funkar, DMA räknaren minskar och jag får DMA interrupt, men bara första värdet sparas i arrayen, resten blir 0 (init värden). Nån som ser var jag missat?
Jag har använt cubeMX för genera initiering och sedan lagt till kod för att köra.
Kod: Markera allt
void main()
....
for(i = 0; i < ADC_CONVERTED_DATA_BUFFER_SIZE; i++)
{
aADCxConvertedData[i] = 0;
}
Configure_ADC();
Configure_DMA();
Configure_TIM_TimeBase_ADC_trigger();
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
PrintDMA();
HAL_TIM_Base_Start(&htim6);
err = HAL_ADC_Start_DMA(&hadc1,(uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE);
if (err != HAL_OK)
{
printf("DMA err %d\n\r", err);
}
PrintDMA();
HAL_NVIC_SetPriority(DMA2_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel3_IRQn);
HW_TIM_Delay(100); // wait 100 ms
for(i = 0; i < 10; i++)
{
printf("%d\n\r", aADCxConvertedData[i]);
}
}
void PrintDMA()
{
printf("TIM6: %d: DMA2: %d: %d/%d\n\r", (int)htim6.Instance->CNT, (int)LL_DMA_IsActiveFlag_TC3(DMA2), LL_DMA_GetDataLength(DMA2, LL_DMA_CHANNEL_3), ADC_CONVERTED_DATA_BUFFER_SIZE);
printf("En %d. Flags %d %d\n\r", LL_DMA_IsEnabledChannel(DMA2, LL_DMA_CHANNEL_3), (int)LL_DMA_IsActiveFlag_TE1(DMA2), (int)LL_DMA_IsActiveFlag_TE2(DMA2));
}
void Configure_ADC(void)
{
//ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T6_TRGO;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.DMAContinuousRequests = ENABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
//Error_Handler();
}
if (HAL_ADC_ConfigChannel(&hadc1, ADC_CHANNEL_13) != HAL_OK)
{
//Error_Handler();
}
}
void Configure_DMA(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
HAL_DMA_DeInit(&hdma_adc1);
__HAL_RCC_DMA2_FORCE_RESET();
__HAL_RCC_DMA2_RELEASE_RESET();
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**ADC1 GPIO Configuration
PC4 ------> ADC1_IN13
*/
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA2_Channel3;
hdma_adc1.Init.Request = DMA_REQUEST_0;
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_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_NORMAL;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hadc1,DMA_Handle,hdma_adc1);
}
void Configure_TIM_TimeBase_ADC_trigger(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM6_Init 1 */
__HAL_RCC_TIM6_CLK_ENABLE();
/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 20; //timer_prescaler-1;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 1000;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim6.Init.RepetitionCounter = 0;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}