Skip to main content
PRedd.111
Associate III
September 29, 2019
Solved

Why ADC continuous readings from software are not possible?

  • September 29, 2019
  • 3 replies
  • 1861 views

I have STM32F303CCTX custom board.

IO Pin PB8 has a timer that triggers a gpio high for 200us and resets for 300us. creates a 1.8KHz wave with about 35% duty using plain timer mode. Timer IRQ handler also fires the adc conversion on pin PB0.

It continuously keeps running with no values for over a minute. Then suddenly exits to second for loop with the scans(mostly invalid values).

main.c

#define ADC_ARRY_SIZE 30
 
 
uint16_t adc_vals[ADC_ARRY_SIZE] = {0};
 
uint16_t adc_val = 0;
 
uint32_t adc_zero_count = 0;
 
uint32_t index_no = 0;
 
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
 
{
 
 adc_val = HAL_ADC_GetValue(&hadc3);
 
 if((adc_val != 0) && (index_no < ADC_ARRY_SIZE))
 
 adc_vals[index_no++] = adc_val;
 
 else if(adc_val == 0)
 
 adc_zero_count++;
 
}
 
void set_pwm2_duty(uint32_t duty_count)
 
{
 
 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, duty_count);
 
}
 
int main(void)
 
{
 
 adc_val = 0;
 
 adc_zero_count = 0;
 
 index_no = 0;
 
 adc_buffer_full = false;
 
 int i;
 
//Generated code begin
 
 HAL_Init();
 
 SystemClock_Config();
 
 MX_GPIO_Init();
 
 MX_ADC3_Init();
 
 MX_TIM2_Init();
 
 MX_TIM6_Init();
 
//generated code end
 
 set_laser_pwm_duty(3000);
 
 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
 
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
 
 HAL_GPIO_WritePin(GPIOGPIOB, GPIO_PIN_8, GPIO_PIN_SET);
 
 HAL_TIM_Base_Start_IT(&htim6);//start pulse timer
 
 adc_trigger = true;
 
 while (1)
 
 {
 
 /* USER CODE END WHILE */
 
 
 /* USER CODE BEGIN 3 */
 
 if(index_no >= 30)
 
 break;
 
 HAL_Delay(1);
 
 
 }
 
 HAL_TIM_Base_Stop(&htim6);//start blink timer
 
 HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
 
 HAL_ADC_Stop_IT(&hadc3);
 
 for(i=0;i<ADC_ARRY_SIZE;i++)
 
 ladc_vals[i] = adc_vals[i];
 
 for(;;);
 
}

This topic has been closed for replies.
Best answer by PRedd.111

The issue in ADC setup. The sampling cycles were too low at 1.5 cycles. It needed at least 19 cycles to get a non zero value.

3 replies

TDK
Super User
September 29, 2019

If index_no is modified in an interrupt you should define it as volatile.

"If you feel a post has answered your question, please click ""Accept as Solution""."
PRedd.111
PRedd.111Author
Associate III
September 30, 2019

Tried it. Same issue.​

Tesla DeLorean
Guru
September 29, 2019

How are we supposed to debug this?

It won't advance the pointer for an indeterminate time if the ADC returns zero.

How do you know these are invalid values? Do have some plot or independent capture of the signals you can align?

A more rational approach to this is to use DMA into the array, and trigger the ADC directly with the TIM

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
PRedd.111
PRedd.111Author
Associate III
September 30, 2019

I did put break point on timer irq handler and it never fired.​ That seems to be the main issue.

As for debug, it's quite simple. The task is to get periodic adc samples which is where the timer comes to focus. You can attach a dc supply to a Single ended adc channel and set it up to give 10 mV at 25 mA.​

Tesla DeLorean
Guru
September 30, 2019

This assumes I'm interested in racking this up and testing it, the code's not even buildable.

My point would be to supply enough of your experimental data that one could look at what's happening from afar, and not have to repeat and understand observations I might not be able to reproduce in 2 minutes or less.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
PRedd.111
PRedd.111AuthorAnswer
Associate III
October 23, 2019

The issue in ADC setup. The sampling cycles were too low at 1.5 cycles. It needed at least 19 cycles to get a non zero value.