![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Version12.04.18
Fork of Micromouse_beta by
EncoderCounter.cpp@1:d9e840c48b1e, 2018-03-31 (annotated)
- Committer:
- ruesipat
- Date:
- Sat Mar 31 16:45:57 2018 +0000
- Revision:
- 1:d9e840c48b1e
- Parent:
- 0:a9fe4ef404bf
j
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ruesipat | 0:a9fe4ef404bf | 1 | /* |
ruesipat | 0:a9fe4ef404bf | 2 | * EncoderCounter.cpp |
ruesipat | 0:a9fe4ef404bf | 3 | * Copyright (c) 2018, ZHAW |
ruesipat | 0:a9fe4ef404bf | 4 | * All rights reserved. |
ruesipat | 0:a9fe4ef404bf | 5 | */ |
ruesipat | 0:a9fe4ef404bf | 6 | |
ruesipat | 0:a9fe4ef404bf | 7 | #include "EncoderCounter.h" |
ruesipat | 0:a9fe4ef404bf | 8 | |
ruesipat | 0:a9fe4ef404bf | 9 | using namespace std; |
ruesipat | 0:a9fe4ef404bf | 10 | |
ruesipat | 0:a9fe4ef404bf | 11 | /** |
ruesipat | 0:a9fe4ef404bf | 12 | * Creates and initializes the driver to read the quadrature |
ruesipat | 0:a9fe4ef404bf | 13 | * encoder counter of the STM32 microcontroller. |
ruesipat | 0:a9fe4ef404bf | 14 | * @param a the input pin for the channel A. |
ruesipat | 0:a9fe4ef404bf | 15 | * @param b the input pin for the channel B. |
ruesipat | 0:a9fe4ef404bf | 16 | */ |
ruesipat | 1:d9e840c48b1e | 17 | EncoderCounter::EncoderCounter(PinName a, PinName b) |
ruesipat | 1:d9e840c48b1e | 18 | { |
ruesipat | 1:d9e840c48b1e | 19 | |
ruesipat | 0:a9fe4ef404bf | 20 | // check pins |
ruesipat | 1:d9e840c48b1e | 21 | |
ruesipat | 0:a9fe4ef404bf | 22 | if ((a == PA_0) && (b == PA_1)) { |
ruesipat | 1:d9e840c48b1e | 23 | |
ruesipat | 0:a9fe4ef404bf | 24 | // pinmap OK for TIM2 CH1 and CH2 |
ruesipat | 1:d9e840c48b1e | 25 | |
ruesipat | 0:a9fe4ef404bf | 26 | TIM = TIM2; |
ruesipat | 1:d9e840c48b1e | 27 | |
ruesipat | 0:a9fe4ef404bf | 28 | // configure general purpose I/O registers |
ruesipat | 1:d9e840c48b1e | 29 | |
ruesipat | 0:a9fe4ef404bf | 30 | GPIOA->MODER &= ~GPIO_MODER_MODER0; // reset port A0 |
ruesipat | 0:a9fe4ef404bf | 31 | GPIOA->MODER |= GPIO_MODER_MODER0_1; // set alternate mode of port A0 |
ruesipat | 0:a9fe4ef404bf | 32 | GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR0; // reset pull-up/pull-down on port A0 |
ruesipat | 0:a9fe4ef404bf | 33 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_1; // set input as pull-down |
ruesipat | 0:a9fe4ef404bf | 34 | GPIOA->AFR[0] &= ~(0xF << 4*0); // reset alternate function of port A0 |
ruesipat | 0:a9fe4ef404bf | 35 | GPIOA->AFR[0] |= 1 << 4*0; // set alternate funtion 1 of port A0 |
ruesipat | 1:d9e840c48b1e | 36 | |
ruesipat | 0:a9fe4ef404bf | 37 | GPIOA->MODER &= ~GPIO_MODER_MODER1; // reset port A1 |
ruesipat | 0:a9fe4ef404bf | 38 | GPIOA->MODER |= GPIO_MODER_MODER1_1; // set alternate mode of port A1 |
ruesipat | 0:a9fe4ef404bf | 39 | GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR1; // reset pull-up/pull-down on port A1 |
ruesipat | 0:a9fe4ef404bf | 40 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR1_1; // set input as pull-down |
ruesipat | 0:a9fe4ef404bf | 41 | GPIOA->AFR[0] &= ~(0xF << 4*1); // reset alternate function of port A1 |
ruesipat | 0:a9fe4ef404bf | 42 | GPIOA->AFR[0] |= 1 << 4*1; // set alternate funtion 1 of port A1 |
ruesipat | 1:d9e840c48b1e | 43 | |
ruesipat | 0:a9fe4ef404bf | 44 | // configure reset and clock control registers |
ruesipat | 1:d9e840c48b1e | 45 | |
ruesipat | 0:a9fe4ef404bf | 46 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; //reset TIM2 controller |
ruesipat | 0:a9fe4ef404bf | 47 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; |
ruesipat | 1:d9e840c48b1e | 48 | |
ruesipat | 0:a9fe4ef404bf | 49 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // TIM2 clock enable |
ruesipat | 1:d9e840c48b1e | 50 | |
ruesipat | 0:a9fe4ef404bf | 51 | } else if ((a == PA_6) && (b == PC_7)) { |
ruesipat | 1:d9e840c48b1e | 52 | |
ruesipat | 0:a9fe4ef404bf | 53 | // pinmap OK for TIM3 CH1 and CH2 |
ruesipat | 1:d9e840c48b1e | 54 | |
ruesipat | 0:a9fe4ef404bf | 55 | TIM = TIM3; |
ruesipat | 1:d9e840c48b1e | 56 | |
ruesipat | 0:a9fe4ef404bf | 57 | // configure reset and clock control registers |
ruesipat | 1:d9e840c48b1e | 58 | |
ruesipat | 0:a9fe4ef404bf | 59 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // manually enable port C (port A enabled by mbed library) |
ruesipat | 1:d9e840c48b1e | 60 | |
ruesipat | 0:a9fe4ef404bf | 61 | // configure general purpose I/O registers |
ruesipat | 1:d9e840c48b1e | 62 | |
ruesipat | 0:a9fe4ef404bf | 63 | GPIOA->MODER &= ~GPIO_MODER_MODER6; // reset port A6 |
ruesipat | 0:a9fe4ef404bf | 64 | GPIOA->MODER |= GPIO_MODER_MODER6_1; // set alternate mode of port A6 |
ruesipat | 0:a9fe4ef404bf | 65 | GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR6; // reset pull-up/pull-down on port A6 |
ruesipat | 0:a9fe4ef404bf | 66 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR6_1; // set input as pull-down |
ruesipat | 0:a9fe4ef404bf | 67 | GPIOA->AFR[0] &= ~(0xF << 4*6); // reset alternate function of port A6 |
ruesipat | 0:a9fe4ef404bf | 68 | GPIOA->AFR[0] |= 2 << 4*6; // set alternate funtion 2 of port A6 |
ruesipat | 1:d9e840c48b1e | 69 | |
ruesipat | 0:a9fe4ef404bf | 70 | GPIOC->MODER &= ~GPIO_MODER_MODER7; // reset port C7 |
ruesipat | 0:a9fe4ef404bf | 71 | GPIOC->MODER |= GPIO_MODER_MODER7_1; // set alternate mode of port C7 |
ruesipat | 0:a9fe4ef404bf | 72 | GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR7; // reset pull-up/pull-down on port C7 |
ruesipat | 0:a9fe4ef404bf | 73 | GPIOC->PUPDR |= GPIO_PUPDR_PUPDR7_1; // set input as pull-down |
ruesipat | 0:a9fe4ef404bf | 74 | GPIOC->AFR[0] &= ~0xF0000000; // reset alternate function of port C7 |
ruesipat | 0:a9fe4ef404bf | 75 | GPIOC->AFR[0] |= 2 << 4*7; // set alternate funtion 2 of port C7 |
ruesipat | 1:d9e840c48b1e | 76 | |
ruesipat | 0:a9fe4ef404bf | 77 | // configure reset and clock control registers |
ruesipat | 1:d9e840c48b1e | 78 | |
ruesipat | 0:a9fe4ef404bf | 79 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST; //reset TIM3 controller |
ruesipat | 0:a9fe4ef404bf | 80 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST; |
ruesipat | 1:d9e840c48b1e | 81 | |
ruesipat | 0:a9fe4ef404bf | 82 | RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // TIM3 clock enable |
ruesipat | 1:d9e840c48b1e | 83 | |
ruesipat | 0:a9fe4ef404bf | 84 | } else if ((a == PB_6) && (b == PB_7)) { |
ruesipat | 1:d9e840c48b1e | 85 | |
ruesipat | 0:a9fe4ef404bf | 86 | // pinmap OK for TIM4 CH1 and CH2 |
ruesipat | 1:d9e840c48b1e | 87 | |
ruesipat | 0:a9fe4ef404bf | 88 | TIM = TIM4; |
ruesipat | 1:d9e840c48b1e | 89 | |
ruesipat | 0:a9fe4ef404bf | 90 | // configure reset and clock control registers |
ruesipat | 1:d9e840c48b1e | 91 | |
ruesipat | 0:a9fe4ef404bf | 92 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // manually enable port B (port A enabled by mbed library) |
ruesipat | 1:d9e840c48b1e | 93 | |
ruesipat | 0:a9fe4ef404bf | 94 | // configure general purpose I/O registers |
ruesipat | 1:d9e840c48b1e | 95 | |
ruesipat | 0:a9fe4ef404bf | 96 | GPIOB->MODER &= ~GPIO_MODER_MODER6; // reset port B6 |
ruesipat | 0:a9fe4ef404bf | 97 | GPIOB->MODER |= GPIO_MODER_MODER6_1; // set alternate mode of port B6 |
ruesipat | 0:a9fe4ef404bf | 98 | GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR6; // reset pull-up/pull-down on port B6 |
ruesipat | 0:a9fe4ef404bf | 99 | GPIOB->PUPDR |= GPIO_PUPDR_PUPDR6_1; // set input as pull-down |
ruesipat | 0:a9fe4ef404bf | 100 | GPIOB->AFR[0] &= ~(0xF << 4*6); // reset alternate function of port B6 |
ruesipat | 0:a9fe4ef404bf | 101 | GPIOB->AFR[0] |= 2 << 4*6; // set alternate funtion 2 of port B6 |
ruesipat | 1:d9e840c48b1e | 102 | |
ruesipat | 0:a9fe4ef404bf | 103 | GPIOB->MODER &= ~GPIO_MODER_MODER7; // reset port B7 |
ruesipat | 0:a9fe4ef404bf | 104 | GPIOB->MODER |= GPIO_MODER_MODER7_1; // set alternate mode of port B7 |
ruesipat | 0:a9fe4ef404bf | 105 | GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR7; // reset pull-up/pull-down on port B7 |
ruesipat | 0:a9fe4ef404bf | 106 | GPIOB->PUPDR |= GPIO_PUPDR_PUPDR7_1; // set input as pull-down |
ruesipat | 0:a9fe4ef404bf | 107 | GPIOB->AFR[0] &= ~0xF0000000; // reset alternate function of port B7 |
ruesipat | 0:a9fe4ef404bf | 108 | GPIOB->AFR[0] |= 2 << 4*7; // set alternate funtion 2 of port B7 |
ruesipat | 1:d9e840c48b1e | 109 | |
ruesipat | 0:a9fe4ef404bf | 110 | // configure reset and clock control registers |
ruesipat | 1:d9e840c48b1e | 111 | |
ruesipat | 0:a9fe4ef404bf | 112 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM4RST; //reset TIM4 controller |
ruesipat | 0:a9fe4ef404bf | 113 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM4RST; |
ruesipat | 1:d9e840c48b1e | 114 | |
ruesipat | 0:a9fe4ef404bf | 115 | RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // TIM4 clock enable |
ruesipat | 1:d9e840c48b1e | 116 | |
ruesipat | 0:a9fe4ef404bf | 117 | } else { |
ruesipat | 1:d9e840c48b1e | 118 | |
ruesipat | 0:a9fe4ef404bf | 119 | printf("pinmap not found for peripheral\n"); |
ruesipat | 0:a9fe4ef404bf | 120 | } |
ruesipat | 1:d9e840c48b1e | 121 | |
ruesipat | 0:a9fe4ef404bf | 122 | // configure general purpose timer 3 or 4 |
ruesipat | 1:d9e840c48b1e | 123 | |
ruesipat | 0:a9fe4ef404bf | 124 | TIM->CR1 = 0x0000; // counter disable |
ruesipat | 0:a9fe4ef404bf | 125 | TIM->CR2 = 0x0000; // reset master mode selection |
ruesipat | 0:a9fe4ef404bf | 126 | TIM->SMCR = TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0; // counting on both TI1 & TI2 edges |
ruesipat | 0:a9fe4ef404bf | 127 | TIM->CCMR1 = TIM_CCMR1_CC2S_0 | TIM_CCMR1_CC1S_0; |
ruesipat | 0:a9fe4ef404bf | 128 | TIM->CCMR2 = 0x0000; // reset capture mode register 2 |
ruesipat | 0:a9fe4ef404bf | 129 | TIM->CCER = TIM_CCER_CC2E | TIM_CCER_CC1E; |
ruesipat | 0:a9fe4ef404bf | 130 | TIM->CNT = 0x0000; // reset counter value |
ruesipat | 0:a9fe4ef404bf | 131 | TIM->ARR = 0xFFFF; // auto reload register |
ruesipat | 0:a9fe4ef404bf | 132 | TIM->CR1 = TIM_CR1_CEN; // counter enable |
ruesipat | 0:a9fe4ef404bf | 133 | } |
ruesipat | 0:a9fe4ef404bf | 134 | |
ruesipat | 0:a9fe4ef404bf | 135 | EncoderCounter::~EncoderCounter() {} |
ruesipat | 0:a9fe4ef404bf | 136 | |
ruesipat | 0:a9fe4ef404bf | 137 | /** |
ruesipat | 0:a9fe4ef404bf | 138 | * Resets the counter value to zero. |
ruesipat | 0:a9fe4ef404bf | 139 | */ |
ruesipat | 1:d9e840c48b1e | 140 | void EncoderCounter::reset() |
ruesipat | 1:d9e840c48b1e | 141 | { |
ruesipat | 1:d9e840c48b1e | 142 | |
ruesipat | 0:a9fe4ef404bf | 143 | TIM->CNT = 0x0000; |
ruesipat | 0:a9fe4ef404bf | 144 | } |
ruesipat | 0:a9fe4ef404bf | 145 | |
ruesipat | 0:a9fe4ef404bf | 146 | /** |
ruesipat | 0:a9fe4ef404bf | 147 | * Resets the counter value to a given offset value. |
ruesipat | 0:a9fe4ef404bf | 148 | * @param offset the offset value to reset the counter to. |
ruesipat | 0:a9fe4ef404bf | 149 | */ |
ruesipat | 1:d9e840c48b1e | 150 | void EncoderCounter::reset(short offset) |
ruesipat | 1:d9e840c48b1e | 151 | { |
ruesipat | 1:d9e840c48b1e | 152 | |
ruesipat | 0:a9fe4ef404bf | 153 | TIM->CNT = -offset; |
ruesipat | 0:a9fe4ef404bf | 154 | } |
ruesipat | 0:a9fe4ef404bf | 155 | |
ruesipat | 0:a9fe4ef404bf | 156 | /** |
ruesipat | 0:a9fe4ef404bf | 157 | * Reads the quadrature encoder counter value. |
ruesipat | 0:a9fe4ef404bf | 158 | * @return the quadrature encoder counter as a signed 16-bit integer value. |
ruesipat | 0:a9fe4ef404bf | 159 | */ |
ruesipat | 1:d9e840c48b1e | 160 | short EncoderCounter::read() |
ruesipat | 1:d9e840c48b1e | 161 | { |
ruesipat | 1:d9e840c48b1e | 162 | |
ruesipat | 0:a9fe4ef404bf | 163 | return (short)(-TIM->CNT); |
ruesipat | 0:a9fe4ef404bf | 164 | } |
ruesipat | 0:a9fe4ef404bf | 165 | |
ruesipat | 0:a9fe4ef404bf | 166 | /** |
ruesipat | 0:a9fe4ef404bf | 167 | * The empty operator is a shorthand notation of the <code>read()</code> method. |
ruesipat | 0:a9fe4ef404bf | 168 | */ |
ruesipat | 1:d9e840c48b1e | 169 | EncoderCounter::operator short() |
ruesipat | 1:d9e840c48b1e | 170 | { |
ruesipat | 1:d9e840c48b1e | 171 | |
ruesipat | 0:a9fe4ef404bf | 172 | return read(); |
ruesipat | 0:a9fe4ef404bf | 173 | } |