cancel
Showing results for 
Search instead for 
Did you mean: 

ADC Scan Mode and PWM Complementary Channel Conflict.

prometus
Visitor

(MCU:STM8AF6223A-TSSOP20 MCU Label: STM8AF6223PDX
Library: SPL V2.2.0

Compiler SDCC:4.5.0 Debugger:stm8-gdb 8.1

Custom Makefile
MCU uses internal oscillator runnnig 16 MHz)

Hi I'm Attila.

When I enable the ADC1 Scan Mode and DataBuffer with ADC_Channel >= ADC1_CHANNEL_2 TIM1_CH2N waveform distorted.

Oscilloscope CH1(Yellow) -> TIM1_CH1N
Oscilloscope CH1(Light Blue) -> TIM1_CH2N

For example when ADC_Init() with ADC1_CHANNEL_2

ADC1_CH2.png

when ADC_Init() with ADC1_CHANNEL_1

ADC1_CH1.png

ADC1_CHANNEL_2 is the AIN2 but Before the operation, i program the option bytes for enable the complementary channels.

prometus_0-1767361751193.png

What causes the distortion?

Best regards.

Bonus.

I also try disable TIM1_CH2N with TIM1_OC2Init() function i realized that ADC sampling effect that pin .

prometus_1-1767361849463.pngprometus_2-1767361860959.png

Some piece of code 

 

void main(void)
{
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
    ADC_Config();
    TIM1_Config();
    ITC_SetSoftwarePriority(ITC_IRQ_ADC1,  ITC_PRIORITYLEVEL_2); 
    TIM1_Cmd(ENABLE);
    TIM1_CtrlPWMOutputs(ENABLE);
    TIM1_SetCompare1(66);
    TIM1_SetCompare2(376);
    TIM1_SetCompare3(1);

}

static void ADC_Config()
{
  /*  Init GPIO for ADC1 */
  GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_IN_FL_NO_IT);

  GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_FL_NO_IT); //20.pin for reading negative current

  /* De-Init ADC peripheral*/
  ADC1_DeInit();

  /* Init ADC2 peripheral */
  ADC1_Init(ADC1_CONVERSIONMODE_SINGLE/*ADC1_CONVERSIONMODE_CONTINUOUS*/, ADC1_CHANNEL_2, ADC1_PRESSEL_FCPU_D2,
            ADC1_EXTTRIG_TIM, /*DISABLE*/ENABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_ALL,
            DISABLE);
            
  /* Enable scan mode and buffering */
  ADC1_ScanModeCmd(ENABLE);
  ADC1_DataBufferCmd(ENABLE);

  /* Enable EOC interrupt */
  ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE); // not ADC1_IT_EOC
  ADC1_Cmd(ENABLE);
  ADC1_SchmittTriggerConfig(ADC1_SCHMITTTRIG_ALL, DISABLE);  // explicitly disable Schmitt on AIN2 = PC4

  ADC1_StartConversion();

}

static void TIM1_Config(void)
{
    TIM1_DeInit();
    CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);  
    GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_FAST); // CH1
    GPIO_Init(GPIOC, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST); // CH1N
    GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_HIGH_FAST); // CH2
    GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST); // CH2N
    TIM1_TimeBaseInit(0, COUNTER_MODE, TIM_PERIOD, PWM_REPETITION_COUNTER);

    TIM1_OC1Init(
      TIM1_OCMODE_PWM2,
      TIM1_OUTPUTSTATE_ENABLE,
      TIM1_OUTPUTNSTATE_ENABLE,
      0,  // CCR2
      TIM1_OCPOLARITY_HIGH,
      TIM1_OCNPOLARITY_HIGH,
      TIM1_OCIDLESTATE_RESET,
      TIM1_OCNIDLESTATE_SET
  );

  TIM1_OC1PreloadConfig(ENABLE);

    TIM1_OC2Init(
      TIM1_OCMODE_PWM2,
      TIM1_OUTPUTSTATE_ENABLE,
      TIM1_OUTPUTNSTATE_ENABLE,
      0,  // CCR2
      TIM1_OCPOLARITY_HIGH,
      TIM1_OCNPOLARITY_HIGH,
      TIM1_OCIDLESTATE_RESET,
      TIM1_OCNIDLESTATE_SET
  );

TIM1_OC2PreloadConfig(ENABLE);
TIM1_OC3Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_DISABLE, TIM1_OUTPUTNSTATE_DISABLE, (uint16_t)1, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_RESET);
TIM1_OC3PreloadConfig(ENABLE);

  TIM1_BDTRConfig(
  TIM1_OSSISTATE_DISABLE,     // OSSI (off-state selection for idle mode)
  TIM1_LOCKLEVEL_1,
  8,                          // Deadtime 
  TIM1_BREAK_DISABLE,         // Break enable
  TIM1_BREAKPOLARITY_LOW,     // Break polarity
  TIM1_AUTOMATICOUTPUT_ENABLE // Automatic output enable
);

 TIM1_SelectOutputTrigger(TIM1_TRGOSOURCE_OC3REF);

}

INTERRUPT_HANDLER(ADC1_IRQHandler, 22)
{
  if (ADC1_GetFlagStatus(ADC1_FLAG_EOC) == SET)
  {
    value_pos = ADC1_GetBufferValue(3); // AIN3 (positive current)
    value_neg = ADC1_GetBufferValue(4); // AIN4 (negative current)

    adc_sample_counter += 1u;

    ADC1_ClearFlag(ADC1_FLAG_EOC);
    if (ADC1_GetFlagStatus(ADC1_FLAG_OVR) == SET) {
      ADC1_ClearFlag(ADC1_FLAG_OVR); // Handle potential overrun
    }
  }
}

 

 

 

0 REPLIES 0