4 Rotary encoders with 5110 LCD display. For Nucleo boards

Dependencies:   N5110 mbed

Revision:
7:62c2c1382d86
Parent:
6:920bfbc7a7a1
Child:
8:67732769ecdd
--- a/main.cpp	Sat Oct 22 19:56:47 2016 +0000
+++ b/main.cpp	Sun Oct 23 15:48:58 2016 +0000
@@ -1,6 +1,36 @@
+/*
+ * Using STM32's counter peripherals to interface rotary encoders.
+ * Encoders are supported on F4xx's TIM1,2,3,4,5. TIM2 & TIM5 have 32bit count, others 16bit.
+ * Beware mbed uses TIM5 for system timer, SPI needs TIM1, others used for PWM.
+ * Check your platform's PeripheralPins.c & PeripheralNames.h if you need both PWM & encoders.
+ *
+ * Edit HAL_TIM_Encoder_MspInitFx.cpp to suit your mcu & board's available pinouts & pullups/downs.
+ *
+ * Thanks to:
+ * http://petoknm.wordpress.com/2015/01/05/rotary-encoder-and-stm32/
+ *
+ * References:
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00122015.pdf
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00096844.pdf
+ * http://www.st.com/web/en/resource/technical/document/application_note/DM00042534.pdf
+ * http://www.st.com/web/en/resource/technical/document/datasheet/DM00102166.pdf
+ * 
+ * David Lowe Jan 2015
+ */
+
+
 #include "mbed.h"
 #include "N5110.h"
-#include "REnc.h"
+#include "Encoder.h"
+
+//STM mbed bug: these macros are MISSING from stm32f3xx_hal_tim.h
+#ifdef TARGET_STM32F3
+#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT)
+#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__)            (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR))
+#endif
+
+TIM_Encoder_InitTypeDef encoder1, encoder2, encoder3, encoder4;
+TIM_HandleTypeDef  timer1,  timer2,  timer3,  timer4;
 
 
 //DigitalOut red(LED1);
@@ -10,25 +40,34 @@
 
 //         VCC,SCE, RST, D/C, MOSI,SCLK,LED
 N5110 lcd(PB_8,PA_4,PA_0,PA_1,PA_7,PA_5,PB_9);  //PA_4 and PA_6 not used
-REnc encoder(PC_3, PC_2);
+
 int temperature = 50;
 
-void CCW_Handle(void)
-{
-    temperature--;
-}
+int main() {
+    uint16_t count1=0, count3=0, count4=0;
+    uint32_t count2=0;
+    int8_t dir1, dir2, dir3, dir4;
+
+     // first need to initialise display
+    lcd.init();
+         //examples
     
-void CW_Handle(void)
-{
-    temperature++;
-}
-    
+    //counting on A-input only, 2 ticks per cycle, rolls over at 100
+    EncoderInit(&encoder1, &timer1, TIM1, 99, TIM_ENCODERMODE_TI1);
+
+    //counting on both A&B inputs, 4 ticks per cycle, full 32-bit count
+    EncoderInit(&encoder2, &timer2, TIM2, 0xffffffff, TIM_ENCODERMODE_TI12);
 
-int main() {
-     // first need to initialise display
-        lcd.init();
-        encoder.setHandleCCW(CCW_Handle);
-        encoder.setHandleCC(CW_Handle);
+    //counting on B-input only, 2 ticks per cycle, full 16-bit count
+    EncoderInit(&encoder3, &timer3, TIM3, 0xffff, TIM_ENCODERMODE_TI2);
+    
+    //counting on both A&B inputs, 4 ticks per cycle, full 16-bit count
+    EncoderInit(&encoder4, &timer4, TIM4, 0xffff, TIM_ENCODERMODE_TI12);
+    
+    //TIM5 is used by mbed for systick
+    //EncoderInit(encoder2, timer2, TIM5, 0xffffffff, TIM_ENCODERMODE_TI12);
+        
+    printf("STM HAL encoder demo\n\r");
 
 //    while(1) {
 //        for (i=1; i<7; i++) {
@@ -38,50 +77,85 @@
 //            wait(0.2);
 //        }
 //    }
-    while(1) {
+    while(1) 
+    {
+                
+        //OK 401 411 446 TICKER 030
+        //count1=TIM1->CNT;
+        //dir1=TIM1->CR1&TIM_CR1_DIR;
+        count1=__HAL_TIM_GET_COUNTER(&timer1);
+        dir1 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer1);
 
-           // these are default settings so not strictly needed
-           lcd.normalMode();      // normal colour mode
-           lcd.setBrightness(0.5); // put LED backlight on 50%
-
-           // can directly print strings at specified co-ordinates
-           lcd.printString("Hello, World!",0,0);
+        //OK 401 411 446 NOK 030
+        //count2=TIM2->CNT;
+        //dir2=TIM2->CR1&TIM_CR1_DIR;
+        count2=__HAL_TIM_GET_COUNTER(&timer2);
+        dir2 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer2);
 
-           char buffer[14];  // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
-           // so can display a string of a maximum 14 characters in length
-           // or create formatted strings - ensure they aren't more than 14 characters long
-          // int temperature = encoder.getVal();
-           int length = sprintf(buffer,"T = %2d C",temperature); // print formatted data to buffer
-           // it is important the format specifier ensures the length will fit in the buffer
-           if (length <= 14)  // if string will fit on display
-               lcd.printString(buffer,0,1);           // display on screen
+        //OK 401 411 446 030
+        //count3=TIM3->CNT;
+        //dir3=TIM3->CR1&TIM_CR1_DIR;
+        count3=__HAL_TIM_GET_COUNTER(&timer3);
+        dir3 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer3);
+
+        //OK 401 411 446 N/A 030
+        //count4=TIM4->CNT;
+        //dir4=TIM4->CR1&TIM_CR1_DIR;
+        count4=__HAL_TIM_GET_COUNTER(&timer4);
+        dir4 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer4);
 
