Spyros Papanastasiou
/
General_purpose_timer_TIM2__custom_interrupt_handler
Using CMSIS NVIC functions to set custom timer interrupt handler.
main.cpp
- Committer:
- Ladon
- Date:
- 2019-08-02
- Revision:
- 3:db424769ecca
- Parent:
- 2:7c45a714b991
- Child:
- 4:c52637c8d084
File content as of revision 3:db424769ecca:
//#include <mbed.h> #include "stm32f303xe.h" #include <iostream> #include <iomanip> using namespace std; // Timer functions: // - void inline enable_timer () { TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_URS | TIM_CR1_CEN; } void inline enable_timer_interrupt () { cout << "Setting DIER..." << endl; cout << "DIER was : 0x" << hex << TIM2->DIER << endl; cout << "Status is : 0x" << hex << TIM2->SR << endl; TIM2->DIER = TIM_DIER_UIE; cout << "Set DIER." << endl; } void inline clear_timer_status () { TIM2->SR = 0; } void inline reset_timer () { TIM2->EGR = TIM_EGR_UG; clear_timer_status(); } void inline downscale_timer_by (const unsigned short& v) { cout << "Downscaling counter by : 0x" << hex << 1 + v << endl; TIM2->PSC = v; } void inline downscale_timer_max () { downscale_timer_by(0xFFFF); } void inline limit_timer_counter_to (const unsigned int& v) { cout << "Limiting counter to : 0x" << hex << v << endl; TIM2->ARR = v; } void inline set_interrupt_period_to (const double& T) { limit_timer_counter_to(36000); downscale_timer_by(1999 + (T - 1) * 2e3); // ^This allows : 500us <= T <= 32.768 // The ^former was found by solving : 0 <= 1999 + (T - 1) * 2e3 <= 0xFFFF, for the prescaler register. // - } void inline set_interrupt_period_to_1sec () { set_interrupt_period_to(1); } // GPIOA functions: // - void init_LED () { GPIOA->MODER &= ~GPIO_MODER_MODER5; // Set as output. // - GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos; } void toggle_LED () { GPIOA->ODR ^= GPIO_ODR_5; } // Other functions: // - void inline enable_clock_for_timer () { RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; } // NVIC functions: // - extern "C" void TIM2_IRQHandler (void) { cout << "Interrupt hit!" << endl; clear_timer_status(); toggle_LED(); } void fun () { cout << "Interrupt hit!" << endl; clear_timer_status(); toggle_LED(); } inline void enable_interrupt () { NVIC_SetPriority(TIM2_IRQn, 250); cout << "TIM2_IRQn priority : " << NVIC_GetPriority(TIM2_IRQn) << endl; NVIC_EnableIRQ(TIM2_IRQn); cout << "TIM2_IRQn status : " << NVIC_GetEnableIRQ(TIM2_IRQn) << endl; cout << "TIM2_IRQn pending : " << NVIC_GetPendingIRQ(TIM2_IRQn) << endl; NVIC_SetVector(TIM2_IRQn, (uint32_t) &fun); } // // - // int main () { cout << "Entered main()." << endl; init_LED(); enable_clock_for_timer(); TIM2->ARR = 0xffffffff; TIM2->CR1 = TIM2->CR2 = TIM2->SMCR = TIM2->DIER = TIM2->SR = TIM2->CCMR1 = TIM2->CCMR2 = TIM2->CCER = TIM2->CNT = TIM2->PSC = TIM2->CCR1 = TIM2->CCR2 = TIM2->CCR3 = TIM2->CCR4 = TIM2->DCR = TIM2->DMAR = 0; TIM2->CR1 |= TIM_CR1_UDIS; downscale_timer_max(); limit_timer_counter_to(0x1000); // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec. // - clear_timer_status(); enable_timer_interrupt(); enable_timer(); enable_interrupt(); cout << "Exiting main().." << endl; cout << endl; cout << hex << "Status : 0x" << TIM2->SR << endl << "Count : 0x" << TIM2->CNT << endl; TIM2->CR1 &= ~TIM_CR1_UDIS; while (true) { cout << hex << "Status : 0x" << TIM2->SR << endl << "Count : 0x" << TIM2->CNT << endl; if (TIM2->CNT > 2) TIM2->SR = 0; } }