Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
EncoderCounter.cpp@0:4beb2ea291ec, 2020-03-16 (annotated)
- Committer:
- boro
- Date:
- Mon Mar 16 13:12:31 2020 +0000
- Revision:
- 0:4beb2ea291ec
a
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| boro | 0:4beb2ea291ec | 1 | /* |
| boro | 0:4beb2ea291ec | 2 | * EncoderCounter.cpp |
| boro | 0:4beb2ea291ec | 3 | * Copyright (c) 2019, ZHAW |
| boro | 0:4beb2ea291ec | 4 | * All rights reserved. |
| boro | 0:4beb2ea291ec | 5 | * |
| boro | 0:4beb2ea291ec | 6 | * modiefied version to use with Nucleo F767ZI |
| boro | 0:4beb2ea291ec | 7 | */ |
| boro | 0:4beb2ea291ec | 8 | |
| boro | 0:4beb2ea291ec | 9 | #include "EncoderCounter.h" |
| boro | 0:4beb2ea291ec | 10 | |
| boro | 0:4beb2ea291ec | 11 | using namespace std; |
| boro | 0:4beb2ea291ec | 12 | |
| boro | 0:4beb2ea291ec | 13 | /** |
| boro | 0:4beb2ea291ec | 14 | * Creates and initializes the driver to read the quadrature |
| boro | 0:4beb2ea291ec | 15 | * encoder counter of the STM32 microcontroller. |
| boro | 0:4beb2ea291ec | 16 | * @param a the input pin for the channel A. |
| boro | 0:4beb2ea291ec | 17 | * @param b the input pin for the channel B. |
| boro | 0:4beb2ea291ec | 18 | */ |
| boro | 0:4beb2ea291ec | 19 | EncoderCounter::EncoderCounter(PinName a, PinName b) { |
| boro | 0:4beb2ea291ec | 20 | |
| boro | 0:4beb2ea291ec | 21 | // check pins |
| boro | 0:4beb2ea291ec | 22 | |
| boro | 0:4beb2ea291ec | 23 | if ((a == PB_4) && (b == PC_7)) { |
| boro | 0:4beb2ea291ec | 24 | |
| boro | 0:4beb2ea291ec | 25 | // pinmap OK for TIM3 CH1 and CH2 |
| boro | 0:4beb2ea291ec | 26 | |
| boro | 0:4beb2ea291ec | 27 | TIM = TIM3; |
| boro | 0:4beb2ea291ec | 28 | |
| boro | 0:4beb2ea291ec | 29 | // configure reset and clock control registers |
| boro | 0:4beb2ea291ec | 30 | |
| boro | 0:4beb2ea291ec | 31 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // manually enable port C (port A enabled by mbed library) |
| boro | 0:4beb2ea291ec | 32 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // manually enable port B |
| boro | 0:4beb2ea291ec | 33 | |
| boro | 0:4beb2ea291ec | 34 | // configure general purpose I/O registers |
| boro | 0:4beb2ea291ec | 35 | |
| boro | 0:4beb2ea291ec | 36 | GPIOB->MODER &= ~GPIO_MODER_MODER4; // reset port B4 |
| boro | 0:4beb2ea291ec | 37 | GPIOB->MODER |= GPIO_MODER_MODER4_1; // set alternate mode of port B4 |
| boro | 0:4beb2ea291ec | 38 | GPIOB->PUPDR &= ~GPIO_MODER_MODER4; // reset pull-up/pull-down on port B4 |
| boro | 0:4beb2ea291ec | 39 | GPIOB->PUPDR |= GPIO_MODER_MODER4_1; // set input as pull-down |
| boro | 0:4beb2ea291ec | 40 | GPIOB->AFR[0] &= ~(0xF << 4*4); // reset alternate function of port B4 |
| boro | 0:4beb2ea291ec | 41 | GPIOB->AFR[0] |= 2 << 4*4; // set alternate funtion 2 of port B4, AF2 is TIM3_CH1 |
| boro | 0:4beb2ea291ec | 42 | |
| boro | 0:4beb2ea291ec | 43 | GPIOC->MODER &= ~GPIO_MODER_MODER7; // reset port C7 |
| boro | 0:4beb2ea291ec | 44 | GPIOC->MODER |= GPIO_MODER_MODER7_1; // set alternate mode of port C7 |
| boro | 0:4beb2ea291ec | 45 | GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR7; // reset pull-up/pull-down on port C7 |
| boro | 0:4beb2ea291ec | 46 | GPIOC->PUPDR |= GPIO_PUPDR_PUPDR7_1; // set input as pull-down |
| boro | 0:4beb2ea291ec | 47 | GPIOC->AFR[0] &= ~(0xF << 4*7); // reset alternate function of port C7 |
| boro | 0:4beb2ea291ec | 48 | GPIOC->AFR[0] |= 2 << 4*7; // set alternate funtion 2 of port C7, AF2 is TIM3_CH2 |
| boro | 0:4beb2ea291ec | 49 | |
| boro | 0:4beb2ea291ec | 50 | // configure reset and clock control registers |
| boro | 0:4beb2ea291ec | 51 | |
| boro | 0:4beb2ea291ec | 52 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST; //reset TIM3 controller |
| boro | 0:4beb2ea291ec | 53 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST; |
| boro | 0:4beb2ea291ec | 54 | |
| boro | 0:4beb2ea291ec | 55 | RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // TIM3 clock enable |
| boro | 0:4beb2ea291ec | 56 | |
| boro | 0:4beb2ea291ec | 57 | } else if ((a == PA_15) && (b == PB_3)) { |
| boro | 0:4beb2ea291ec | 58 | |
| boro | 0:4beb2ea291ec | 59 | // pinmap OK for TIM2 CH1 and CH2 |
| boro | 0:4beb2ea291ec | 60 | |
| boro | 0:4beb2ea291ec | 61 | TIM = TIM2; |
| boro | 0:4beb2ea291ec | 62 | |
| boro | 0:4beb2ea291ec | 63 | // configure reset and clock control registers |
| boro | 0:4beb2ea291ec | 64 | |
| boro | 0:4beb2ea291ec | 65 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // manually enable port B |
| boro | 0:4beb2ea291ec | 66 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // manually enable port A |
| boro | 0:4beb2ea291ec | 67 | |
| boro | 0:4beb2ea291ec | 68 | // configure general purpose I/O registers |
| boro | 0:4beb2ea291ec | 69 | |
| boro | 0:4beb2ea291ec | 70 | GPIOA->MODER &= ~GPIO_MODER_MODER15; // reset port A15 |
| boro | 0:4beb2ea291ec | 71 | GPIOA->MODER |= GPIO_MODER_MODER15_1; // set alternate mode of port A15 |
| boro | 0:4beb2ea291ec | 72 | GPIOA->PUPDR &= ~GPIO_MODER_MODER15; // reset pull-up/pull-down on port A15 |
| boro | 0:4beb2ea291ec | 73 | GPIOA->PUPDR |= GPIO_MODER_MODER15_1; // set input as pull-down |
| boro | 0:4beb2ea291ec | 74 | GPIOA->AFR[1] &= ~(0xF << 4*7); // reset alternate function of port A15 (port 15 = pin7 AFR High register) |
| boro | 0:4beb2ea291ec | 75 | GPIOA->AFR[1] |= 1 << 4*7; // set alternate funtion 1 of port A15, AF1 is TIM2_CH1 |
| boro | 0:4beb2ea291ec | 76 | |
| boro | 0:4beb2ea291ec | 77 | GPIOB->MODER &= ~GPIO_MODER_MODER3; // reset port B3 |
| boro | 0:4beb2ea291ec | 78 | GPIOB->MODER |= GPIO_MODER_MODER3_1; // set alternate mode of port B3 |
| boro | 0:4beb2ea291ec | 79 | GPIOB->PUPDR &= ~GPIO_MODER_MODER3; // reset pull-up/pull-down on port B3 |
| boro | 0:4beb2ea291ec | 80 | GPIOB->PUPDR |= GPIO_MODER_MODER3_1; // set input as pull-down |
| boro | 0:4beb2ea291ec | 81 | GPIOB->AFR[0] &= ~(0xF << 4*3); // reset alternate function of port B3 |
| boro | 0:4beb2ea291ec | 82 | GPIOB->AFR[0] |= 1 << 4*3; // set alternate funtion 1 of port B3, AF1 is TIM2_CH2 |
| boro | 0:4beb2ea291ec | 83 | |
| boro | 0:4beb2ea291ec | 84 | // configure reset and clock control registers |
| boro | 0:4beb2ea291ec | 85 | |
| boro | 0:4beb2ea291ec | 86 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST; //reset TIM2 controller |
| boro | 0:4beb2ea291ec | 87 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST; |
| boro | 0:4beb2ea291ec | 88 | |
| boro | 0:4beb2ea291ec | 89 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // TIM2 clock enable |
| boro | 0:4beb2ea291ec | 90 | |
| boro | 0:4beb2ea291ec | 91 | } else if ((a == PD_12) && (b == PD_13)) { |
| boro | 0:4beb2ea291ec | 92 | |
| boro | 0:4beb2ea291ec | 93 | // pinmap OK for TIM4 CH1 and CH2 |
| boro | 0:4beb2ea291ec | 94 | |
| boro | 0:4beb2ea291ec | 95 | TIM = TIM4; |
| boro | 0:4beb2ea291ec | 96 | |
| boro | 0:4beb2ea291ec | 97 | // configure reset and clock control registers |
| boro | 0:4beb2ea291ec | 98 | |
| boro | 0:4beb2ea291ec | 99 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // manually enable port D |
| boro | 0:4beb2ea291ec | 100 | |
| boro | 0:4beb2ea291ec | 101 | // configure general purpose I/O registers |
| boro | 0:4beb2ea291ec | 102 | |
| boro | 0:4beb2ea291ec | 103 | GPIOD->MODER &= ~GPIO_MODER_MODER12; // reset port D12 |
| boro | 0:4beb2ea291ec | 104 | GPIOD->MODER |= GPIO_MODER_MODER12_1; // set alternate mode of port D12 |
| boro | 0:4beb2ea291ec | 105 | GPIOD->PUPDR &= ~GPIO_MODER_MODER12; // reset pull-up/pull-down on port D12 |
| boro | 0:4beb2ea291ec | 106 | GPIOD->PUPDR |= GPIO_MODER_MODER12_1; // set input as pull-down |
| boro | 0:4beb2ea291ec | 107 | GPIOD->AFR[1] &= ~(0xF << 4*4); // reset alternate function of port D12 (port 12 = pin4 AFR High register) |
| boro | 0:4beb2ea291ec | 108 | GPIOD->AFR[1] |= 2 << 4*4; // set alternate funtion 2 of port D12, AF2 is TIM4_CH1 |
| boro | 0:4beb2ea291ec | 109 | |
| boro | 0:4beb2ea291ec | 110 | GPIOD->MODER &= ~GPIO_MODER_MODER13; // reset port D13 |
| boro | 0:4beb2ea291ec | 111 | GPIOD->MODER |= GPIO_MODER_MODER13_1; // set alternate mode of port D13 |
| boro | 0:4beb2ea291ec | 112 | GPIOD->PUPDR &= ~GPIO_MODER_MODER13; // reset pull-up/pull-down on port B3D13 |
| boro | 0:4beb2ea291ec | 113 | GPIOD->PUPDR |= GPIO_MODER_MODER13_1; // set input as pull-down |
| boro | 0:4beb2ea291ec | 114 | GPIOD->AFR[1] &= ~(0xF << 4*5); // reset alternate function of port D13 |
| boro | 0:4beb2ea291ec | 115 | GPIOD->AFR[1] |= 2 << 4*5; // set alternate funtion 2 of port D13, AF2 is TIM4_CH2 |
| boro | 0:4beb2ea291ec | 116 | |
| boro | 0:4beb2ea291ec | 117 | // configure reset and clock control registers |
| boro | 0:4beb2ea291ec | 118 | |
| boro | 0:4beb2ea291ec | 119 | RCC->APB1RSTR |= RCC_APB1RSTR_TIM4RST; //reset TIM4 controller |
| boro | 0:4beb2ea291ec | 120 | RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM4RST; |
| boro | 0:4beb2ea291ec | 121 | |
| boro | 0:4beb2ea291ec | 122 | RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // TIM2 clock enable |
| boro | 0:4beb2ea291ec | 123 | |
| boro | 0:4beb2ea291ec | 124 | } else { |
| boro | 0:4beb2ea291ec | 125 | |
| boro | 0:4beb2ea291ec | 126 | printf("pinmap not found for peripheral\n"); |
| boro | 0:4beb2ea291ec | 127 | } |
| boro | 0:4beb2ea291ec | 128 | |
| boro | 0:4beb2ea291ec | 129 | // configure general purpose timer 3 or 4 |
| boro | 0:4beb2ea291ec | 130 | |
| boro | 0:4beb2ea291ec | 131 | TIM->CR1 = 0x0000; // counter disable |
| boro | 0:4beb2ea291ec | 132 | TIM->CR2 = 0x0000; // reset master mode selection |
| boro | 0:4beb2ea291ec | 133 | TIM->SMCR = TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0; // counting on both TI1 & TI2 edges |
| boro | 0:4beb2ea291ec | 134 | TIM->CCMR1 = TIM_CCMR1_CC2S_0 | TIM_CCMR1_CC1S_0; |
| boro | 0:4beb2ea291ec | 135 | TIM->CCMR2 = 0x0000; // reset capture mode register 2 |
| boro | 0:4beb2ea291ec | 136 | TIM->CCER = TIM_CCER_CC2E | TIM_CCER_CC1E; |
| boro | 0:4beb2ea291ec | 137 | TIM->CNT = 0x0000; // reset counter value |
| boro | 0:4beb2ea291ec | 138 | TIM->ARR = 0xFFFF; // auto reload register |
| boro | 0:4beb2ea291ec | 139 | TIM->CR1 = TIM_CR1_CEN; // counter enable |
| boro | 0:4beb2ea291ec | 140 | } |
| boro | 0:4beb2ea291ec | 141 | |
| boro | 0:4beb2ea291ec | 142 | EncoderCounter::~EncoderCounter() {} |
| boro | 0:4beb2ea291ec | 143 | |
| boro | 0:4beb2ea291ec | 144 | /** |
| boro | 0:4beb2ea291ec | 145 | * Resets the counter value to zero. |
| boro | 0:4beb2ea291ec | 146 | */ |
| boro | 0:4beb2ea291ec | 147 | void EncoderCounter::reset() { |
| boro | 0:4beb2ea291ec | 148 | |
| boro | 0:4beb2ea291ec | 149 | TIM->CNT = 0x0000; |
| boro | 0:4beb2ea291ec | 150 | } |
| boro | 0:4beb2ea291ec | 151 | |
| boro | 0:4beb2ea291ec | 152 | /** |
| boro | 0:4beb2ea291ec | 153 | * Resets the counter value to a given offset value. |
| boro | 0:4beb2ea291ec | 154 | * @param offset the offset value to reset the counter to. |
| boro | 0:4beb2ea291ec | 155 | */ |
| boro | 0:4beb2ea291ec | 156 | void EncoderCounter::reset(short offset) { |
| boro | 0:4beb2ea291ec | 157 | |
| boro | 0:4beb2ea291ec | 158 | TIM->CNT = -offset; |
| boro | 0:4beb2ea291ec | 159 | } |
| boro | 0:4beb2ea291ec | 160 | |
| boro | 0:4beb2ea291ec | 161 | /** |
| boro | 0:4beb2ea291ec | 162 | * Reads the quadrature encoder counter value. |
| boro | 0:4beb2ea291ec | 163 | * @return the quadrature encoder counter as a signed 16-bit integer value. |
| boro | 0:4beb2ea291ec | 164 | */ |
| boro | 0:4beb2ea291ec | 165 | short EncoderCounter::read() { |
| boro | 0:4beb2ea291ec | 166 | |
| boro | 0:4beb2ea291ec | 167 | return (short)(-TIM->CNT); |
| boro | 0:4beb2ea291ec | 168 | } |
| boro | 0:4beb2ea291ec | 169 | |
| boro | 0:4beb2ea291ec | 170 | /** |
| boro | 0:4beb2ea291ec | 171 | * The empty operator is a shorthand notation of the <code>read()</code> method. |
| boro | 0:4beb2ea291ec | 172 | */ |
| boro | 0:4beb2ea291ec | 173 | EncoderCounter::operator short() { |
| boro | 0:4beb2ea291ec | 174 | |
| boro | 0:4beb2ea291ec | 175 | return read(); |
| boro | 0:4beb2ea291ec | 176 | } |
| boro | 0:4beb2ea291ec | 177 | |
| boro | 0:4beb2ea291ec | 178 | |
| boro | 0:4beb2ea291ec | 179 |