Spyros Papanastasiou
/
General_purpose_timer_TIM2__PWM_LED
Controlling PWM of LED through direct access of TIM2 timer's registers.
Revision 11:42d5cbbd0f3e, committed 2019-08-02
- Comitter:
- Ladon
- Date:
- Fri Aug 02 13:30:49 2019 +0000
- Parent:
- 10:f80370dd55f8
- Commit message:
- Controlling PWD of LED through direct access of TIM2 timer's registers.
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Fri Aug 02 12:31:03 2019 +0000 +++ b/main.cpp Fri Aug 02 13:30:49 2019 +0000 @@ -9,9 +9,15 @@ // - // Set PA5 as AF1 (TIM2_CH1). // - + // Alternate Function Low Register. + // - GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL5; GPIOA->AFR[0] |= 1 << GPIO_AFRL_AFRL5_Pos; + // Port Output Speed Register. + // - GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5; + // Port Mode Register. + // - GPIOA->MODER &= ~GPIO_MODER_MODER5; GPIOA->MODER |= 2 << GPIO_MODER_MODER5_Pos; } @@ -19,6 +25,7 @@ void inline reset_timer () { // Peripheral Reset Register. + // TIM2 timer reset. // - RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; @@ -26,17 +33,35 @@ void inline clock_enable_for_timer () { + reset_timer(); // Peripheral Clock Enable Register. // TIM2 Timer Clock Enable. // - - reset_timer(); RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; } +void inline timer_setup_pwm () +{ + const double duty_cycle = 0.6; + // Capture/ Compare Register 1. + // - + TIM2->CCR1 = TIM2->ARR * duty_cycle; + // Capture/ Compare Mode Register 1. + // Output Compare 1 Mode. + // Output Compare 1 Preload Enable. + // Output Compare 1 Fast Enable. + // - + TIM2->CCMR1 = (0b111 << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE | TIM_CCMR1_OC1FE; + // ^ 0b111 : PWM Mode 2 : On while CCR < ARR, OFF while >=. + // - +} + void inline timer_enable_pwm () { - TIM2->CCR1 = TIM2->ARR * 0.6; - TIM2->CCMR1 = (0b111 << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE | TIM_CCMR1_OC1FE; + timer_setup_pwm(); + // Capture/ Compare Enable Register. + // Capture/ Compare 1 Output Enable. + // - TIM2->CCER = TIM_CCER_CC1E; } @@ -56,9 +81,11 @@ void inline timer_set_period_to (const double& T) { - // Precondition : T <= 59. + // Precondition : T <= 59 (= (2^32 - 1) / 72e6). // - timer_limit_counter_to(72000000 * T); + // ^Explanation : By limiting ARR to 72e6, the counter gets filled in 1sec (at 72Mhz). + // - } void inline timer_enable_interrupt () @@ -66,7 +93,6 @@ // DMA/ Interrupt Enable Register. // Update Interrupt Enable. // - -// TIM2->DIER = TIM_DIER_UIE | TIM_DIER_CC1IE; TIM2->DIER = TIM_DIER_UIE; } @@ -75,10 +101,7 @@ // Control Register 1. // Update Request Source | Counter Enable. // - -// TIM2->CR1 = TIM_CR1_ARPE | TIM_CR1_URS; - TIM2->CR1 = TIM_CR1_URS; -// TIM2->EGR |= TIM_EGR_UG; - TIM2->CR1 |= TIM_CR1_CEN; + TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN; } void inline timer_clear_status () @@ -104,9 +127,7 @@ // - void interrupt_handler () { -// cout << "SR : 0x" << hex << TIM2->SR << endl; timer_clear_status(); -// led_toggle(); } void inline interrupt_enable () @@ -118,19 +139,20 @@ // - } -// -// - -// +void inline timer_init () +{ + clock_enable_for_timer(); + timer_set_period_to(0.1); + timer_enable_interrupt(); + timer_enable_pwm(); + timer_enable(); +} int main () { cout << "Entered main()." << endl; led_init(); - clock_enable_for_timer(); - timer_set_period_to(0.1); - timer_enable_interrupt(); - timer_enable_pwm(); - timer_enable(); + timer_init(); interrupt_enable(); cout << "Exiting main().." << endl; } \ No newline at end of file