Square wave FSK issue using PWM ouput
Hi All,
I am trying to impliment a frequency shift keying (FSK) routine to represent a each bit of a byte as FSK.
My routine is kind of working (see the IRQ for TIM3 below). My FSK is :
Bit 0 & Start : 3600Hz
Bit 1 & Stop : 1200Hz
This ensures that timing is alway 833.3us, and transisitons only occur at the end of a full cycle (avoiding glitches).
In this example pictured I am sending a 'U' to be encoded (this has a binary value of '0b01010101') so its easy to see the FSK changes.
What I've noticed is that when I change from bit from 0 (3600Hz) to 1 (1200Hz) the output polarity keeps the previous polarity level. This makes it look like last pulse of the 3600Hz waveform is streatched.
My question is, How can I change the polarity of the PWM ouput on each sucessive bit?
Here is my IRQ code:
extern volatile uint8_t transmitting;
extern volatile uint8_t transmit_data;
extern volatile uint8_t bit_count;
extern volatile uint8_t bit_index;
extern volatile uint8_t current_bit;
extern volatile uint8_t Finished_TX; //MD
// Working FSK with Start/Stop bits - To be tested
void TIM3_IRQHandler(void) {
if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE) != RESET) {
__HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE); // Ensure interrupt flag is cleared
HAL_TIM_IRQHandler(&htim3); // Keep HAL processing
if (transmitting)
{
//Toggle pin D07
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_7);
bit_count--; // Reduce cycle count
if (bit_count == 0)
{ // Time to switch to next bit
if (bit_index == -1)
{ // Start bit (Before data transmission)
bit_count = 3; // 3 cycles @ 3600Hz
///bit_count = 4; // 3 cycles @ 3600Hz
htim3.Instance->ARR = (48000000 / 3600) - 1;
htim3.Instance->CCR1 = (htim3.Instance->ARR * 50) / 100;
//htim3.Instance->CCR1 = (htim3.Instance->ARR * 57) / 100;
bit_index++; // Move to first data bit
}
else if (bit_index < 8)
{ // Process next bit in character
current_bit = (transmit_data >> bit_index) & 0x01;
bit_count = current_bit ? 1 : 3; // '1' → 1200Hz (1 cycle), '0' → 3600Hz (3 cycles)
///bit_count = current_bit ? 1 : 4; // '1' → 1200Hz (1 cycle), '0' → 3600Hz (3 cycles)
htim3.Instance->ARR = current_bit ? (48000000 / 1200) - 1 : (48000000 / 3600) - 1;
htim3.Instance->CCR1 = (htim3.Instance->ARR * 50) / 100;
//htim3.Instance->CCR1 = (htim3.Instance->ARR * 57) / 100;
bit_index++; // Move to next bit
}
else
{ // Stop bit handling after last data bit
bit_count = 1;
htim3.Instance->ARR = (48000000 / 1200) - 1; // Stop bit at 1200Hz
htim3.Instance->CCR1 = (htim3.Instance->ARR * 50) / 100;
//htim3.Instance->CCR1 = (htim3.Instance->ARR * 57) / 100;
transmitting = 0; // Ensure transmission reset
bit_index = -1; // Prepare for next transmission
Finished_TX = 1;
printf("Transmission complete!\n");
// Force timer update to ensure it stays at 1200Hz idle
__HAL_TIM_SET_AUTORELOAD(&htim3, htim3.Instance->ARR);
__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
}
}
}
// Ensure TIM3 interrupts remain enabled
__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
}
}