Spyros Papanastasiou
/
General_purpose_timer_TIM2__custom_interrupt_handler
Using CMSIS NVIC functions to set custom timer interrupt handler.
main.cpp@2:7c45a714b991, 2019-08-01 (annotated)
- Committer:
- Ladon
- Date:
- Thu Aug 01 07:53:05 2019 +0000
- Revision:
- 2:7c45a714b991
- Parent:
- 1:8d34cf217c0a
- Child:
- 3:db424769ecca
Without interrupt.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ladon | 0:12efa8652054 | 1 | #include <mbed.h> |
Ladon | 0:12efa8652054 | 2 | |
Ladon | 0:12efa8652054 | 3 | #include <iostream> |
Ladon | 0:12efa8652054 | 4 | #include <iomanip> |
Ladon | 0:12efa8652054 | 5 | |
Ladon | 0:12efa8652054 | 6 | using namespace std; |
Ladon | 0:12efa8652054 | 7 | |
Ladon | 0:12efa8652054 | 8 | // Timer functions: |
Ladon | 0:12efa8652054 | 9 | // - |
Ladon | 0:12efa8652054 | 10 | |
Ladon | 2:7c45a714b991 | 11 | void inline enable_timer () |
Ladon | 0:12efa8652054 | 12 | { |
Ladon | 2:7c45a714b991 | 13 | TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN; |
Ladon | 0:12efa8652054 | 14 | } |
Ladon | 0:12efa8652054 | 15 | |
Ladon | 2:7c45a714b991 | 16 | void inline enable_timer_interrupt () |
Ladon | 0:12efa8652054 | 17 | { |
Ladon | 2:7c45a714b991 | 18 | cout << "Setting DIER..." << endl; |
Ladon | 2:7c45a714b991 | 19 | cout << "DIER was : 0x" << hex << TIM2->DIER << endl; |
Ladon | 2:7c45a714b991 | 20 | cout << "Status is : 0x" << hex << TIM2->SR << endl; |
Ladon | 2:7c45a714b991 | 21 | TIM2->DIER = TIM_DIER_UIE; |
Ladon | 2:7c45a714b991 | 22 | cout << "Set DIER." << endl; |
Ladon | 0:12efa8652054 | 23 | } |
Ladon | 0:12efa8652054 | 24 | |
Ladon | 2:7c45a714b991 | 25 | void inline clear_timer_status () |
Ladon | 0:12efa8652054 | 26 | { |
Ladon | 2:7c45a714b991 | 27 | TIM2->SR = 0; |
Ladon | 0:12efa8652054 | 28 | } |
Ladon | 0:12efa8652054 | 29 | |
Ladon | 2:7c45a714b991 | 30 | void inline reset_timer () |
Ladon | 0:12efa8652054 | 31 | { |
Ladon | 2:7c45a714b991 | 32 | TIM2->EGR = TIM_EGR_UG; |
Ladon | 2:7c45a714b991 | 33 | clear_timer_status(); |
Ladon | 0:12efa8652054 | 34 | } |
Ladon | 0:12efa8652054 | 35 | |
Ladon | 2:7c45a714b991 | 36 | void inline downscale_timer_by (const unsigned short& v) |
Ladon | 0:12efa8652054 | 37 | { |
Ladon | 2:7c45a714b991 | 38 | cout << "Downscaling counter by : 0x" << hex << 1 + v << endl; |
Ladon | 2:7c45a714b991 | 39 | TIM2->PSC = v; |
Ladon | 0:12efa8652054 | 40 | } |
Ladon | 0:12efa8652054 | 41 | |
Ladon | 2:7c45a714b991 | 42 | void inline downscale_timer_max () |
Ladon | 0:12efa8652054 | 43 | { |
Ladon | 2:7c45a714b991 | 44 | downscale_timer_by(0xFFFF); |
Ladon | 0:12efa8652054 | 45 | } |
Ladon | 0:12efa8652054 | 46 | |
Ladon | 2:7c45a714b991 | 47 | void inline limit_timer_counter_to (const unsigned int& v) |
Ladon | 0:12efa8652054 | 48 | { |
Ladon | 2:7c45a714b991 | 49 | cout << "Limiting counter to : 0x" << hex << v << endl; |
Ladon | 2:7c45a714b991 | 50 | TIM2->ARR = v; |
Ladon | 0:12efa8652054 | 51 | } |
Ladon | 0:12efa8652054 | 52 | |
Ladon | 0:12efa8652054 | 53 | void inline set_interrupt_period_to (const double& T) |
Ladon | 0:12efa8652054 | 54 | { |
Ladon | 2:7c45a714b991 | 55 | limit_timer_counter_to(36000); |
Ladon | 2:7c45a714b991 | 56 | downscale_timer_by(1999 + (T - 1) * 2e3); |
Ladon | 1:8d34cf217c0a | 57 | // ^This allows : 500us <= T <= 32.768 |
Ladon | 1:8d34cf217c0a | 58 | // The ^former was found by solving : 0 <= 1999 + (T - 1) * 2e3 <= 0xFFFF, for the prescaler register. |
Ladon | 1:8d34cf217c0a | 59 | // - |
Ladon | 0:12efa8652054 | 60 | } |
Ladon | 0:12efa8652054 | 61 | |
Ladon | 0:12efa8652054 | 62 | void inline set_interrupt_period_to_1sec () |
Ladon | 0:12efa8652054 | 63 | { |
Ladon | 0:12efa8652054 | 64 | set_interrupt_period_to(1); |
Ladon | 0:12efa8652054 | 65 | } |
Ladon | 0:12efa8652054 | 66 | |
Ladon | 0:12efa8652054 | 67 | // GPIOA functions: |
Ladon | 0:12efa8652054 | 68 | // - |
Ladon | 0:12efa8652054 | 69 | |
Ladon | 0:12efa8652054 | 70 | void init_LED () |
Ladon | 0:12efa8652054 | 71 | { |
Ladon | 2:7c45a714b991 | 72 | GPIOA->MODER &= ~GPIO_MODER_MODER5; |
Ladon | 2:7c45a714b991 | 73 | // Set as output. |
Ladon | 0:12efa8652054 | 74 | // - |
Ladon | 2:7c45a714b991 | 75 | GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos; |
Ladon | 0:12efa8652054 | 76 | } |
Ladon | 0:12efa8652054 | 77 | |
Ladon | 0:12efa8652054 | 78 | void toggle_LED () |
Ladon | 0:12efa8652054 | 79 | { |
Ladon | 2:7c45a714b991 | 80 | GPIOA->ODR ^= GPIO_ODR_5; |
Ladon | 0:12efa8652054 | 81 | } |
Ladon | 0:12efa8652054 | 82 | |
Ladon | 0:12efa8652054 | 83 | // Other functions: |
Ladon | 0:12efa8652054 | 84 | // - |
Ladon | 0:12efa8652054 | 85 | |
Ladon | 2:7c45a714b991 | 86 | void inline enable_clock_for_timer () |
Ladon | 0:12efa8652054 | 87 | { |
Ladon | 2:7c45a714b991 | 88 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; |
Ladon | 2:7c45a714b991 | 89 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; |
Ladon | 2:7c45a714b991 | 90 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; |
Ladon | 0:12efa8652054 | 91 | } |
Ladon | 0:12efa8652054 | 92 | |
Ladon | 0:12efa8652054 | 93 | // NVIC functions: |
Ladon | 0:12efa8652054 | 94 | // - |
Ladon | 0:12efa8652054 | 95 | |
Ladon | 2:7c45a714b991 | 96 | extern "C" void TIM2_IRQHandler (void) |
Ladon | 0:12efa8652054 | 97 | { |
Ladon | 2:7c45a714b991 | 98 | cout << "Interrupt hit!" << endl; |
Ladon | 2:7c45a714b991 | 99 | clear_timer_status(); |
Ladon | 0:12efa8652054 | 100 | toggle_LED(); |
Ladon | 0:12efa8652054 | 101 | } |
Ladon | 0:12efa8652054 | 102 | |
Ladon | 0:12efa8652054 | 103 | inline void enable_interrupt () |
Ladon | 0:12efa8652054 | 104 | { |
Ladon | 2:7c45a714b991 | 105 | NVIC_SetPriority(TIM2_IRQn, 255); |
Ladon | 2:7c45a714b991 | 106 | NVIC_EnableIRQ(TIM2_IRQn); |
Ladon | 0:12efa8652054 | 107 | } |
Ladon | 0:12efa8652054 | 108 | |
Ladon | 0:12efa8652054 | 109 | // |
Ladon | 0:12efa8652054 | 110 | // - |
Ladon | 0:12efa8652054 | 111 | // |
Ladon | 0:12efa8652054 | 112 | |
Ladon | 0:12efa8652054 | 113 | int main () |
Ladon | 0:12efa8652054 | 114 | { |
Ladon | 0:12efa8652054 | 115 | cout << "Entered main()." << endl; |
Ladon | 0:12efa8652054 | 116 | init_LED(); |
Ladon | 2:7c45a714b991 | 117 | enable_clock_for_timer(); |
Ladon | 2:7c45a714b991 | 118 | TIM2->ARR = 0xffffffff; |
Ladon | 2:7c45a714b991 | 119 | TIM2->CR1 = TIM2->CR2 = TIM2->SMCR = TIM2->DIER = TIM2->SR = TIM2->CCMR1 = TIM2->CCMR2 |
Ladon | 2:7c45a714b991 | 120 | = TIM2->CCER = TIM2->CNT = TIM2->PSC = TIM2->CCR1 = TIM2->CCR2 = TIM2->CCR3 |
Ladon | 2:7c45a714b991 | 121 | = TIM2->CCR4 = TIM2->DCR = TIM2->DMAR = 0; |
Ladon | 2:7c45a714b991 | 122 | downscale_timer_max(); |
Ladon | 2:7c45a714b991 | 123 | limit_timer_counter_to(0x1000); |
Ladon | 0:12efa8652054 | 124 | // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec. |
Ladon | 0:12efa8652054 | 125 | // - |
Ladon | 2:7c45a714b991 | 126 | clear_timer_status(); |
Ladon | 2:7c45a714b991 | 127 | // enable_timer_interrupt(); |
Ladon | 2:7c45a714b991 | 128 | enable_timer(); |
Ladon | 2:7c45a714b991 | 129 | enable_interrupt(); |
Ladon | 0:12efa8652054 | 130 | cout << "Exiting main().." << endl; |
Ladon | 0:12efa8652054 | 131 | cout << endl; |
Ladon | 2:7c45a714b991 | 132 | while (true) |
Ladon | 2:7c45a714b991 | 133 | { |
Ladon | 2:7c45a714b991 | 134 | cout << hex |
Ladon | 2:7c45a714b991 | 135 | << "Status : 0x" << TIM2->SR << endl |
Ladon | 2:7c45a714b991 | 136 | << "Count : 0x" << TIM2->CNT << endl; |
Ladon | 2:7c45a714b991 | 137 | } |
Ladon | 0:12efa8652054 | 138 | } |