cancel
Showing results for 
Search instead for 
Did you mean: 

ADC 1 problem with STM8S-Discovery

u23
Senior
Posted on May 26, 2015 at 13:55

Hi,

I have problem with ADC1 conversions on STM8S-Discovery.

I have configured the analogic inputs following:

PB4 - AN4

PB5 - AN5

PB6 - AN6

unsigned char ADC_Config_INT ( void )

{

    

    GPIO_Init(ADC_PORT,ADC_15V_PIN, GPIO_MODE_IN_FL_NO_IT);

    GPIO_Init(ADC_PORT,ADC_CURR_PIN, GPIO_MODE_IN_FL_NO_IT);

    GPIO_Init(ADC_PORT,ADC_5V_PIN, GPIO_MODE_IN_FL_NO_IT);

 

    /* De-Init ADC1 peripheral */

  ADC1_DeInit();

    

  /* Enable EOC interrupt */

  ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);

    

  /* Enable conversion data buffering */

  ADC1_DataBufferCmd(ENABLE);

    

  /* Enable scan mode conversion */

  ADC1_ScanModeCmd(ENABLE);

  /* Init ADC1 peripheral */

    /* ADC1 Channel 4 */

  ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_4, ADC1_PRESSEL_FCPU_D8, \

            ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL4,\

            DISABLE);

                        

    /* ADC1 Channel 5 */

  ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_5, ADC1_PRESSEL_FCPU_D8, \

            ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL5,\

            DISABLE);

                        

    /* ADC1 Channel 6 */

  ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_6, ADC1_PRESSEL_FCPU_D8, \

            ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL6,\

            DISABLE);                       

    

  /* Enable ADC1 */

  ADC1_Cmd(ENABLE);

        

    return 0;

}

the interrupt function code is:

#define ADC_SAMPLES 8

extern volatile uint16_t ValueCh4[ADC_SAMPLES];            

extern volatile uint16_t ValueCh5[ADC_SAMPLES];            

extern volatile uint16_t ValueCh6[ADC_SAMPLES];            

volatile uint8_t Index = 0;

extern uint8_t ArrayEmpty;

/**

  * @brief  ADC1 interrupt routine.

  * @param  None

  * @retval None

  */

 INTERRUPT_HANDLER(ADC1_IRQHandler, 22)

{

            if ( ADC1_GetFlagStatus(ADC1_FLAG_EOC) != RESET )

            {

                ValueCh4[Index] = ADC1_GetBufferValue(4);

                ValueCh5[Index] = ADC1_GetBufferValue(5);

                ValueCh6[Index] = ADC1_GetBufferValue(6);

                // Controlla se ho acquisito un numero sufficiente di campioni

                if( Index >= ADC_SAMPLES )

                        {

                            ArrayEmpty = 1;

                            Index = 0;

                        }    

                else{

                            Index++;

                        }

 

                

                ADC1_ClearFlag(ADC1_FLAG_EOC);

            }    

        

    return;

}

The ''ADC1_GetBufferValue'' function return the value correct the first time only.

If I modified the value on pin PB4 for example, continuos at read the previous value.

Any idea?

Thanks
5 REPLIES 5
u23
Senior
Posted on May 28, 2015 at 14:07

I attached the project.

The ADC interrupt is occurs, but the ''ADC1_GetBufferValue(ADC1_CHANNEL_4)'' not

return the updated value on the channel 4. This function return the read first value.

A

ny suggestions?

Thanks

________________

Attachments :

Project1.rar : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzNB&d=%2Fa%2F0X0000000bKg%2FfMUpHYx5zpJf69vgPIFnEFm63eHgHQ_e.eRcebHDUa4&asPdf=false
u23
Senior
Posted on June 04, 2015 at 12:09

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6l0&d=%2Fa%2F0X0000000buj%2FjUQeQkRoZH8IXlJ4.jBsmRUt0E9vh9WFtPYC34bTGbo&asPdf=false
laith charles
Associate
Posted on December 07, 2016 at 18:05

I am having a similar issue...  I have to restart the program to refresh this value.

Posted on January 10, 2017 at 21:14

You should read ADC chapter in reference manual again. Your continuous scan mode is always convert N channels (from channel 0) automatically. Multi channel c

ontinuous scan is not recommend.

You can combine timer trigger with single mode on each channel, refer post of @LaserElettronicaSRL
Mojzesz Winnetou
Associate
Posted on September 12, 2017 at 10:10

Hi

Problem with conversion in single scan mode is in ADC1->CSR register. After correct conversion it's necessary to reload value of this register by following way:

ADC1->CSR &= (uint8_t)(~ADC1_CSR_CH);
ADC1->CSR |= (uint8_t)(ADC1_CHANNEL_5);
ADC1->CR1 &= (uint8_t)(~ADC1_CR1_CONT);�?�?�?�?�?�?�?

This 3 lines should be placed in ADC1 INTERRUPT_HANDLER after Interrupt flag clear:

 INTERRUPT_HANDLER(ADC1_IRQHandler, 22)
{
 /* Clear interrupt flag */
 ADC1_ClearITPendingBit(ADC1_IT_EOC);
 /* Workaround for ADC ScanMode issue (Reconfig ADC) */
 ADC1->CSR &= (uint8_t)(~ADC1_CSR_CH);
 ADC1->CSR |= (uint8_t)(ADC1_CHANNEL_5);
 ADC1->CR1 &= (uint8_t)(~ADC1_CR1_CONT);
 /* User code */
}�?�?�?�?�?�?�?�?�?�?�?�?�?

Below I show correct ADC configure for single scan mode with external trigger from TIM1 overflow:

/* Init timer 1 */
 TIM1_DeInit(); //deinit first configuration
 TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, TIM1_TOP, 0); //set frequency of timer 1
 TIM1_SelectOutputTrigger(TIM1_TRGOSOURCE_UPDATE); //set TRGO active when UPDATE event
 /* Init ADC */
 ADC1_DeInit(); //deinit first configuration of ADC
 ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, //single conversion mode
 ADC1_CHANNEL_5, //in scan mode, this is the last channel to conversion
 ADC1_PRESSEL_FCPU_D4, //set prescaler to 4 (16MHz / 4 = 4MHz [MAX 6MHz])
 ADC1_EXTTRIG_TIM, //select external trigger from timer 1
 ENABLE, //enable external trigger
 ADC1_ALIGN_RIGHT, //align ADC data to right
 ADC1_SCHMITTTRIG_CHANNEL0, //any Schmit trigger
 DISABLE); //because it's disable
 ADC1_ScanModeCmd(ENABLE); //enable scan mode
 ADC1_DataBufferCmd(ENABLE); //enable buffers for ADC
 ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE); //enable End Of Conversion IT
 ADC1_Cmd(ENABLE); //enable ADC�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

For start conversion we need to start timer and global interrupts:

/* Enable global interrupt flag */ 
enableInterrupts();
/* Enable main measure timer, for ADC triggering */
TIM1_Cmd(ENABLE);�?�?�?�?�?�?�?�?�?�?

Now ADC should work correct in single scan mode with external trigger.