2015-05-26 04:55 AM
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? Thanks2015-05-28 05:07 AM
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. Any 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=false2015-06-04 03:09 AM
2016-12-07 09:05 AM
I am having a similar issue... I have to restart the program to refresh this value.
2017-01-10 01:14 PM
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 @LaserElettronicaSRL2017-09-12 01:10 AM
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.