cancel
Showing results for 
Search instead for 
Did you mean: 

ADC input disturbed by PWM

kristblo
Associate II

I'm having an issue with my STM32F303RE. I'm using CubeMX to initialize ADC1_IN1 as single ended on PA0, and PWM generation on TIM2_CH1 on PA15. Unfortunately, PA0 will OUTPUT a voltage roughly proportional with the duty cycle of the PWM on PA15, i.e. setting the PWM (again, supposed to be on PA15) to 50% duty cycle results in about 1.5V on PA0. The PWM on PA15 is generated correctly. The PA0 voltage looks like a noisy but constant signal, it doesn't have the PWM signal "shape". PA0 is itself compatible with TIM2_CH1, so I guess something is bleeding over somewhere. Please help me fix this programmatically, I'm really not keen on redoing my circuit.

12 REPLIES 12

> On a general note, where would I find such errata? 

Google "stm32f303 errata". I'm sure it's on the product page as well, but google is generally faster.

https://www.st.com/resource/en/errata_sheet/es0204-stm32f303xbc-device-errata-stmicroelectronics.pdf

> Setting the ADC/PA0 pin to RESET_STATE in the GUI does remove the problem.

So probably it was misconfigured. Doesn't make a whole lot of sense to me why. PA0 is in input mode by default. Might want to dig into why that's happening. Step through and find out where the lower two bits in GPIOA_MODER get changed.

When actively debugging, and paused, the "SFRs" window in CubeIDE will show the value of registers. Open it with Window -> Show View -> SFRs.

If you feel a post has answered your question, please click "Accept as Solution".
kristblo
Associate II

Thanks for your input, everyone! The code below shows the init function mapping the timers to their respective pins. They look correct to me, both for TIM2 and TIM15. I haven't been able to actually verify the memory contents as I'm using VSCode which isn't as capable as CubeIDE on that point apparently.

@TDK, There is one point I'd like to emphasize, which after this (albeit incomplete) attempt at debugging has left me even more convinced that this should be in the errata: The signal I'm seeing on PA0 is NOT a PWM signal. It is a noisy, but steady state signal proportional to the PWM duty cycle. I'm feeding my STMF303RE 3.3V, so that means approximately 1.5V at 50% DT. Fwiw I'm running a PWM frequency of 25kHz. I'm also seeing it on both of my two STMs ordered at the same time, so maybe a batch error? PA0 is not supposed to be compatible with DAC, so at no valid config will there be a steady state voltage other than logic high/low on PA0, correct? Then there's the fact that the other driver on TIM15 and ADC2 are initialized similarly as TIM2 and ADC1, and that setup works fine -- again something which repeats for both of my STMs.

 

The circuits for the two drivers are schematically identical, but the layouts are a little bit different for all four (2 driver layouts x 2 PCB designs) drivers. I beeped an unsoldered PCB of one of my two designs, and found no signs of shorts or other manufacturing defects.

If the configurations available from the CubeMX GUI don't represent the actual full "configuration space" for the STM (i.e. it's actually possible to set PA0 as an analog output manually), then I guess that weakens my argument above, but I've all but convinced myself that this is a hardware error at this point.

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspPostInit 0 */

  /* USER CODE END TIM2_MspPostInit 0 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**TIM2 GPIO Configuration
    PA15     ------> TIM2_CH1
    PB3     ------> TIM2_CH2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM2_MspPostInit 1 */

  /* USER CODE END TIM2_MspPostInit 1 */
  }
  else if(timHandle->Instance==TIM15)
  {
  /* USER CODE BEGIN TIM15_MspPostInit 0 */

  /* USER CODE END TIM15_MspPostInit 0 */

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**TIM15 GPIO Configuration
    PA2     ------> TIM15_CH1
    PA3     ------> TIM15_CH2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF9_TIM15;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM15_MspPostInit 1 */

  /* USER CODE END TIM15_MspPostInit 1 */
  }

}

 

> PA0 is not supposed to be compatible with DAC, so at no valid config will there be a steady state voltage other than logic high/low on PA0, correct?

In output mode, or in input mode with a pullup or pulldown, yes. In floating input mode, or analog mode, it's going to have an undefined state and will be subject to interference. I think that's what is happening here.

Doesn't really make sense why R_IPROPI isn't pulling it down though, or why configuring it to "reset state" changes things.

If you feel a post has answered your question, please click "Accept as Solution".