Author Topic: stm32 problem with ADC conversion  (Read 13588 times)

0 Members and 1 Guest are viewing this topic.

Offline mikewaxTopic starter

  • Contributor
  • Posts: 19
  • Country: us
stm32 problem with ADC conversion
« on: March 26, 2017, 03:09:44 am »
can someone check my setup please? in line 1 the MCU, an stm32F070RB, does a conversion and in line 5 it does another one. but the second conversion fails and the program hangs up at line 7. if i suppress line 7 the program will continue uninterrupted.
the ADC register values are shown below.
Code: [Select]
1 ADC1->CR |= (uint32_t)ADC_CR_ADSTART;  // start first conversion
2 count = 0;
3 while(((ADC1->ISR & ADC_ISR_EOC) == (uint32_t)reset) && (count < timeout)) count++; // wait for end of conversion
4 capVL = (uint16_t)ADC1->DR;  // read value
5 ADC1->CR |= (uint32_t)ADC_CR_ADSTART;  // start second conversion
6 count = 0;
7(//) while(((ADC1->ISR & ADC_ISR_EOC) == (uint32_t)reset) && (count < timeout)) count++;
8 capVH = (uint16_t)ADC1->DR;  // read value
« Last Edit: March 26, 2017, 03:11:28 am by mikewax »
 

Offline mbless

  • Regular Contributor
  • *
  • Posts: 227
  • Country: 00
Re: stm32 problem with ADC conversion
« Reply #1 on: March 26, 2017, 05:59:11 pm »
Someone correct me if I wrong, but from what I understand if you're only doing single conversions you have to stop the ADC before starting it again.
« Last Edit: March 26, 2017, 06:04:01 pm by mbless »
 
The following users thanked this post: mikewax

Offline mikewaxTopic starter

  • Contributor
  • Posts: 19
  • Country: us
Re: stm32 problem with ADC conversion
« Reply #2 on: March 26, 2017, 07:33:20 pm »
yes that's what the "while(((ADC1->ISR & ADC_ISR_EOC)" is for, waiting for the End Of Conversion bit to set. but you're not supposed to have to explicitely stop the ADC process. at least not in my experience.
« Last Edit: March 26, 2017, 10:38:41 pm by mikewax »
 

Offline mbless

  • Regular Contributor
  • *
  • Posts: 227
  • Country: 00
Re: stm32 problem with ADC conversion
« Reply #3 on: March 26, 2017, 07:56:03 pm »
I know you're not using the HAL but according to it, you have to call the stop function HAL_ADC_Stop() then call HAL_ADC_Start() to read another value in single, polling mode. See the excerpt from stm32f4xx_hal_adc.c below. A similar questions was asked on stack exchange.

Code: [Select]
[..] 
  (#) ADC driver can be used among three modes: polling, interruption,
      transfer by DMA.   

     *** Polling mode IO operation ***
     =================================
     [..]   
       (+) Start the ADC peripheral using HAL_ADC_Start()
       (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage
           user can specify the value of timeout according to his end application     
       (+) To read the ADC converted values, use the HAL_ADC_GetValue() function.
       (+) Stop the ADC peripheral using HAL_ADC_Stop()
       
     *** Interrupt mode IO operation ***   
     ===================================
     [..]   
       (+) Start the ADC peripheral using HAL_ADC_Start_IT()
       (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine
       (+) At ADC end of conversion HAL_ADC_ConvCpltCallback() function is executed and user can
           add his own code by customization of function pointer HAL_ADC_ConvCpltCallback
       (+) In case of ADC Error, HAL_ADC_ErrorCallback() function is executed and user can
           add his own code by customization of function pointer HAL_ADC_ErrorCallback
       (+) Stop the ADC peripheral using HAL_ADC_Stop_IT()     

     *** DMA mode IO operation ***   
     ==============================
     [..]   
       (+) Start the ADC peripheral using HAL_ADC_Start_DMA(), at this stage the user specify the length
           of data to be transferred at each end of conversion
       (+) At The end of data transfer by HAL_ADC_ConvCpltCallback() function is executed and user can
           add his own code by customization of function pointer HAL_ADC_ConvCpltCallback
       (+) In case of transfer Error, HAL_ADC_ErrorCallback() function is executed and user can
           add his own code by customization of function pointer HAL_ADC_ErrorCallback
       (+) Stop the ADC peripheral using HAL_ADC_Stop_DMA()
 
The following users thanked this post: mikewax

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: stm32 problem with ADC conversion
« Reply #4 on: March 26, 2017, 08:17:16 pm »
Just wait for the ADSTART bit to clear. Should work.
Quote from: RM0091
Bit 2 ADSTART: ADC start conversion command
This bit is set by software to start ADC conversion. Depending on the EXTEN [1:0] configuration bits, a conversion either starts immediately (software trigger configuration) or once a hardware trigger event
occurs (hardware trigger configuration).
It is cleared by hardware:
– In single conversion mode when software trigger is selected (EXTEN=0x0): at the assertion of the
End of Conversion Sequence (EOSEQ) flag.

– In all cases: after the execution of the ADSTP command, at the same time as the ADSTP bit is cleared by hardware.
0: No ADC conversion is ongoing.
1: Write 1 to start the ADC. Read 1 means that the ADC is operating and may be converting.
Note:Software is allowed to set ADSTART only when ADEN=1 and ADDIS=0 (ADC is enabled and there is no pending request to disable the ADC)

Anyway, I recommend setting up a timer triggered sequence and the DMA. You save power by not letting it run free, and you'll still have recent values.
« Last Edit: March 26, 2017, 08:19:06 pm by Jeroen3 »
 
The following users thanked this post: mikewax

Offline mikewaxTopic starter

  • Contributor
  • Posts: 19
  • Country: us
Re: stm32 problem with ADC conversion
« Reply #5 on: March 26, 2017, 08:22:25 pm »
ok i gotta look into that cause i AM using HAL. but that's for the usb, not for the ADC.
the essential code goes like this:
Code: [Select]
uint8_t  i, v;
uint8_t word[8] = { 'w', 'o', 'r', 'd', 32, 32, 32 };
int main(void)
{
// usb setup-----------------
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
// ADC setup-----------------
  ADC1_Config();
  v = 1;

  while (1)
  {
     i = checkVcap(); // <--ADC routine where it hangs
     if(v++ % 25 == 0) VCP_write(word, strlen((const char *)word);// <- usb send word
     HAL_Delay(10);
     v++;
  }
}
the ADC1_Config() came from the standard peripheral library. the usb setup routines came from the (puke) stm32CubeMX library. it didn't occur to me that the HAL functions could interfere.
i'll go back and try that.
thanx.
 

Offline mikewaxTopic starter

  • Contributor
  • Posts: 19
  • Country: us
Re: stm32 problem with ADC conversion
« Reply #6 on: March 26, 2017, 09:01:39 pm »
Just wait for the ADSTART bit to clear. Should work.
well there's a possible solution that i didn't think about. i'll try it. but i would still like to know why it seems that the EOC bit is not setting.


thanx
« Last Edit: March 26, 2017, 10:43:33 pm by mikewax »
 

Offline mikewaxTopic starter

  • Contributor
  • Posts: 19
  • Country: us
Re: stm32 problem with ADC conversion
« Reply #7 on: March 26, 2017, 10:55:56 pm »
Anyway, I recommend setting up a timer triggered sequence and the DMA. You save power by not letting it run free, and you'll still have recent values.
well i'm not using DMA i just read the ADC and calculate the output. it's doing ADC readings at about 100Hz. you think it would save power if i have it disable the ADC between readings?
 

Offline mikewaxTopic starter

  • Contributor
  • Posts: 19
  • Country: us
Re: stm32 problem with ADC conversion
« Reply #8 on: March 26, 2017, 11:07:34 pm »
I know you're not using the HAL but according to it, you have to call the stop function HAL_ADC_Stop() then call HAL_ADC_Start() to read another value in single, polling mode. See the excerpt from stm32f4xx_hal_adc.c below. A similar questions was asked on stack exchange.

thanx for the idea, it did lead me to a rather ambiguous resolution. i Xed out the usb function and ran the program again. Lo and behold, THAT WAS IT! the program stopped hanging at the ADC routine. the usb, it seems, was interfering.
here's where it gets weird. i always repeat the test 2 or 3 times. i re-included the usb function and not only does the program continue to run correctly, it outputs the right #s, so i know the ADC is reading the accurate voltage. so i can't repeat the test because now the original problem is gone.
four days i been at it, and i still have no clue what was wrong.   |O
so the problem is resolved but never solved. i just hope it stays that way.  :phew:
go figure....
and thanx guys for the assistance   :)
« Last Edit: March 26, 2017, 11:12:20 pm by mikewax »
 

Offline rimpi

  • Newbie
  • Posts: 2
  • Country: in
Re: stm32 problem with ADC conversion
« Reply #9 on: September 21, 2018, 04:37:44 pm »
can u plz hlp to make a code for start and stop the counter using adc in stm32f0.
m stuck in this code
 

Offline rimpi

  • Newbie
  • Posts: 2
  • Country: in
Re: stm32 problem with ADC conversion
« Reply #10 on: September 22, 2018, 05:24:46 am »
plz hlp to write code to start n stop counter using adc in stm32
plzzzzz.......
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf