#include <stdint.h>
// Register memory addresses for STM32C0 series
#define RCC_IOPENR (*(volatile uint32_t *)(0x40021034)) // Clock Enable: Wakes up Port A so it can receive power
#define GPIOA_MODER (*(volatile uint32_t *)(0x50000000)) // Mode Register: Configures pins as INPUT or OUTPUT
#define GPIOA_PUPDR (*(volatile uint32_t *)(0x5000000C)) // Resistor Register: Manages internal Pull-Up / Pull-Down settings
#define GPIOA_IDR (*(volatile uint32_t *)(0x50000010)) // Input Register: Reads live HIGH (3.3V) or LOW (0V) signals from pins
#define GPIOA_ODR (*(volatile uint32_t *)(0x50000014)) // Output Register: Sends HIGH (3.3V) or LOW (0V) power commands to pins
// Simple delay function that pauses execution by wasting processor time
void delay(volatile uint32_t count) {
// 'volatile' prevents the compiler from deleting this loop to optimize speed.
// 'while(count--)' runs a loop, subtracting 1 from 'count' until it hits 0.
while(count--) {
// '__asm("nop")' is a raw Assembly command meaning "No Operation".
// It forces the CPU core to waste exactly 1 clock cycle doing absolutely nothing.
__asm("nop");
}
}
int main(void) {
// 1. Enable clock for GPIOA port
RCC_IOPENR |= (1 << 0);
// 2. Configure PA0 (A0) as Output
GPIOA_MODER &= ~(3 << 0);
GPIOA_MODER |= (1 << 0);
// 3. Configure PA1 (A1) as Input
GPIOA_MODER &= ~(3 << 2);
// 4. Clear internal pull-up/down resistors (Not needed because you have an external one!)
GPIOA_PUPDR &= ~(3 << 2);
while (1) {
// 5. FIXED: Added '!' to check if PA1 is LOW (0V / Pressed)
if (!(GPIOA_IDR & (1 << 1))) {
GPIOA_ODR ^= (1 << 0); // Toggle PA0 to blink the blue LED
delay(200000); // Blink pace delay
} else {
GPIOA_ODR &= ~(1 << 0); // Keep LED completely off when not pressed
}
}
}