cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F405 ADC DMA reading problem

karol1dw
Associate
Posted on October 16, 2016 at 10:04

Hi

I'm using STM32F405RGT6 configured in CubeMX. I'm reading ADC inside TIM6 interrupt which is executed every 40us. As you can see in switch statement I read all 7 channels and next, one or two channels (I wrote a little functions to update SQR registers so that I don't need to call HAL config structure). If I read like this and check DR via Keil debugger I get strage values, that are really unstable. However if I move the code to main loop and disable TIM6 and read they are fine. I tried to change NVIC priorities, TIM6 has 3, ADC interrupt has 2 and ADC DMA int has 1 but it didnt helped. Another question: I would like to send data in TIM6 interrupt after ADC readings. Atm I'm using HAL_USART_Transmit_DMA() to send data every 1ms. The problem is I'm not getting all data. I checked how much time this functions need to execute and it takes 3us, so it's not breaking theinterrupt in any way. TIM6 interrupt:

volatile
uint8_t count;
void
TIM6_DAC_IRQHandler(
void
)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
//static int COUNTER_MAX = MOTOR_DRIVER_T/0.00002;
//HAL_GPIO_WritePin(GPIOB, CS_A_Pin, GPIO_PIN_RESET);
switch
(count){
case
0:
ADCreadAmbient(); 
// read ambient light
HAL_GPIO_WritePin(GPIOC, D_LF_Pin, GPIO_PIN_SET);
break
;
case
1: 
// case 3: // 40us
ADCreadChannel(CH2, &sensor[0].buf[2]); 
// LF read
HAL_GPIO_WritePin(GPIOC, D_LF_Pin, GPIO_PIN_RESET);
break
;
case
2: 
//120us case 6: // 100us
HAL_GPIO_WritePin(GPIOC, D_RF_Pin, GPIO_PIN_SET);
break
;
case
4: 
//160us case 8: // 140us
ADCreadChannel(CH11, &sensor[1].buf[2]); 
// RF read
HAL_GPIO_WritePin(GPIOC, D_RF_Pin, GPIO_PIN_RESET);
break
;
case
6: 
// 240us case 11: // 200us
HAL_GPIO_WritePin(GPIOA, D_L_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, D_R_Pin, GPIO_PIN_SET);
break
;
case
7: 
// 280us case 13: // 240us
ADCread2Channel(CH13, CH12, &read[0]); 
// L, R read
HAL_GPIO_WritePin(GPIOA, D_L_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, D_R_Pin, GPIO_PIN_RESET);
break
;
case
9: 
// 360us case 16: // 300us
HAL_GPIO_WritePin(GPIOC, D_LS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, D_RS_Pin, GPIO_PIN_SET);
break
;
case
10: 
// case 18: // 340us
ADCread2Channel(CH3, CH10, &read[2]); 
// LS, RS read
HAL_GPIO_WritePin(GPIOC, D_LS_Pin, GPIO_PIN_RESET); 
// side sensors off
HAL_GPIO_WritePin(GPIOC, D_RS_Pin, GPIO_PIN_RESET);
break
;
case
12:
GyroGetAngle(0.001);
break
;
case
13:
MotorUpdate();
break
;
}
++count;
if
(count >= 25){ // execute every 1ms
//HAL_GPIO_WritePin(GPIOB, CS_A_Pin, 1);
count = 0;
}
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
/* USER CODE END TIM6_DAC_IRQn 1 */
}

ADC functions:

void
ADCreadAmbient(){
ADC1->SQR1 = (ADC_SQR1_L_2|ADC_SQR1_L_1); 
// 7 conversions (0x06, count from 0)
// channels order is important!
ADC1->SQR3 = (CH2)|(CH11<<5)|(CH13<<10)|(CH12<<15)|(CH3<<20)|(CH10<<25); 
// channels to convert: 2, 11, 12, 13 and 9 for battery
ADC1->SQR2 = CH9;
//CH3, CH10
HAL_ADC_Start_DMA(&hadc1, cal, 7);
//vbat = cal[6]; // *0.0025 + 0,067;
if
(cal[6] < 2884 && cal[6] > 2650){ 
// 7,4-6,8
batError = 1;
UI_LedOnAll();
}
}
void
ADCreadChannel(uint8_t CHx, uint32_t *buf){
ADC1->SQR1 &= ~ADC_SQR1_L; 
// 1 conversion
ADC1->SQR3 = CHx; 
// channel to be converted
HAL_ADC_Start_DMA(&hadc1, buf, 1);
}
void
ADCread2Channel(uint8_t CHx1, uint8_t CHx2, uint32_t *buf){
ADC1->SQR1 = ADC_SQR1_L_0;
ADC1->SQR3 = (CHx1)|(CHx2<<5);
HAL_ADC_Start_DMA(&hadc1, buf, 2);
}

ADC config:

void
MX_ADC1_Init(
void
)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 7;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if
(HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_84CYCLES;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = 2;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = 3;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_12;
sConfig.Rank = 4;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = 5;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = 6;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = 7;
if
(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}

#stm32 #adc #dma
1 REPLY 1
Amel NASRI
ST Employee
Posted on October 31, 2016 at 17:05

Hi Def,

Try to minimize your settings and code in order to identify your problem root cause. It is not easy to help you based on what you provided as description.

You may also start from a working example then update it depending on your application case.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.