1
\$\begingroup\$

I am using an STM8S105C6 MCU (user guide), specifically a discovery board, with Cosmic C and the standard peripheral library provided by STM.

I have hooked up 2 signals to channels 0 and 1 of the ADC. I then enabled the ADC peripheral as follows:

static void ADC_Config()
{
  GPIO_DeInit(GPIOB);

  GPIO_Init(GPIOB, (GPIO_PIN_0|GPIO_PIN_1), GPIO_MODE_IN_FL_NO_IT);
  
  /* De-Init ADC peripheral*/
  ADC1_DeInit();

  /* Init ADC1 peripheral */
  ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_0, ADC1_PRESSEL_FCPU_D4, ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL0,DISABLE);
    
  ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_1, ADC1_PRESSEL_FCPU_D8, ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL1, DISABLE);
  ADC1_ConversionConfig(ADC1_CONVERSIONMODE_CONTINUOUS,((ADC1_Channel_TypeDef)(ADC1_CHANNEL_0 |ADC1_CHANNEL_1)), ADC1_ALIGN_RIGHT);
    
  /* Enable data storage in buffer */
  ADC1_DataBufferCmd(ENABLE);
    
  ADC1_Cmd(ENABLE);
}

Then, through polling in the main I start the ADC conversion (see code below), but only channel 0 gets updated, while channel 1 remains with the value it had at startup.

while (1)
{
  /* Enable ScanMode */
  ADC1_ScanModeCmd(ENABLE);
    
  /*Start Conversion */
  ADC1_StartConversion();
        
  while (ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE) {};
        
  ADC1_ClearFlag(ADC1_FLAG_EOC);
        
  Conversion_Value[0] = ADC1_GetBufferValue(0);
  Conversion_Value[1] = ADC1_GetBufferValue(1);
        
}

I have been stuck like this for quite a while and I think a new pair of eyes could see what's wrong with the code.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Welcome to EE stack exchange.

As I understand from your code, you're setting up the ADC to do continuous conversions. However, in that mode, only one channel is sampled continuously (Ch0 in your case).

If you want to "scan" through the channels, then you should use the scan mode (continuous scan mode in your case).

Page 432 & 433 of the user manual explain how the scan modes work:

enter image description here

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ Thank you for your reply Rahmany. As I understand it, that's what I've been doing via the Standard Peripheral Library functions. I also tried doing it by setting the corresponding registers with no luck either. \$\endgroup\$
    – Daniel Gil
    Oct 11, 2022 at 6:05
  • \$\begingroup\$ @DanielGil Why do you start your ADC as (normal) continuous and later switch to scan mode after enabling the ADC ? Try setting the scan mode ON before enabling the ADC. \$\endgroup\$
    – Rahmany
    Oct 11, 2022 at 6:53
  • \$\begingroup\$ that function does not "start" the ADC in normal continuous or Scan mode. The ScanMode one just enables the SCAN bit, which is what according to the datasheet you should do in order to activate the adc. \$\endgroup\$
    – Daniel Gil
    Oct 13, 2022 at 6:07
  • \$\begingroup\$ Glad you've found the solution to the problem. But as a general advice when manipulating Mcu peripherals, it's better to activate the peripherals after all the configuration bits have been set (unless the datasheet/user guide says otherwise). This ensures your config bits are taken into account. \$\endgroup\$
    – Rahmany
    Oct 13, 2022 at 7:20
1
\$\begingroup\$

I seem to have figured out what happened. According to the user manual you're not supposed to do bit manipulation to clear the EOC flag in scan mode, instead you should write a byte to the SCR register i.e. use the ADC_Cmd each time you want to poll for the conversion, so the while loop would look like this:

ADC1_Cmd(ENABLE);
        
/* Enable ScanMode */
ADC1_ScanModeCmd(ENABLE);
        
ADC1_ConversionConfig(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_1, ADC1_ALIGN_RIGHT);
    
/*Start Conversion */
ADC1_StartConversion();

while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE){};
        
Conversion_Value[0] = ADC1_GetBufferValue(0);
Conversion_Value[1] = ADC1_GetBufferValue(1);
    
        
ADC1_ClearFlag(ADC1_FLAG_EOC);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.