Spyros Papanastasiou
/
General_purpose_timer_TIM2__PWM_LED
Controlling PWM of LED through direct access of TIM2 timer's registers.
main.cpp@3:db424769ecca, 2019-08-02 (annotated)
- Committer:
- Ladon
- Date:
- Fri Aug 02 04:16:14 2019 +0000
- Revision:
- 3:db424769ecca
- Parent:
- 2:7c45a714b991
- Child:
- 4:c52637c8d084
First working version, i think..
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ladon | 3:db424769ecca | 1 | //#include <mbed.h> |
Ladon | 3:db424769ecca | 2 | #include "stm32f303xe.h" |
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 | 3:db424769ecca | 13 | TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_OPM | 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 | 3:db424769ecca | 103 | void fun () |
Ladon | 3:db424769ecca | 104 | { |
Ladon | 3:db424769ecca | 105 | cout << "Interrupt hit!" << endl; |
Ladon | 3:db424769ecca | 106 | clear_timer_status(); |
Ladon | 3:db424769ecca | 107 | toggle_LED(); |
Ladon | 3:db424769ecca | 108 | } |
Ladon | 3:db424769ecca | 109 | |
Ladon | 0:12efa8652054 | 110 | inline void enable_interrupt () |
Ladon | 0:12efa8652054 | 111 | { |
Ladon | 3:db424769ecca | 112 | NVIC_SetPriority(TIM2_IRQn, 250); |
Ladon | 3:db424769ecca | 113 | cout << "TIM2_IRQn priority : " << NVIC_GetPriority(TIM2_IRQn) << endl; |
Ladon | 2:7c45a714b991 | 114 | NVIC_EnableIRQ(TIM2_IRQn); |
Ladon | 3:db424769ecca | 115 | cout << "TIM2_IRQn status : " << NVIC_GetEnableIRQ(TIM2_IRQn) << endl; |
Ladon | 3:db424769ecca | 116 | cout << "TIM2_IRQn pending : " << NVIC_GetPendingIRQ(TIM2_IRQn) << endl; |
Ladon | 3:db424769ecca | 117 | NVIC_SetVector(TIM2_IRQn, (uint32_t) &fun); |
Ladon | 0:12efa8652054 | 118 | } |
Ladon | 0:12efa8652054 | 119 | |
Ladon | 0:12efa8652054 | 120 | // |
Ladon | 0:12efa8652054 | 121 | // - |
Ladon | 0:12efa8652054 | 122 | // |
Ladon | 0:12efa8652054 | 123 | |
Ladon | 0:12efa8652054 | 124 | int main () |
Ladon | 0:12efa8652054 | 125 | { |
Ladon | 0:12efa8652054 | 126 | cout << "Entered main()." << endl; |
Ladon | 0:12efa8652054 | 127 | init_LED(); |
Ladon | 2:7c45a714b991 | 128 | enable_clock_for_timer(); |
Ladon | 2:7c45a714b991 | 129 | TIM2->ARR = 0xffffffff; |
Ladon | 2:7c45a714b991 | 130 | TIM2->CR1 = TIM2->CR2 = TIM2->SMCR = TIM2->DIER = TIM2->SR = TIM2->CCMR1 = TIM2->CCMR2 |
Ladon | 2:7c45a714b991 | 131 | = TIM2->CCER = TIM2->CNT = TIM2->PSC = TIM2->CCR1 = TIM2->CCR2 = TIM2->CCR3 |
Ladon | 2:7c45a714b991 | 132 | = TIM2->CCR4 = TIM2->DCR = TIM2->DMAR = 0; |
Ladon | 3:db424769ecca | 133 | TIM2->CR1 |= TIM_CR1_UDIS; |
Ladon | 2:7c45a714b991 | 134 | downscale_timer_max(); |
Ladon | 2:7c45a714b991 | 135 | limit_timer_counter_to(0x1000); |
Ladon | 0:12efa8652054 | 136 | // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec. |
Ladon | 0:12efa8652054 | 137 | // - |
Ladon | 2:7c45a714b991 | 138 | clear_timer_status(); |
Ladon | 3:db424769ecca | 139 | enable_timer_interrupt(); |
Ladon | 2:7c45a714b991 | 140 | enable_timer(); |
Ladon | 2:7c45a714b991 | 141 | enable_interrupt(); |
Ladon | 0:12efa8652054 | 142 | cout << "Exiting main().." << endl; |
Ladon | 0:12efa8652054 | 143 | cout << endl; |
Ladon | 3:db424769ecca | 144 | cout << hex |
Ladon | 3:db424769ecca | 145 | << "Status : 0x" << TIM2->SR << endl |
Ladon | 3:db424769ecca | 146 | << "Count : 0x" << TIM2->CNT << endl; |
Ladon | 3:db424769ecca | 147 | TIM2->CR1 &= ~TIM_CR1_UDIS; |
Ladon | 2:7c45a714b991 | 148 | while (true) |
Ladon | 2:7c45a714b991 | 149 | { |
Ladon | 2:7c45a714b991 | 150 | cout << hex |
Ladon | 2:7c45a714b991 | 151 | << "Status : 0x" << TIM2->SR << endl |
Ladon | 2:7c45a714b991 | 152 | << "Count : 0x" << TIM2->CNT << endl; |
Ladon | 3:db424769ecca | 153 | if (TIM2->CNT > 2) |
Ladon | 3:db424769ecca | 154 | TIM2->SR = 0; |
Ladon | 2:7c45a714b991 | 155 | } |
Ladon | 0:12efa8652054 | 156 | } |