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.
Fork of HardwareQuadratureEncoderABZ by
main.cpp@1:e63be50a9453, 2015-01-25 (annotated)
- Committer:
- misan
- Date:
- Sun Jan 25 23:01:30 2015 +0000
- Revision:
- 1:e63be50a9453
- Parent:
- 0:25c34018702c
Adapting Nigel Webb code for my encoders, using internal pullups and a diode for the connection of the encoder inputs. No index signal though.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Nigel945426 | 0:25c34018702c | 1 | #include "mbed.h" |
| Nigel945426 | 0:25c34018702c | 2 | |
| Nigel945426 | 0:25c34018702c | 3 | // Hardware Quadrature Encoder ABZ for Nucleo F401RE |
| Nigel945426 | 0:25c34018702c | 4 | // Output on debug port to host PC @ 9600 baud |
| Nigel945426 | 0:25c34018702c | 5 | // |
| Nigel945426 | 0:25c34018702c | 6 | // By Nigel Webb, November 2014 |
| misan | 1:e63be50a9453 | 7 | // Modified by Miguel Sánchez, January 2015 |
| Nigel945426 | 0:25c34018702c | 8 | |
| Nigel945426 | 0:25c34018702c | 9 | /* Connections |
| Nigel945426 | 0:25c34018702c | 10 | PA_0 = Encoder A |
| Nigel945426 | 0:25c34018702c | 11 | PA_1 = Encoder B |
| Nigel945426 | 0:25c34018702c | 12 | PA_4 = Encoder Z |
| Nigel945426 | 0:25c34018702c | 13 | */ |
| Nigel945426 | 0:25c34018702c | 14 | |
| misan | 1:e63be50a9453 | 15 | // ZPulse(PA_4) ; // Setup Interrupt for Z Pulse --> no index needed here |
| misan | 1:e63be50a9453 | 16 | |
| misan | 1:e63be50a9453 | 17 | DigitalIn A(PA_0); |
| misan | 1:e63be50a9453 | 18 | DigitalIn B(PA_1); |
| misan | 1:e63be50a9453 | 19 | |
| Nigel945426 | 0:25c34018702c | 20 | |
| Nigel945426 | 0:25c34018702c | 21 | void EncoderInitialise(void) { |
| Nigel945426 | 0:25c34018702c | 22 | // configure GPIO PA0 & PA1 as inputs for Encoder |
| Nigel945426 | 0:25c34018702c | 23 | RCC->AHB1ENR |= 0x00000001; // Enable clock for GPIOA |
| Nigel945426 | 0:25c34018702c | 24 | |
| Nigel945426 | 0:25c34018702c | 25 | GPIOA->MODER |= GPIO_MODER_MODER0_1 | GPIO_MODER_MODER1_1 ; //PA0 & PA1 as Alternate Function /*!< GPIO port mode register, Address offset: 0x00 */ |
| Nigel945426 | 0:25c34018702c | 26 | GPIOA->OTYPER |= GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 ; //PA0 & PA1 as Inputs /*!< GPIO port output type register, Address offset: 0x04 */ |
| Nigel945426 | 0:25c34018702c | 27 | GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 ; // Low speed /*!< GPIO port output speed register, Address offset: 0x08 */ |
| Nigel945426 | 0:25c34018702c | 28 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_1 | GPIO_PUPDR_PUPDR1_1 ; // Pull Down /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ |
| Nigel945426 | 0:25c34018702c | 29 | GPIOA->AFR[0] |= 0x00000011 ; // AF01 for PA0 & PA1 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ |
| Nigel945426 | 0:25c34018702c | 30 | GPIOA->AFR[1] |= 0x00000000 ; // /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ |
| Nigel945426 | 0:25c34018702c | 31 | |
| Nigel945426 | 0:25c34018702c | 32 | // configure TIM2 as Encoder input |
| Nigel945426 | 0:25c34018702c | 33 | RCC->APB1ENR |= 0x00000001; // Enable clock for TIM2 |
| Nigel945426 | 0:25c34018702c | 34 | |
| Nigel945426 | 0:25c34018702c | 35 | TIM2->CR1 = 0x0001; // CEN(Counter ENable)='1' < TIM control register 1 |
| Nigel945426 | 0:25c34018702c | 36 | TIM2->SMCR = 0x0003; // SMS='011' (Encoder mode 3) < TIM slave mode control register |
| Nigel945426 | 0:25c34018702c | 37 | TIM2->CCMR1 = 0xF1F1; // CC1S='01' CC2S='01' < TIM capture/compare mode register 1 |
| Nigel945426 | 0:25c34018702c | 38 | TIM2->CCMR2 = 0x0000; // < TIM capture/compare mode register 2 |
| Nigel945426 | 0:25c34018702c | 39 | TIM2->CCER = 0x0011; // CC1P CC2P < TIM capture/compare enable register |
| Nigel945426 | 0:25c34018702c | 40 | TIM2->PSC = 0x0000; // Prescaler = (0+1) < TIM prescaler |
| Nigel945426 | 0:25c34018702c | 41 | TIM2->ARR = 0xffffffff; // reload at 0xfffffff < TIM auto-reload register |
| Nigel945426 | 0:25c34018702c | 42 | |
| Nigel945426 | 0:25c34018702c | 43 | TIM2->CNT = 0x0000; //reset the counter before we use it |
| Nigel945426 | 0:25c34018702c | 44 | } |
| Nigel945426 | 0:25c34018702c | 45 | |
| misan | 1:e63be50a9453 | 46 | |
| misan | 1:e63be50a9453 | 47 | void EncoderInitialiseTIM3(void) { |
| misan | 1:e63be50a9453 | 48 | // configure GPIO PA0 & PA1 aka A0 & A1 as inputs for Encoder |
| misan | 1:e63be50a9453 | 49 | // Enable clock for GPIOA |
| misan | 1:e63be50a9453 | 50 | __GPIOA_CLK_ENABLE(); //equivalent from hal_rcc.h |
| misan | 1:e63be50a9453 | 51 | |
| misan | 1:e63be50a9453 | 52 | //stm32f4xx.h |
| misan | 1:e63be50a9453 | 53 | GPIOA->MODER |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1 ; //PA6 & PA7 as Alternate Function /*!< GPIO port mode register, Address offset: 0x00 */ |
| misan | 1:e63be50a9453 | 54 | GPIOA->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 ; //PA6 & PA7 as Inputs /*!< GPIO port output type register, Address offset: 0x04 */ |
| misan | 1:e63be50a9453 | 55 | GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 ; //Low speed /*!< GPIO port output speed register, Address offset: 0x08 */ |
| misan | 1:e63be50a9453 | 56 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR6_1 | GPIO_PUPDR_PUPDR7_1 ; //Pull Down /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ |
| misan | 1:e63be50a9453 | 57 | GPIOA->AFR[0] |= 0x22000000 ; //AF02 for PA6 & PA7 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ |
| misan | 1:e63be50a9453 | 58 | GPIOA->AFR[1] |= 0x00000000 ; //nibbles here refer to gpio8..15 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ |
| misan | 1:e63be50a9453 | 59 | |
| misan | 1:e63be50a9453 | 60 | // configure TIM3 as Encoder input |
| misan | 1:e63be50a9453 | 61 | // Enable clock for TIM3 |
| misan | 1:e63be50a9453 | 62 | __TIM3_CLK_ENABLE(); |
| misan | 1:e63be50a9453 | 63 | |
| misan | 1:e63be50a9453 | 64 | TIM3->CR1 = 0x0001; // CEN(Counter ENable)='1' < TIM control register 1 |
| misan | 1:e63be50a9453 | 65 | TIM3->SMCR = TIM_ENCODERMODE_TI12; // SMS='011' (Encoder mode 3) < TIM slave mode control register |
| misan | 1:e63be50a9453 | 66 | TIM3->CCMR1 = 0xF1F1; // CC1S='01' CC2S='01' < TIM capture/compare mode register 1 |
| misan | 1:e63be50a9453 | 67 | TIM3->CCMR2 = 0x0000; // < TIM capture/compare mode register 2 |
| misan | 1:e63be50a9453 | 68 | TIM3->CCER = 0x0011; // CC1P CC2P < TIM capture/compare enable register |
| misan | 1:e63be50a9453 | 69 | TIM3->PSC = 0x0000; // Prescaler = (0+1) < TIM prescaler |
| misan | 1:e63be50a9453 | 70 | TIM3->ARR = 0xffffffff; // reload at 0xfffffff < TIM auto-reload register |
| misan | 1:e63be50a9453 | 71 | |
| misan | 1:e63be50a9453 | 72 | TIM3->CNT = 0x0000; //reset the counter before we use it |
| misan | 1:e63be50a9453 | 73 | } |
| misan | 1:e63be50a9453 | 74 | |
| misan | 1:e63be50a9453 | 75 | void EncoderInitialiseTIM4(void) { |
| misan | 1:e63be50a9453 | 76 | //PB6 PB7 aka D10 MORPHO_PB7 |
| misan | 1:e63be50a9453 | 77 | // Enable clock for GPIOA |
| misan | 1:e63be50a9453 | 78 | __GPIOB_CLK_ENABLE(); //equivalent from hal_rcc.h |
| misan | 1:e63be50a9453 | 79 | |
| misan | 1:e63be50a9453 | 80 | //stm32f4xx.h |
| misan | 1:e63be50a9453 | 81 | GPIOB->MODER |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1 ; //PB6 & PB7 as Alternate Function /*!< GPIO port mode register, Address offset: 0x00 */ |
| misan | 1:e63be50a9453 | 82 | GPIOB->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 ; //PB6 & PB7 as Inputs /*!< GPIO port output type register, Address offset: 0x04 */ |
| misan | 1:e63be50a9453 | 83 | GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 ; //Low speed /*!< GPIO port output speed register, Address offset: 0x08 */ |
| misan | 1:e63be50a9453 | 84 | GPIOB->PUPDR |= GPIO_PUPDR_PUPDR6_1 | GPIO_PUPDR_PUPDR7_1 ; //Pull Down /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ |
| misan | 1:e63be50a9453 | 85 | GPIOB->AFR[0] |= 0x22000000 ; //AF02 for PB6 & PB7 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ |
| misan | 1:e63be50a9453 | 86 | GPIOB->AFR[1] |= 0x00000000 ; //nibbles here refer to gpio8..15 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ |
| misan | 1:e63be50a9453 | 87 | |
| misan | 1:e63be50a9453 | 88 | // configure TIM4 as Encoder input |
| misan | 1:e63be50a9453 | 89 | // Enable clock for TIM4 |
| misan | 1:e63be50a9453 | 90 | __TIM4_CLK_ENABLE(); |
| misan | 1:e63be50a9453 | 91 | |
| misan | 1:e63be50a9453 | 92 | TIM4->CR1 = 0x0001; // CEN(Counter ENable)='1' < TIM control register 1 |
| misan | 1:e63be50a9453 | 93 | TIM4->SMCR = TIM_ENCODERMODE_TI12; // < TIM slave mode control register |
| misan | 1:e63be50a9453 | 94 | //TIM_ENCODERMODE_TI1 input 1 edges trigger count |
| misan | 1:e63be50a9453 | 95 | //TIM_ENCODERMODE_TI2 input 2 edges trigger count |
| misan | 1:e63be50a9453 | 96 | //TIM_ENCODERMODE_TI12 all edges trigger count |
| misan | 1:e63be50a9453 | 97 | TIM4->CCMR1 = 0xF1F1; // CC1S='01' CC2S='01' < TIM capture/compare mode register 1 |
| misan | 1:e63be50a9453 | 98 | //0xF nibble sets up filter |
| misan | 1:e63be50a9453 | 99 | TIM4->CCMR2 = 0x0000; // < TIM capture/compare mode register 2 |
| misan | 1:e63be50a9453 | 100 | TIM4->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E; // < TIM capture/compare enable register |
| misan | 1:e63be50a9453 | 101 | TIM4->PSC = 0x0000; // Prescaler = (0+1) < TIM prescaler |
| misan | 1:e63be50a9453 | 102 | TIM4->ARR = 0xffff; // reload at 0xfffffff < TIM auto-reload register |
| misan | 1:e63be50a9453 | 103 | |
| misan | 1:e63be50a9453 | 104 | TIM4->CNT = 0x0000; //reset the counter before we use it |
| misan | 1:e63be50a9453 | 105 | } |
| misan | 1:e63be50a9453 | 106 | |
| misan | 1:e63be50a9453 | 107 | |
| misan | 1:e63be50a9453 | 108 | |
| misan | 1:e63be50a9453 | 109 | |
| misan | 1:e63be50a9453 | 110 | /* |
| Nigel945426 | 0:25c34018702c | 111 | // Z Pulse routine |
| Nigel945426 | 0:25c34018702c | 112 | void ZeroEncoderCount() { |
| Nigel945426 | 0:25c34018702c | 113 | TIM2->CNT=0 ; //reset count to zero |
| Nigel945426 | 0:25c34018702c | 114 | } |
| misan | 1:e63be50a9453 | 115 | */ |
| misan | 1:e63be50a9453 | 116 | |
| misan | 1:e63be50a9453 | 117 | |
| Nigel945426 | 0:25c34018702c | 118 | |
| Nigel945426 | 0:25c34018702c | 119 | int main() { |
| Nigel945426 | 0:25c34018702c | 120 | EncoderInitialise() ; |
| Nigel945426 | 0:25c34018702c | 121 | |
| misan | 1:e63be50a9453 | 122 | //ZPulse.rise(&ZeroEncoderCount) ; //Setup Interrupt for rising edge of Z pulse |
| misan | 1:e63be50a9453 | 123 | //ZPulse.mode(PullDown) ; // Set input as pull down |
| misan | 1:e63be50a9453 | 124 | A.mode(PullUp); |
| misan | 1:e63be50a9453 | 125 | B.mode(PullUp); |
| Nigel945426 | 0:25c34018702c | 126 | |
| Nigel945426 | 0:25c34018702c | 127 | unsigned int EncoderPosition ; |
| Nigel945426 | 0:25c34018702c | 128 | |
| Nigel945426 | 0:25c34018702c | 129 | while (true) { |
| Nigel945426 | 0:25c34018702c | 130 | // Print Encoder Quadrature count to debug port every 0.5 seconds |
| Nigel945426 | 0:25c34018702c | 131 | EncoderPosition = TIM2->CNT ; // Get current position from Encoder |
| Nigel945426 | 0:25c34018702c | 132 | printf("Encoder Position %i\r\n", EncoderPosition); |
| Nigel945426 | 0:25c34018702c | 133 | wait(0.5); |
| Nigel945426 | 0:25c34018702c | 134 | } |
| Nigel945426 | 0:25c34018702c | 135 | |
| Nigel945426 | 0:25c34018702c | 136 | |
| Nigel945426 | 0:25c34018702c | 137 | } |
