#define RCC_BASE 0x40021000
#define TIM1_BASE 0x40012C00
#define GPIOA_BASE 0x50000000
// RCC Registers
#define RCC_APB2ENR (*((volatile uint32_t *)(RCC_BASE + 0x40))) // APB2 Peripheral Clock Enable Register
#define RCC_IOPENR (*((volatile uint32_t *)(RCC_BASE + 0x34)))
// TIM1 Registers
#define TIM1_CR1 (*((volatile uint32_t *)(TIM1_BASE + 0x00))) // Control Register 1
#define TIM1_CR2 (*((volatile uint32_t *)(TIM1_BASE + 0x04))) // Control Register 2
#define TIM1_SMCR (*((volatile uint32_t *)(TIM1_BASE + 0x08))) // Slave Mode Control Register
#define TIM1_DIER (*((volatile uint32_t *)(TIM1_BASE + 0x0C))) // DMA/Interrupt Enable Register
#define TIM1_SR (*((volatile uint32_t *)(TIM1_BASE + 0x10))) // Status Register
#define TIM1_EGR (*((volatile uint32_t *)(TIM1_BASE + 0x14))) // Event Generation Register
#define TIM1_CCMR1 (*((volatile uint32_t *)(TIM1_BASE + 0x18))) // Capture/Compare Mode Register 1
#define TIM1_CCER (*((volatile uint32_t *)(TIM1_BASE + 0x20))) // Capture/Compare Enable Register
#define TIM1_CNT (*((volatile uint32_t *)(TIM1_BASE + 0x24))) // Counter
#define TIM1_PSC (*((volatile uint32_t *)(TIM1_BASE + 0x28))) // Prescaler
#define TIM1_ARR (*((volatile uint32_t *)(TIM1_BASE + 0x2C))) // Auto-Reload Register
#define TIM1_CCR1 (*((volatile uint32_t *)(TIM1_BASE + 0x34))) // Capture/Compare Register 1
#define TIM1_BDTR (*((volatile uint32_t *)(TIM1_BASE + 0x44))) // Break and Dead-Time Register
#define GPIOA_MODER (*((volatile uint32_t *)(GPIOA_BASE + 0x00)))
#define GPIOA_AFRL (*((volatile uint32_t *)(GPIOA_BASE + 0x20)))
#define GPIOA_AFRH (*((volatile uint32_t *)(GPIOA_BASE + 0x24)))
void ConfigureAFUserLED()
{
// GPIOA clock enable
RCC_IOPENR |= (1<<0);
// Set PA5 alternate function
GPIOA_MODER &= ~(3 << 16);
GPIOA_MODER |= (2 << 16);
GPIOA_AFRH &= ~(0xF << 0);
GPIOA_AFRH |= (0x2 << 0);
}
void TIM1_Init_OutputCompare(void) {
// 1. Enable TIM1 clock
RCC_APB2ENR |= (1 << 11); // Set bit 0 to enable TIM1 clock
// 2. Configure prescaler and auto-reload
TIM1_CCMR1 &= ~(0xFF);
TIM1_PSC = 15999; // Prescaler: Divide clock by 16000 (assuming 16 MHz input clock)
TIM1_ARR = 499; // Auto-reload: Timer period of 1 second at 1 kHz
TIM1_CCR1 = 199;
TIM1_CCER &= ~(1<<0);
TIM1_CCER &= ~(1<<1);
TIM1_CCMR1 &= ~(3 << 0);
TIM1_CCMR1 |= (0x3 << 4);
TIM1_CCER |= (1 << 0);
TIM1_BDTR |= (1 << 15);
TIM1_CR1 |= (1 << 0);//enable timer
}
int main(void) {
ConfigureAFUserLED();
TIM1_Init_OutputCompare();
while (1) {
// Main loop: Timer runs independently
}
}