STM32F4 output on PD15 creating an unwanted PWM signal on PD9
That's because an assignment like GPIOD-&gt;ODR = value sets all 16 port bits at once, so each assignment resets the port bit that the other one has just set.

You can calculate all output pin values, and set them at once

S1S2 = notInj;
// will do later : GPIOD-&gt;ODR = S1S2; //output is now on pin 15
S11S12 = ((comp1&amp;notComp3)&amp;(ssgn&amp;inj)) | ((notComp1&amp;comp3)&amp;(notSsgn&amp;inj));
S11S12 = S11S12 &gt;&gt; 6;
GPIOD-&gt;ODR = S11S12 | S1S2; //output on pin 9 AND 15


or you can mask the port bit values

GPIOD-&gt;ODR = (GPIOD-&gt;ODR &amp; ~GPIO_PIN_15) | S1S2;
// ...
GPIOD-&gt;ODR = (GPIOD-&gt;ODR &amp; ~GPIO_PIN_9) | S11S12;


or use the BSRR register to change individual port bits

GPIOD-&gt;BSRR = S1S2 ? (1 &lt;&lt; 15) : (1 &lt;&lt; (15 + 16));
// ...
GPIOD-&gt;BSRR = S11S12 ? (1 &lt;&lt; 9) : (1 &lt;&lt; (9 + 16));


or figure out the Bit-Banding address of the port bits, and set them directly

#define GPIOD_ODR_OFFSET ((uint32_t)&amp;(GPIOD-&gt;ODR) - (PERIPH_BASE))
#define GPIOD_ODR_BB (PERIPH_BB_BASE + GPIOD_ODR_OFFSET * 32U)
#define GPIOD_ODR_PIN(x) ((volatile uint32_t *)(GPIO_ODR_BB + (x) * 4))
// calculate S1S2 ...
GPIOD_ODR_PIN(15) = S1S2;
// calculate S11S12 ...
GPIOD_ODR_PIN(9) = S11S12;