Main C source file

This program is a modified version of blinky The full source and support files can be downloaded here. The main C source file includes a system initialization function that turns on clocks for GPIO C and Timer 1. Interrupts are enabled for Timer 1 and its auto reload register is set to 8000. This means that there will be a timer 1 update event every 1 millisecond (approx). At each interrupt, a counter (Count) is incremented. If Count exceeds 1000 the blue LED is toggled on the board. The net result is that the led should come on for 1 second and go off for 1 second.
#include "stm32f05xxx.h"

void ToggleBlueLED();
int Count = 0;

// Interrupt service routines are the same as normal
// subroutines (or C funtions) in Cortex-M micros.
// The following should happen at a rate of 1kHz.
// The following function is associated with the TIM1 interrupt 
// via the interrupt vector table defined in cstartup_M.c 
void Timer1ISR() 
{
  TIM1_SR &= ~BIT0; // clear update interrupt flag
  Count++;
  if (Count > 1000) { // toggle the state of the LED every second
    Count = 0;
    ToggleBlueLED();
  }   
}

void delay(int dly)
{
  while( dly--);
}

void SysInit()
{
  // Set up output port bit for LED
  RCC_AHBENR |= BIT19; // turn on clock for PORTC
  GPIOC_MODER |= BIT16; // Make bit 8 an output  
  // Set up timer
  RCC_APB2ENR |= BIT11; // turn on clock for timer1
  TIM1_ARR = 8000; // reload counter with 8000 at each overflow (equiv to 1ms)
  ISER |= BIT13; // enable timer interrupts in the NVIC
  TIM1_CR1 |= BIT4; // Downcounting    
  TIM1_CR1 |= BIT0; // enable counting    
  TIM1_DIER  |= BIT0; // enable update event (reload event) interrupt  
  enable_interrupts();

}
void ToggleBlueLED() 
{    
  GPIOC_ODR ^= BIT8;
}
int main()
{
  SysInit();
  while(1) {    
    delay(10);    
  }
  return 0;
}

The modified startup.s file


The original startup.s file needs to be modified to so that the interrupt vector for timer 1's ISR points at the Timer1ISR function in the main c file. The modifed section is shown below.
Vector_Table:    
		.word     0x20002000          /* Top of Stack */
/* The interrupt vectors that follow are manually forced to be aligned along
   odd addresses.  The reason for this is that the address for a Thumb instruction
   must always have its LSB set to 1.  This does not mean that the instruction 
   is stored at an odd number address.  The LSB is used as a flag to indicate
   that an ARM (LSB=0) or a Thumb (LSB=1) instruction is being addressed. */
ResetVector:    .word     Reset_Handler+1     /* Reset Handler */
                .word     Default_Handler+1   /* NMI */
                .word     Default_Handler+1   /* Hard Fault */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     Default_Handler+1   /* SVC */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     Default_Handler+1   /* PendSV */
                .word     Default_Handler+1   /* SysTick */
		
/* External interrupt handlers follow */
		.word	  Default_Handler + 1 /* WWDG */
		.word	  Default_Handler + 1 /* PVD */
		.word	  Default_Handler + 1 /* RTC */
		.word	  Default_Handler + 1 /* FLASH */
 		.word	  Default_Handler + 1 /* RCC */
		.word	  Default_Handler + 1 /* EXTI0_1 */
		.word	  Default_Handler + 1 /* EXTI2_3 */
		.word	  Default_Handler + 1 /* EXTI4_15 */
		.word	  Default_Handler + 1 /* TSC */
		.word	  Default_Handler + 1 /* DMA_CH1 */
		.word	  Default_Handler + 1 /* DMA_CH2_3 */
		.word	  Default_Handler + 1 /* DMA_CH4_5 */
		.word	  Default_Handler + 1 /* ADC_COMP */

	.extern	Timer1ISR
		.word	  Timer1ISR /* TIM1_BRK_UP_TRG_COM */

		.word	  Default_Handler + 1 /* TIM1_CC */
		.word	  Default_Handler + 1 /* TIM2 */
		.word	  Default_Handler + 1 /* TIM3 */
		.word	  Default_Handler + 1 /* TIM6_DAC */
		.word	  Default_Handler + 1 /* RESERVED */
		.word	  Default_Handler + 1 /* TIM14 */
		.word	  Default_Handler + 1 /* TIM15 */
  		.word	  Default_Handler + 1 /* TIM16 */
		.word	  Default_Handler + 1 /* TIM17 */
		.word	  Default_Handler + 1 /* I2C1 */
		.word	  Default_Handler + 1 /* I2C2 */
		.word	  Default_Handler + 1 /* SPI1 */
		.word	  Default_Handler + 1 /* SPI2 */
		.word	  Default_Handler + 1 /* USART1 */
		.word	  Default_Handler + 1 /* USART2 */
		.word	  Default_Handler + 1 /* RESERVED */
		.word	  Default_Handler + 1 /* CEC */
 		.word	  Default_Handler + 1 /* RESERVED */