Spyros Papanastasiou
/
General_purpose_timer_TIM2__PWM_LED
Controlling PWM of LED through direct access of TIM2 timer's registers.
main.cpp
- Committer:
- Ladon
- Date:
- 2019-08-02
- Revision:
- 4:c52637c8d084
- Parent:
- 3:db424769ecca
- Child:
- 5:3ee6e0113b41
File content as of revision 4:c52637c8d084:
//#include <mbed.h> #include "stm32f303xe.h" #include <iostream> #include <iomanip> using namespace std; // Timer functions: // - void inline timer_enable () { TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN; } void inline timer_enable_interrupt () { TIM2->DIER = TIM_DIER_UIE; } void inline timer_clear_status () { TIM2->SR = 0; } void inline timer_downscale_by (const unsigned short& v) { cout << "Downscaling counter by : 0x" << hex << 1 + v << endl; TIM2->PSC = v; } void inline timer_downscale_by_max () { timer_downscale_by(0xFFFF); } void inline timer_limit_counter_to (const unsigned int& v) { cout << "Limiting counter to : 0x" << hex << v << endl; TIM2->ARR = v; } void inline timer_set_interrupt_period_to (const double& T) { timer_limit_counter_to(36000); timer_downscale_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. // - } // GPIOA functions: // - void led_init () { GPIOA->MODER &= ~GPIO_MODER_MODER5; // Set as output. // - GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos; } void led_toggle () { GPIOA->ODR ^= GPIO_ODR_5; } // Other functions: // - void inline clock_enable_for_timer () { RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; } // NVIC functions: // - /* // I couldn 't get TIM2_IRQHandler() to work; probably wrong name. // - extern "C" void TIM2_IRQHandler (void) { cout << "Interrupt hit!" << endl; clear_timer_status(); toggle_LED(); } */ void interrupt_handler () { cout << "Interrupt hit!" << endl; timer_clear_status(); led_toggle(); } inline void interrupt_enable () { // NVIC_SetPriority(TIM2_IRQn, 250); NVIC_EnableIRQ(TIM2_IRQn); NVIC_SetVector(TIM2_IRQn, (uint32_t) &interrupt_handler); } // // - // int main () { cout << "Entered main()." << endl; led_init(); clock_enable_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; timer_downscale_by_max(); timer_limit_counter_to(0x1000); // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec. // - timer_clear_status(); timer_enable_interrupt(); timer_enable(); interrupt_enable(); 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; } }