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.
Dependents: serial_connected_mcu_nucleo rotary_encoder_mbed serial_connected_mcu_nucleo omuni_speed_pid ... more
Fork of rotary_encoder by
Revision 0:caf1d0bc4b90, committed 2016-02-06
- Comitter:
- inst
- Date:
- Sat Feb 06 14:24:56 2016 +0000
- Child:
- 1:0b315dd1bbbf
- Commit message:
- many classes
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder.cpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,12 @@
+#include "mbed.h"
+#include "rotary_encoder.hpp"
+
+const size_t rotary_encoder::max_counts_ = 0xFFFF;
+
+rotary_encoder::rotary_encoder(size_t resolution) :
+ resolution_(resolution) {}
+rotary_encoder::~rotary_encoder() {}
+
+float rotary_encoder::get_revol_num() const {
+ return static_cast<float>(get_counts()) / resolution_;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder.hpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,23 @@
+#ifndef INCLUDED_ROTARY_ENCODER_H
+#define INCLUDED_ROTARY_ENCODER_H
+
+#include "mbed.h"
+
+class rotary_encoder {
+public:
+ rotary_encoder(size_t resolution);
+ virtual ~rotary_encoder() = 0;
+
+ virtual int32_t get_counts() const = 0;
+ float get_revol_num() const;
+
+ virtual void reset() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
+
+protected:
+ static const size_t max_counts_;
+ const size_t resolution_;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_a_phase.hpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,32 @@
+#ifndef INCLUDED_ROTARY_ENCODER_A_PHASE_H
+#define INCLUDED_ROTARY_ENCODER_A_PHASE_H
+
+#include "rotary_encoder_base.hpp"
+#include "mbed.h"
+
+/*
+ * TIM1_CH1: AF1 @ PA_8
+ * TIM1_CH2: AF1 @ PA_9
+ *
+ * TIM2_CH1: AF1 @ PA_0
+ * TIM2_CH2: AF1 @ PA_1
+ *
+ * TIM3_CH1: AF2 @ PB_4
+ * TIM3_CH2: AF2 @ PB_5
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0* *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+class rotary_encoder_a_phase : public rotary_encoder_base {
+public:
+ rotary_encoder_a_phase(TIM_TypeDef* timer_type, size_t resolution) :
+ rotary_encoder_base(timer_type, TIM_ENCODERMODE_TI1, resolution) {}
+ virtual ~rotary_encoder_a_phase() {}
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_ab_phase.hpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,32 @@
+#ifndef INCLUDED_ROTARY_ENCODER_A_PHASE_H
+#define INCLUDED_ROTARY_ENCODER_A_PHASE_H
+
+#include "rotary_encoder_base.hpp"
+#include "mbed.h"
+
+/*
+ * TIM1_CH1: AF1 @ PA_8
+ * TIM1_CH2: AF1 @ PA_9
+ *
+ * TIM2_CH1: AF1 @ PA_0
+ * TIM2_CH2: AF1 @ PA_1
+ *
+ * TIM3_CH1: AF2 @ PB_4
+ * TIM3_CH2: AF2 @ PB_5
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0* *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+class rotary_encoder_ab_phase : public rotary_encoder_base {
+public:
+ rotary_encoder_ab_phase(TIM_TypeDef* timer_type, size_t resolution) :
+ rotary_encoder_base(timer_type, TIM_ENCODERMODE_TI12, resolution) {}
+ virtual ~rotary_encoder_ab_phase() {}
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_abz_phase/rotary_encoder_abz_phase.cpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,38 @@
+#include "mbed.h"
+#include "rotary_encoder_abz_phase.hpp"
+#include "rotary_encoder_base.hpp"
+
+rotary_encoder_abz_phase::rotary_encoder_abz_phase(TIM_TypeDef* timer_type, PinName z_pin, size_t resolution) :
+ rotary_encoder_base(timer_type, TIM_ENCODERMODE_TI12, resolution),
+ z_phase_intr_(z_pin),
+ counts_in_prev_intr_(0) {
+ z_phase_intr_.fall(this, &rotary_encoder_abz_phase::intr_z_phase_first);
+}
+
+int32_t rotary_encoder_abz_phase::get_counts() const {
+ int32_t counts = timer_handler_->Instance->CNT;
+
+ if (counts > (max_counts_ >> 1)) {
+ return counts - max_counts_;
+ }
+ return counts;
+}
+
+void rotary_encoder_abz_phase::intr_z_phase_first() {
+ counts_in_prev_intr_ = timer_handler_->Instance->CNT;
+ z_phase_intr_.fall(this, &rotary_encoder_abz_phase::intr_z_phase);
+}
+
+void rotary_encoder_abz_phase::intr_z_phase() {
+ uint32_t counts = timer_handler_->Instance->CNT;
+ // Z相の割り込みが入る時は、前回とのカウントの差は分解能で割り切れるはず
+ int64_t error = (counts - counts_in_prev_intr_) % resolution_;
+ timer_handler_->Instance->CNT -= error;
+
+ counts_in_prev_intr_ = counts;
+}
+
+void rotary_encoder_abz_phase::reset() {
+ counts_in_prev_intr_ = 0;
+ timer_handler_->Instance->CNT = 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_abz_phase/rotary_encoder_abz_phase.hpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,42 @@
+#ifndef INCLUDED_ROTARY_ENCODER_A_PHASE_H
+#define INCLUDED_ROTARY_ENCODER_A_PHASE_H
+
+#include "rotary_encoder_base.hpp"
+#include "mbed.h"
+
+/*
+ * TIM1_CH1: AF1 @ PA_8
+ * TIM1_CH2: AF1 @ PA_9
+ *
+ * TIM2_CH1: AF1 @ PA_0
+ * TIM2_CH2: AF1 @ PA_1
+ *
+ * TIM3_CH1: AF2 @ PB_4
+ * TIM3_CH2: AF2 @ PB_5
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0* *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+class rotary_encoder_abz_phase : public rotary_encoder_base {
+public:
+ rotary_encoder_abz_phase(TIM_TypeDef* timer_type, PinName z_pin, size_t resolution);
+ virtual ~rotary_encoder_abz_phase() {}
+
+ virtual int32_t get_counts() const;
+
+ virtual void reset();
+
+private:
+ void intr_z_phase_first();
+ void intr_z_phase();
+
+ InterruptIn z_phase_intr_;
+ uint32_t counts_in_prev_intr_;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_base/EncoderMspInitF4.cpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,76 @@
+#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.
+ *
+ * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00102166.pdf
+ * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00141306.pdf
+ *
+ * TIM1_CH1: AF1 @ PA_8, PE_9
+ * TIM1_CH2: AF1 @ PA_9, PE_11
+ *
+ * TIM2_CH1: AF1 @ PA_0, PA_5, PA_15, PB_8* *F446 only
+ * TIM2_CH2: AF1 @ PA_1, PB_3, PB_9* *F446 only
+ *
+ * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6
+ * TIM3_CH2: AF2 @ PA_7, PB_5, PC_7
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0* *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+#ifdef TARGET_STM32F4
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8
+ __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
+ __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
+ __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);
+ }
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_base/rotary_encoder_base.cpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,57 @@
+#include "rotary_encoder_base.hpp"
+#include "rotary_encoder.hpp"
+
+rotary_encoder_base::rotary_encoder_base(TIM_TypeDef* timer_type,
+ uint32_t encoder_mode,
+ size_t resolution) : rotary_encoder(resolution) {
+ TIM_Encoder_InitTypeDef encoder;
+ timer_handler_ = new TIM_HandleTypeDef;
+
+ timer_handler_->Instance = timer_type;
+ timer_handler_->Init.Period = max_counts_;
+ timer_handler_->Init.CounterMode = TIM_COUNTERMODE_UP;
+ timer_handler_->Init.Prescaler = 0;
+ timer_handler_->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+
+ encoder.EncoderMode = encoder_mode;
+
+ 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_handler_, &encoder) != HAL_OK) {
+ error("couldn't init encoder\r\n");
+ }
+}
+
+int32_t rotary_encoder_base::get_counts() const {
+ int32_t counts = timer_handler_->Instance->CNT;
+
+ if (counts > (max_counts_ >> 1)) {
+ return counts - max_counts_;
+ }
+
+ return counts;
+}
+
+void rotary_encoder_base::reset() {
+ timer_handler_->Instance->CNT = 0;
+}
+
+void rotary_encoder_base::start() {
+ if(HAL_TIM_Encoder_Start(timer_handler_, TIM_CHANNEL_1) != HAL_OK) {
+ error("couldn't start encoder\r\n");
+ }
+}
+
+void rotary_encoder_base::stop() {
+ if(HAL_TIM_Encoder_Stop(timer_handler_, TIM_CHANNEL_1) != HAL_OK) {
+ error("couldn't start encoder\r\n");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_base/rotary_encoder_base.hpp Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,23 @@
+#ifndef INCLUDED_ROTARY_ENCODER_BASE_H
+#define INCLUDED_ROTARY_ENCODER_BASE_H
+
+#include "rotary_encoder.hpp"
+
+class rotary_encoder_base : public rotary_encoder {
+public:
+ rotary_encoder_base(TIM_TypeDef* timer_type,
+ uint32_t encoder_mode,
+ size_t resolution);
+ virtual ~rotary_encoder_base() {}
+
+ virtual int32_t get_counts() const;
+
+ virtual void reset();
+ virtual void start();
+ virtual void stop();
+
+protected:
+ TIM_HandleTypeDef* timer_handler_;
+};
+
+#endif
