My first STM32 code - please criticize me
On the STM32s, all peripherals are by default disabled and don't get any clock signals. This saves a bunch of power (and forces you to think about interactions between pins as you code). If you want to use GPIOE, you need to tell the STM32 to enable its clock.

1UL &lt;&lt; 21 shifts an unsigned long value of 1 21 bits to the left. 1 &lt;&lt; 21 shifts some number valued at 1, but it's some default type, which may or may not be unsigned long, and you don't necessarily know how wide your system defaults are.  It will vary by platform and compiler. In fact, UL can vary by platform and compiler as well. It is best to use the library typedefs, which are sure things.

(uint32_t)1 &lt;&lt; 21 and (uint64_t)1 &lt;&lt; 21 are unambiguous.