Counter using TIM2

Dependencies:   mbed

Fork of Nucleo_Hello_counter by paolo della vedova

Files at this revision

API Documentation at this revision

Comitter:
gregeric
Date:
Sat Jan 10 20:06:07 2015 +0000
Child:
1:3d2fffa6e19f
Commit message:
Hello World example using the STM32's timer hardware interface, no interrupts.; ; Supporting Nucleo F030, F401, F411 (others can be added - L0xx included but untested).; ; Encoder with TIM4 not working on F411, OK on F401?

Changed in this revision

Encoder/Encoder.h Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderInit.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitF0.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitF4.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitL0.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/Encoder.h	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,6 @@
+#ifndef ENCODER_H
+#define ENCODER_H
+
+void EncoderInit(TIM_Encoder_InitTypeDef encoder, TIM_HandleTypeDef timer, TIM_TypeDef *TIMx, uint32_t maxcount, uint32_t encmode);
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderInit.cpp	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,34 @@
+#include "mbed.h"
+
+void EncoderInit(TIM_Encoder_InitTypeDef encoder, TIM_HandleTypeDef timer, TIM_TypeDef *TIMx, uint32_t maxcount, uint32_t encmode)
+{
+    timer.Instance = TIMx;
+    timer.Init.Period = maxcount;
+    timer.Init.CounterMode = TIM_COUNTERMODE_UP;
+    timer.Init.Prescaler = 0;
+    timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+
+    encoder.EncoderMode = encmode;
+
+    encoder.IC1Filter = 0x0F;
+    encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
+    encoder.IC1Prescaler = TIM_ICPSC_DIV4;
+    encoder.IC1Selection = TIM_ICSELECTION_DIRECTTI;
+
+    encoder.IC2Filter = 0x0F;
+    encoder.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
+    encoder.IC2Prescaler = TIM_ICPSC_DIV4;
+    encoder.IC2Selection = TIM_ICSELECTION_DIRECTTI;
+
+
+    if (HAL_TIM_Encoder_Init(&timer, &encoder) != HAL_OK) {
+        printf("Couldn't Init Encoder\r\n");
+        while (1) {}
+    }
+
+    if(HAL_TIM_Encoder_Start(&timer,TIM_CHANNEL_1)!=HAL_OK) {
+        printf("Couldn't Start Encoder\r\n");
+        while (1) {}
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitF0.cpp	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,30 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * All Nucleos support encoders, from 030 up.
+ * On 030, there's only TIM3 @ AF1 PA6 PA7 (D11 D12)
+ */
+
+#ifdef TARGET_STM32F0
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM3) { //PA6 PA7 = Nucleo D12 D11
+        __TIM3_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitF4.cpp	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,68 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ */
+
+#ifdef TARGET_STM32F4
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8, poss PB0 PB1 usable too (complementary?)
+        __TIM1_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1, PA5 PB3 = D13 D3 poss too
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4, PA6 PA7 & PC6 PC7 also an option for Nucleo
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM5) { // here for completeness, mbed sytem timer uses this
+        __TIM5_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM5;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitL0.cpp	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,28 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ */
+
+#ifdef TARGET_STM32L0
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,60 @@
+/*
+ * 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, others 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 "Encoder.h"
+
+TIM_Encoder_InitTypeDef encoder1, encoder2, encoder3, encoder4;
+TIM_HandleTypeDef timer1, timer2, timer3, timer4;
+
+int main()
+{
+    //examples
+    
+    //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);
+
+    //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) {
+        int16_t count1=0, count3=0, count4=0;
+        int32_t count2=0, count5=0;
+        
+        count1=TIM1->CNT; //OK 401 411 TICKER 030
+        count2=TIM2->CNT; //OK 401 411 N/A 030
+        count3=TIM3->CNT; //OK 401 411 030
+        count4=TIM4->CNT; //OK 401 NOK 411 N/A 030
+        count5=TIM5->CNT; //TICKER 401 411 N/A 030
+        printf("%d %d %d %d %d\r\n", count1, count2, count3, count4, count5);
+        wait(1.0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Jan 10 20:06:07 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5
\ No newline at end of file