Hi everyone,
I'm working on generating two signals: one that is in phase, and another that's delayed by 90° relative to a reference input signal. I am using an STM32F303K8.
The code technically works, but the output signals are unstable. I've attached a video showing the issue.
I’ve tried reorganizing the code to make it as efficient as possible, but unfortunately, I haven’t seen any improvement. I even considered implementing the logic in assembly, as mentioned in a previous thread, but that approach clearly isn’t feasible.
Has anyone encountered similar behavior? I understand I'm not working with a real-time processor or any high-end hardware, but a 400ns jitter at 72MHz suggests a timing uncertainty of about 30 clock cycles—which seems significant.
Could the issue be related to the PLL? I'm using a 6MHz crystal oscillator that's boosted to 72MHz. Or could it be tied to the code running inside the ISR? After all, 30 clock cycles can be consumed pretty quickly in there.
I'd really appreciate any insights or suggestions on how to improve this. Thanks in advance!
CODE THAT GENERATES THE TWO SQUARE WAVES:
void TIM1_CC_IRQHandler(){
if(TIM1->SR & 1<<1){
TIM1->SR = ~(1<<1); // Clear flag
if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(8+16); // Toggle pin
else GPIOA->BSRR = 1<<8;
TIM1->CCR1 = TIM1->CCR1 + TXpulseWidth/2; // Update compare match
}
else if(TIM1->SR & 1<<2){
TIM1->SR = ~(1<<2); // Clear flag
if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(9+16); // Toggle pin
else GPIOA->BSRR = 1<<9;
TIM1->CCR2 = TIM1->CCR2 + TXpulseWidth/2; // Update compare match
}
}
DISASSEMBLED CODE:
0x08000A7C F6424010 MOVW r0,#0x2C10
0x08000A80 F2C40001 MOVT r0,#0x4001
53: if(TIM1->SR & 1<<1){
54: TIM1->SR = ~(1<<1); // Clear flag
55: if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(8+16); // Toggle pin
56: else GPIOA->BSRR = 1<<8;
57: TIM1->CCR1 = TIM1->CCR1 + TXpulseWidth/2; // Update compare match
58: }
0x08000A84 6801 LDR r1,[r0,#0x00]
0x08000A86 0789 LSLS r1,r1,#30
0x08000A88 F2400110 MOVW r1,#0x10
0x08000A8C F6C40100 MOVT r1,#0x4800
0x08000A90 D410 BMI 0x08000AB4
59: else if(TIM1->SR & 1<<2){
60: TIM1->SR = ~(1<<2); // Clear flag
61: if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(9+16); // Toggle pin
62: else GPIOA->BSRR = 1<<9;
63: TIM1->CCR2 = TIM1->CCR2 + TXpulseWidth/2; // Update compare match
64: }
0x08000A92 6802 LDR r2,[r0,#0x00]
0x08000A94 0752 LSLS r2,r2,#29
65: }
0x08000A96 BF58 IT PL
0x08000A98 4770 BX lr
0x08000A9A F06F0204 MVN r2,#0x04
60: TIM1->SR = ~(1<<2); // Clear flag
0x08000A9E F8402B28 STR r2,[r0],#0x28
61: if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(9+16); // Toggle pin
62: else GPIOA->BSRR = 1<<9;
63: TIM1->CCR2 = TIM1->CCR2 + TXpulseWidth/2; // Update compare match
64: }
0x08000AA2 680A LDR r2,[r1,#0x00]
0x08000AA4 05D2 LSLS r2,r2,#23
0x08000AA6 F04F7200 MOV r2,#0x2000000
0x08000AAA BF58 IT PL
0x08000AAC F44F7200 MOV r2,#0x200
0x08000AB0 E00B B 0x08000ACA
0x08000AB2 BF00 NOP
0x08000AB4 F06F0202 MVN r2,#0x02
54: TIM1->SR = ~(1<<1); // Clear flag
0x08000AB8 F8402B24 STR r2,[r0],#0x24
55: if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(8+16); // Toggle pin
56: else GPIOA->BSRR = 1<<8;
57: TIM1->CCR1 = TIM1->CCR1 + TXpulseWidth/2; // Update compare match
58: }
59: else if(TIM1->SR & 1<<2){
60: TIM1->SR = ~(1<<2); // Clear flag
61: if(GPIOA->IDR & 1<<8) GPIOA->BSRR = 1<<(9+16); // Toggle pin
62: else GPIOA->BSRR = 1<<9;
63: TIM1->CCR2 = TIM1->CCR2 + TXpulseWidth/2; // Update compare match
64: }
0x08000ABC 680A LDR r2,[r1,#0x00]
0x08000ABE 05D2 LSLS r2,r2,#23
0x08000AC0 F04F7280 MOV r2,#0x1000000
0x08000AC4 BF58 IT PL
0x08000AC6 F44F7280 MOV r2,#0x100
0x08000ACA 608A STR r2,[r1,#0x08]
0x08000ACC F2400280 MOVW r2,#0x80
0x08000AD0 F2C20200 MOVT r2,#0x2000
0x08000AD4 6801 LDR r1,[r0,#0x00]
0x08000AD6 6812 LDR r2,[r2,#0x00]
0x08000AD8 EB0272D2 ADD r2,r2,r2,LSR #31
0x08000ADC EB010162 ADD r1,r1,r2,ASR #1
0x08000AE0 6001 STR r1,[r0,#0x00]
65: }