The general structure is valid - I didn't check the bits for you.
I would, however, rearrange the code a little bit differently in order to maximize their reusability:
#define LED_PORT GPIOE //leds on GPIOE
#define LED_DDR GPIOE
#define LED (1<<11) //led on porte.11
#define PIN_SET(port, pins) port->ODR |= (pins) //set pins on port
#define PIN_CLR(port, pins) port->ODR &=~(pins) //clear pins on port
#define PIN_GET(port, pins) ((port->IDR) & (pins)) //read pins on port
#define FPIN_SET(port, pins) port->BSRR = (pins) //fast_st pins on port
#define FPIN_CLR(port, pins port->BRR = (pins) //fast_clear pins on port
#define FPIN_GET(port, pins) PIN_GET(port, pins) //no fast get routines
//initialize the mcu
void mcu_init(void) {
SystemCoreClockUpdate(); //update systemcore clock in case you use non-default settings
RCC->AHBENR |= RCC_AHBENR_GPIOEEN; //enable gpioe clock
//set other rcc gates here too
}
in main
mcu_init(); //reset the mcu
PIN_OUT(LED_DDR, LED); //led as output
while (1) {
PIN_SET(LED_PORT, LED); //set led
delay(5000000);
PIN_CLR(LED_PORT, LED); //clear led
delay(5000000);
}
}
You can put mcu_init() and the associated macros in a .c/.h file to be called on in the future. With this approach you don't have to worry about remembering all those details next time.
GPIOE->OSPEEDR |= (1<<23)|(1<<22);
Alternatively:
GPIOE->OSPEEDR |= (0x03<<22);