Variation Nigel Webb's. AB encoders, using pullups and diodes for connecting 5V (or higher voltage) encoders.

Dependencies:   mbed

Fork of HardwareQuadratureEncoderABZ by Nigel Webb

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 // Hardware Quadrature Encoder ABZ for Nucleo F401RE
00004 // Output on debug port to host PC @ 9600 baud
00005 // 
00006 // By Nigel Webb, November 2014
00007 // Modified by Miguel Sánchez, January 2015
00008 
00009 /* Connections
00010    PA_0 = Encoder A
00011    PA_1 = Encoder B
00012    PA_4 = Encoder Z 
00013 */
00014 
00015 // ZPulse(PA_4) ; // Setup Interrupt for Z Pulse --> no index needed here
00016 
00017 DigitalIn A(PA_0);
00018 DigitalIn B(PA_1);
00019 
00020 
00021 void EncoderInitialise(void) {
00022     // configure GPIO PA0 & PA1 as inputs for Encoder
00023     RCC->AHB1ENR |= 0x00000001;  // Enable clock for GPIOA
00024  
00025     GPIOA->MODER   |= GPIO_MODER_MODER0_1 | GPIO_MODER_MODER1_1 ;           //PA0 & PA1 as Alternate Function   /*!< GPIO port mode register,               Address offset: 0x00      */
00026     GPIOA->OTYPER  |= GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 ;                 //PA0 & PA1 as Inputs               /*!< GPIO port output type register,        Address offset: 0x04      */
00027     GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 ;     // Low speed                        /*!< GPIO port output speed register,       Address offset: 0x08      */
00028     GPIOA->PUPDR   |= GPIO_PUPDR_PUPDR0_1 | GPIO_PUPDR_PUPDR1_1 ;           // Pull Down                        /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
00029     GPIOA->AFR[0]  |= 0x00000011 ;                                          //  AF01 for PA0 & PA1              /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
00030     GPIOA->AFR[1]  |= 0x00000000 ;                                          //                                  /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
00031    
00032     // configure TIM2 as Encoder input
00033     RCC->APB1ENR |= 0x00000001;  // Enable clock for TIM2
00034  
00035     TIM2->CR1   = 0x0001;     // CEN(Counter ENable)='1'     < TIM control register 1
00036     TIM2->SMCR  = 0x0003;     // SMS='011' (Encoder mode 3)  < TIM slave mode control register
00037     TIM2->CCMR1 = 0xF1F1;     // CC1S='01' CC2S='01'         < TIM capture/compare mode register 1
00038     TIM2->CCMR2 = 0x0000;     //                             < TIM capture/compare mode register 2
00039     TIM2->CCER  = 0x0011;     // CC1P CC2P                   < TIM capture/compare enable register
00040     TIM2->PSC   = 0x0000;     // Prescaler = (0+1)           < TIM prescaler
00041     TIM2->ARR   = 0xffffffff; // reload at 0xfffffff         < TIM auto-reload register
00042   
00043     TIM2->CNT = 0x0000;  //reset the counter before we use it  
00044 }
00045 
00046 
00047 void EncoderInitialiseTIM3(void) {
00048     // configure GPIO PA0 & PA1 aka A0 & A1 as inputs for Encoder
00049     // Enable clock for GPIOA
00050     __GPIOA_CLK_ENABLE(); //equivalent from hal_rcc.h
00051  
00052     //stm32f4xx.h 
00053     GPIOA->MODER   |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1 ;           //PA6 & PA7 as Alternate Function   /*!< GPIO port mode register,               Address offset: 0x00      */
00054     GPIOA->OTYPER  |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 ;                 //PA6 & PA7 as Inputs               /*!< GPIO port output type register,        Address offset: 0x04      */
00055     GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 ;     //Low speed                         /*!< GPIO port output speed register,       Address offset: 0x08      */
00056     GPIOA->PUPDR   |= GPIO_PUPDR_PUPDR6_1 | GPIO_PUPDR_PUPDR7_1 ;           //Pull Down                         /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
00057     GPIOA->AFR[0]  |= 0x22000000 ;                                          //AF02 for PA6 & PA7                /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
00058     GPIOA->AFR[1]  |= 0x00000000 ;                                          //nibbles here refer to gpio8..15   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
00059    
00060     // configure TIM3 as Encoder input
00061     // Enable clock for TIM3
00062     __TIM3_CLK_ENABLE();
00063  
00064     TIM3->CR1   = 0x0001;     // CEN(Counter ENable)='1'     < TIM control register 1
00065     TIM3->SMCR  = TIM_ENCODERMODE_TI12;     // SMS='011' (Encoder mode 3)  < TIM slave mode control register
00066     TIM3->CCMR1 = 0xF1F1;     // CC1S='01' CC2S='01'         < TIM capture/compare mode register 1
00067     TIM3->CCMR2 = 0x0000;     //                             < TIM capture/compare mode register 2
00068     TIM3->CCER  = 0x0011;     // CC1P CC2P                   < TIM capture/compare enable register
00069     TIM3->PSC   = 0x0000;     // Prescaler = (0+1)           < TIM prescaler
00070     TIM3->ARR   = 0xffffffff; // reload at 0xfffffff         < TIM auto-reload register
00071   
00072     TIM3->CNT = 0x0000;  //reset the counter before we use it  
00073 }
00074  
00075 void EncoderInitialiseTIM4(void) {
00076     //PB6 PB7 aka D10 MORPHO_PB7
00077     // Enable clock for GPIOA
00078     __GPIOB_CLK_ENABLE(); //equivalent from hal_rcc.h
00079  
00080     //stm32f4xx.h 
00081     GPIOB->MODER   |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1 ;           //PB6 & PB7 as Alternate Function   /*!< GPIO port mode register,               Address offset: 0x00      */
00082     GPIOB->OTYPER  |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 ;                 //PB6 & PB7 as Inputs               /*!< GPIO port output type register,        Address offset: 0x04      */
00083     GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 ;     //Low speed                         /*!< GPIO port output speed register,       Address offset: 0x08      */
00084     GPIOB->PUPDR   |= GPIO_PUPDR_PUPDR6_1 | GPIO_PUPDR_PUPDR7_1 ;           //Pull Down                         /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
00085     GPIOB->AFR[0]  |= 0x22000000 ;                                          //AF02 for PB6 & PB7                /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
00086     GPIOB->AFR[1]  |= 0x00000000 ;                                          //nibbles here refer to gpio8..15   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
00087    
00088     // configure TIM4 as Encoder input
00089     // Enable clock for TIM4
00090     __TIM4_CLK_ENABLE();
00091  
00092     TIM4->CR1   = 0x0001;     // CEN(Counter ENable)='1'     < TIM control register 1
00093     TIM4->SMCR  = TIM_ENCODERMODE_TI12;     //               < TIM slave mode control register
00094     //TIM_ENCODERMODE_TI1 input 1 edges trigger count
00095     //TIM_ENCODERMODE_TI2 input 2 edges trigger count
00096     //TIM_ENCODERMODE_TI12 all edges trigger count
00097     TIM4->CCMR1 = 0xF1F1;     // CC1S='01' CC2S='01'         < TIM capture/compare mode register 1
00098     //0xF nibble sets up filter
00099     TIM4->CCMR2 = 0x0000;     //                             < TIM capture/compare mode register 2
00100     TIM4->CCER  = TIM_CCER_CC1E | TIM_CCER_CC2E;     //     < TIM capture/compare enable register
00101     TIM4->PSC   = 0x0000;     // Prescaler = (0+1)           < TIM prescaler
00102     TIM4->ARR   = 0xffff; // reload at 0xfffffff         < TIM auto-reload register
00103   
00104     TIM4->CNT = 0x0000;  //reset the counter before we use it  
00105 }
00106 
00107 
00108 
00109 
00110 /*
00111 // Z Pulse routine
00112 void ZeroEncoderCount() {
00113     TIM2->CNT=0 ; //reset count to zero
00114 }
00115 */
00116 
00117 
00118 
00119 int main() {
00120     EncoderInitialise() ;
00121     
00122     //ZPulse.rise(&ZeroEncoderCount) ; //Setup Interrupt for rising edge of Z pulse 
00123     //ZPulse.mode(PullDown) ; // Set input as pull down
00124      A.mode(PullUp);
00125      B.mode(PullUp);
00126      
00127     unsigned int EncoderPosition ;
00128     
00129     while (true) {
00130         // Print Encoder Quadrature count to debug port every 0.5 seconds
00131         EncoderPosition = TIM2->CNT ; // Get current position from Encoder
00132         printf("Encoder Position %i\r\n", EncoderPosition); 
00133         wait(0.5);
00134     }
00135    
00136        
00137 }