Based on the info that you have the LED on PC13, I assume you're using the famous Blue Pill board. In that board, LED connection is inverted because of the special limitations of PC13 - that pin should only sink current, not source. So, in order to turn it on, you need to write 0 to corresponding bit of ODR.
Normally, I'm against the usage of magic numbers. But for STM32F103, using hex literals for GPIO configuration is practical, because one single hex digit uniquely defines the pin mode. One can memorize the meaning of hex literals for GPIO settings, and use them in a compact assignment which defines the 8 pins of a GPIO port at once. If you make GPIO configurations only once, you don't need &=
or |=
operators.
Also, prefer using BSRR
instead of ODR
, because it allows atomic modification of output pins.
Here is a LED blink example for Blue Pill board:
//========================================================================
// Includes
//========================================================================
#include "stm32f1xx.h"
#include <stdbool.h>
#include <stdint.h>
//========================================================================
// Local Variables
//========================================================================
volatile uint32_t sysTick = 0;
//========================================================================
// Local Function Prototypes
//========================================================================
void initialize(void);
void delayMs(uint32_t ms);
//========================================================================
// Initialization
//========================================================================
void initialize(void) {
SystemCoreClock = 8000000U;
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN // Enable PortC
| RCC_APB2ENR_AFIOEN; // Enable A.F.Z
// Pin Remaps
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // JTAG is disabled
// GPIO Settings
GPIOC->CRH = 0x44244444; // LED connected to PC13
GPIOC->BSRR = (1 << 13); // LED is inverted, turn it off.
// SysTick Settings
SysTick_Config(SystemCoreClock / 1000);
// Initialization Done Signal
GPIOC->BSRR = (1 << (13 + 16));
delayMs(200);
GPIOC->BSRR = (1 << 13);
}
//========================================================================
// Main
//========================================================================
int main(void) {
initialize();
while (true) {
delayMs(500);
GPIOC->BSRR = (1 << (13 + 16));
delayMs(500);
GPIOC->BSRR = (1 << 13);
}
}
//========================================================================
// Interrupt Handlers
//========================================================================
void SysTick_Handler(void)
{
++sysTick;
}
//========================================================================
// Local Functions
//========================================================================
void delayMs(uint32_t ms) {
uint32_t start = sysTick;
while (sysTick - start < ms);
}