cancel
Showing results for 
Search instead for 
Did you mean: 

contiously reading ADC

torsten2
Associate II
Posted on June 22, 2015 at 17:35

Hello,

I have a tiny application on an STM8L051F3 (current developing hardware is a STM8L152C6), where I need to sample an analog voltage and to send that voltage every once in a while to an i2c bus. To make easy things easy, I just thought of starting the ADC, store the result in the ADCs ISR and restart the ADC from within the ISR. Then use a main loop, to access the sampled voltage and to send it on the i2c bus. Now my problem is, that I do get the ISR served, but I can�t read values that make sense (checked by sending them to a terminal via an UART). I read values that change (in the range ~0x7ed to 0x80d).

According to the documentation, it should be quit simple: Switch on the ADC, select single conversion mode, disable DMA, select the right channel and start conversion. As I�ve read values that have some jitter, I�ve double checked, that I�m using the right channel (pin PB0; Channel 18). What else puzzles me a little bit, is that when I read the ADC1->SR, not only the �End of Conversion� (EOC) bit set, but also the �Overrun�-Bit (OVER). According to the documentation, the Overrun bit is just used in Continuous Conversion mode.

Here is my initializing of the ADC:

void ADC_Init(void)

{

    CLK->PCKENR2 |= 0x01; /* Enable clock to ADC */

    // Switch on ADC

    ADC1->CR1 = 1;

    delay( 2 );

    /* reset all interrupt flags */

    ADC1->SR &= ~0x07;

    /* disable DMA for single conversion */

    ADC1->SQR[1] |= 0x80;

    /* PB0 (channel 18) for STM8L051F3 and STM8L152C6 */

    ADC1->SQR[2] = 1 << (18 - 16);

    /* 12 bit resolution

       Interruptenable for end of conversion

       single conversion

       Conversion start

       ON */

    ADC1->CR1 = 0x09;

    /* conversion start */

    ADC1->CR1 |= 2;

}

and here is the ISR:

void ADCInterruptHandle (void) __interrupt( 18 )

{

    uint8_t low, high;

    low  = ADC1->DRL;

    high = ADC1->DRH;

    voltage = low | ( high << 8 );

    /* conversion start */

    ADC1->CR1 |= 2;

}

Currently in my main loop, I just send `voltage` every second via UART. What could be my problem here? Any example, that comes close to my use case?

Thank you very much in advance for any help, tipp or pointers,

Torsten

#stm8 #adc
1 REPLY 1
torsten2
Associate II
Posted on June 23, 2015 at 08:26

Fortunately, I found the bug. SQR is of cause an array and thus the first element of the array SQR1 has the index 0. So SQR1 from the documentation maps to SQR[ 0 ] in code. A little bit unlucky I think, but that's how it is.

Maybe someone else stumbles over this and finds this thread useful.