2021-05-05 05:00 PM
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);
}
Solved! Go to Solution.
2021-05-05 06:07 PM
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
2021-05-05 05:06 PM
Should be solid.
Remember Period and Prescaler are passed as N-1
Probably want 2048-1 to be On Frequency
2021-05-05 05:19 PM
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
2021-05-05 06:07 PM
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
2021-05-05 06:24 PM
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
2021-05-05 06:25 PM
Thanks, just verified that it was the clock, and it is the ZI2
2021-05-05 06:37 PM
FYI.
You can change the ST-LinkV3 MCO config to generate the clock from F723 HSE.
But, resulted clock freq becomes 8.33MHz (sigh...)
2021-05-05 07:32 PM
thanks, that will come in handy!