cancel
Showing results for 
Search instead for 
Did you mean: 

2 Channel Frequency Generator With Phase Shift

ozkenali
Visitor

Hello to all,

I want to make frequency generator with STM32 Nucleo F746ZG board. I am using PC8 and PC9 output. 

Frequency will begin with 100 kHz both output and during 2 secons it will increase to 400 kHz. Duty ratio always same. And between PC8 and PC9, I want to 180 degree phase shift. 

My codes are working with each output. I am using osiloscope PC8-GND it's ok. With PC9-GND it's ok. But when measured PC8 - PC9 with osiloscope nothing show in my osiloscope. Probably phase shift not exists. 

My codes are in below. Anybody show me where is the my mistake? Or any other suggestion to make phase shift in two output? Thanks.

 

#include "main.h"
#include "string.h"
#include "stm32f7xx_hal.h"

uint32_t period_start = 9; // Starting period for 100 kHz
uint32_t period_end = 2; // Ending period for 400 kHz
uint32_t total_duration_ms = 2000; // Total duration for frequency increase (2 seconds)
uint32_t steps = 100; // Total number of steps for frequency increase
uint32_t step_duration_ms; // Duration of each step
uint32_t current_period = 9; // Current period
uint32_t current_step = 0; // Current step

int main(void)
{
step_duration_ms = total_duration_ms / steps;

HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ETH_Init();
MX_USART3_UART_Init();
MX_USB_OTG_FS_PCD_Init();
MX_TIM3_Init();

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // PC8 (TIM3_CH3)
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); // PC9 (TIM3_CH4)

while (current_step < steps)
{
// Linear frequency increase: period is calculated at each step
current_period = period_start - ((period_start - period_end) * current_step) / steps;

// Set 10% duty cycle for PC8 (TIM3_CH3)
__HAL_TIM_SET_AUTORELOAD(&htim3, current_period); // Period is the same for both channels
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, current_period / 10); // 10% duty cycle

// Set 10% duty cycle for PC9 and add 90-degree phase shift (TIM3_CH4)
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, current_period / 10); // 10% duty cycle
__HAL_TIM_SET_COUNTER(&htim3, current_period / 2); // Counter is set to one-fourth of the period for a 90-degree phase shift

// Wait for the duration of the step before moving to the next frequency step
HAL_Delay(step_duration_ms);

current_step++;
}
}

2 REPLIES 2
TDK
Guru

> But when measured PC8 - PC9 with osiloscope nothing show in my osiloscope.

Are you connecting GND on the scope to PC9? That won't work well. What does "nothing" mean here? Scopes measure voltages, "nothing" is not a voltage measurement. Is the voltage 0? How exactly are things connected?

> uint32_t period_start = 9; // Starting period for 100 kHz
> uint32_t period_end = 2; // Ending period for 400 kHz

> __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, current_period / 10); // 10% duty cycle

Not enough resolution there to be useful. With integer division, 9/10 = 2/10 = 0. So duty cycle is 0% at all levels.

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

You can't really "shift phase" in this way.

You can use TOGGLE mode, and adjust the relative phase of CCR1 vs CCR2

There's also PWM1 vs PWM2 mode,PWM1 asserts at 0, and dis-asserts at CCRx, where as PWM2 dis-asserts at 0, and asserts at CCRx

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