/* p6_7.c Demonstrate Nested Interrupts * * TIM3 is setup to interrupt at about 1 Hz. In the interrupt handler, * PB3 is turned on and a delay function of 500 ms is called. * PB3 is turned off at the end of the delay. * * TIM14 is setup to interrupt at about 10 Hz. In the interrupt handler, * PB4 and the LD2 is turned on and a delay function of 25 ms is called. * PB4 and the LD2 is turned off at the end of the delay. * * When TIM3 has the higher priority (the way this code is), the TIM14 * interrupts are blocked by TIM3 interrupt handler and the LED stops * blinking intermittently. You can see their interactions better * with an oscilloscope on PB3 and PB4. * * When TIM14 has the higher priority (you need to switch the priority of * the two timers at the #define statements), the TIM3 interrupt handler is * preempted by TIM14 interrupts and the LED is blinking all the time. * * This program was tested with Keil uVision v5.23 with DFP v2.0.0 */ #include "stm32f0xx.h" void delayMs(int n); /* priority of TIM3 and TIM14 should be between 0 and 3 */ #define PRIO_TIM3 1 #define PRIO_TIM14 2 int main (void) { __disable_irq(); /* global disable IRQs */ RCC->AHBENR |= 0x00020000; /* enable GPIOA clock */ RCC->AHBENR |= 0x00040000; /* enable GPIOB clock */ GPIOA->MODER &= ~0x00000C00; /* pin PA5 (LED) output */ GPIOA->MODER |= 0x00000400; GPIOB->MODER &= ~0x000003C0; /* pins PB3, PB4 output */ GPIOB->MODER |= 0x00000140; /* setup TIM3 */ RCC->APB1ENR |= 0x00000002; /* enable TIM3 clock */ TIM3->PSC = 1000 - 1; /* divided by 1000 */ TIM3->ARR = 7500 - 1; /* divided by 7500 */ TIM3->CR1 = 1; /* enable counter */ TIM3->DIER |= 1; /* enable UIE */ NVIC_SetPriority(TIM3_IRQn, PRIO_TIM3); NVIC_EnableIRQ(TIM3_IRQn); /* enable interrupt in NVIC */ /* setup TIM14 */ RCC->APB1ENR |= 0x00000100; /* enable TIM14 clock */ TIM14->PSC = 1000 - 1; /* divided by 1000 */ TIM14->ARR = 781 - 1; /* divided by 781 */ TIM14->CR1 = 1; /* enable counter */ TIM14->DIER |= 1; /* enable UIE */ NVIC_SetPriority(TIM14_IRQn, PRIO_TIM14); NVIC_EnableIRQ(TIM14_IRQn); /* enable interrupt in NVIC */ __enable_irq(); /* enable interrupt globally */ while(1) { } } void TIM3_IRQHandler(void) { GPIOB->BSRR = 0x00000008; /* turn on PB3 */ delayMs(500); GPIOB->BSRR = 0x00080000; /* turn off PB3 */ TIM3->SR = 0; /* clear UIF */ } void TIM14_IRQHandler(void) { GPIOA->BSRR = 0x00000020; /* turn on LED */ GPIOB->BSRR = 0x00000010; /* turn on PB4 */ delayMs(25); GPIOA->BRR = 0x00000020; /* turn off LED */ GPIOB->BRR = 0x00000010; /* turn off PB4 */ TIM14->SR = 0; /* clear UIF */ } /* 8 MHz SYSCLK */ void delayMs(int n) { int i; for (; n > 0; n--) for (i = 0; i < 1142; i++) ; }