-           float pressure = 1012.3;  // same idea with floats
-           length = sprintf(buffer,"P = %.2f mb",pressure);
-           if (length <= 14)
-               lcd.printString(buffer,0,2);
+        //TICKER 401 411 446 N/A 030
+//        count5=__HAL_TIM_GET_COUNTER(&timer5);
+//        dir5 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer5);
+//        printf("%d%s %d%s %d%s %d%s\r\n", count1, dir1==0 ? "+":"-",
+//                                             count2, dir2==0 ? "+":"-",
+//                                             count3, dir3==0 ? "+":"-",
+//                                             count4, dir4==0 ? "+":"-" );
+
+        // these are default settings so not strictly needed
+        lcd.normalMode();      // normal colour mode
+        lcd.setBrightness(0.5); // put LED backlight on 50%
 
-           // can also print individual characters at specified place
-           lcd.printChar('X',5,3);
+        // can directly print strings at specified co-ordinates
+        lcd.printString("Hello, World!",0,0);
 
-           // draw a line across the display at y = 40 pixels (origin top-left)
-           for (int i = 0; i < WIDTH; i++) {
-               lcd.setPixel(i,40);
-           }
-           // need to refresh display after setting pixels
-           lcd.refresh();
+        char buffer[14];  // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
+        // so can display a string of a maximum 14 characters in length
+        // or create formatted strings - ensure they aren't more than 14 characters long
+        // int temperature = encoder.getVal();
+        int length = sprintf(buffer,"T = %2d C",temperature); // print formatted data to buffer
+        // it is important the format specifier ensures the length will fit in the buffer
+        if (length <= 14)  // if string will fit on display
+        {
+            lcd.printString(buffer,0,1);           // display on screen
+        }
+        float pressure = 1012.3;  // same idea with floats
+        length = sprintf(buffer,"P = %.2f mb",pressure);
+        if (length <= 14)
+        {
+            lcd.printString(buffer,0,2);                
+        }
+        // can also print individual characters at specified place
+        lcd.printChar('X',5,3);
 
-           // can also check status of pixels using getPixel(x,y)
-           while(1)
-           {               
-                wait(.5);
-               
-                length = sprintf(buffer,"T = %2d C",temperature); // print formatted data to buffer
-           
-                if (length <= 14)  // if string will fit on display
-                    lcd.printString(buffer,0,1);           // display on screen
-           }
-           lcd.clear();
+        // draw a line across the display at y = 40 pixels (origin top-left)
+        for (int i = 0; i < WIDTH; i++) 
+        {
+            lcd.setPixel(i,40);
+        }
+        // need to refresh display after setting pixels
+        lcd.refresh();
 
-       }
+        // can also check status of pixels using getPixel(x,y)
+        while(1)
+        {               
+            wait(.5);               
+            length = sprintf(buffer,"T = %2d C",temperature); // print formatted data to buffer           
+            if (length <= 14)  // if string will fit on display
+            {
+                lcd.printString(buffer,0,1);           // display on screen
+            }
+        }
+        lcd.clear();
+    }
 }