cancel
Showing results for 
Search instead for 
Did you mean: 

Is the MCO signal on Nucleo boards accurate? Inaccurate PWM signal

ABuja.1
Associate II

I'm having some trouble getting an accurate PWM signal from my H743ZI Nucleo board (MB1364C). It is off by about 1%. I am not using an external crystal, I am using the MCO signal from the F723 chip on the same board.

Am I just misconfiguring something? Or is the MCO signal not accurate? I need to generate a 1 ms pulse every 128 ms.

I appreciate any help or suggestions!

#include "main.h"
 
#define time_sync_Pin GPIO_PIN_0
#define time_sync_GPIO_Port GPIOB
 
TIM_HandleTypeDef htim3;
void Error_Handler(void);
void sysclk_config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 24;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void tim_init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
 
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 5999;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 2048;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 16;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  __HAL_RCC_GPIOB_CLK_ENABLE();
  GPIO_InitStruct.Pin = time_sync_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
  HAL_GPIO_Init(time_sync_GPIO_Port, &GPIO_InitStruct);
}
 
int main(void)
{
 
  HAL_Init();
 
  sysclk_config();
  tim_init();
 
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
 
  while (1) {
 
  }
}
 
void Error_Handler(void)
{
  __disable_irq();
  while (1);
}

1 ACCEPTED SOLUTION

Accepted Solutions

The H7 has some fractional PLL options, but you don't look to be using those

You could have it print out the SYSCLK, AHB and APB clocks to see if those look right.

MCO can map out a couple of frequencies

All the output from TIM, etc are going to be integer divisions

If you're using a ZI2 version with the V3 ST-LINK, the clock there isn't at all good (not actually 8 MHz), this is a topic of much complaint

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

7 REPLIES 7

Should be solid.

Remember Period and Prescaler are passed as N-1

Probably want 2048-1 to be On Frequency

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Right, thanks. Good catch! I don't think that accounts for the ~1ms difference I'm seeing. And after fixing this, I'm still getting 992us on time and 125.998 ms off time

The H7 has some fractional PLL options, but you don't look to be using those

You could have it print out the SYSCLK, AHB and APB clocks to see if those look right.

MCO can map out a couple of frequencies

All the output from TIM, etc are going to be integer divisions

If you're using a ZI2 version with the V3 ST-LINK, the clock there isn't at all good (not actually 8 MHz), this is a topic of much complaint

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ABuja.1
Associate II

Short answer, yes, the MCO clock signal is no good - I tried routing the MCO clock signal from a different Discovery board, and I got the expected pwm signal

Thanks, just verified that it was the clock, and it is the ZI2

sirius506
Associate III

FYI.

You can change the ST-LinkV3 MCO config to generate the clock from F723 HSE.

But, resulted clock freq becomes 8.33MHz (sigh...)

0693W00000ANU9nQAH.png

thanks, that will come in handy!