From 6dd3fd5a15c4bd89439958a06f733ee9bed7caea Mon Sep 17 00:00:00 2001 From: Mikhail Date: Wed, 22 May 2024 23:54:50 +0300 Subject: [PATCH] Initial release --- Inc/DS_Encoder.h | 30 +++++++++++++++++++ Src/DS_Encoder.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 Inc/DS_Encoder.h create mode 100644 Src/DS_Encoder.c diff --git a/Inc/DS_Encoder.h b/Inc/DS_Encoder.h new file mode 100644 index 0000000..34aeb35 --- /dev/null +++ b/Inc/DS_Encoder.h @@ -0,0 +1,30 @@ +#ifndef DS_ENCODER_H +#define DS_ENCODER_H + +#ifdef STM32G030xx + #include "stm32g0xx_hal.h" +#endif + +#ifdef STM32F030xx + #include "stm32f0xx_hal.h" +#endif + +typedef struct DS_Encoder +{ + GPIO_TypeDef *PortEncSignal1, *PortEncSignal2; + uint16_t PinEncSignal1, PinEncSignal2; + int8_t State; + int8_t Direction; + uint32_t PrevTick; + + uint8_t ValueSignal1, ValueSignal2; +}DS_Encoder; + + +void DS_EncoderInit(DS_Encoder *Encoder, GPIO_TypeDef* PortEncSignal1, uint16_t PinEncSignal1, GPIO_TypeDef* PortEncSignal2, uint16_t PinEncSignal2); + +void DS_EncoderUpdate(DS_Encoder *Encoder); + +int8_t DS_EncoderGetState(DS_Encoder *Encoder); + +#endif //DS_ENCODER_H \ No newline at end of file diff --git a/Src/DS_Encoder.c b/Src/DS_Encoder.c new file mode 100644 index 0000000..d302ab9 --- /dev/null +++ b/Src/DS_Encoder.c @@ -0,0 +1,75 @@ +#include "Encoder.h" + +void DS_EncoderInit(DS_Encoder *Encoder, GPIO_TypeDef *PortEncSignal1, uint16_t PinEncSignal1, GPIO_TypeDef *PortEncSignal2, uint16_t PinEncSignal2) +{ + Encoder->Direction = 0; + Encoder->State = 0; + Encoder->PrevTick = HAL_GetTick(); + Encoder->PinEncSignal1 = PinEncSignal1; + Encoder->PinEncSignal2 = PinEncSignal2; + Encoder->PortEncSignal1 = PortEncSignal1; + Encoder->PortEncSignal2 = PortEncSignal2; + + Encoder->ValueSignal1 = 0; + Encoder->ValueSignal2 = 0; +} + +void DS_EncoderUpdate(DS_Encoder *Encoder) +{ + uint32_t CurrentTick = HAL_GetTick(); + if ((CurrentTick - Encoder->PrevTick) < 1) + return; + + Encoder->PrevTick = CurrentTick; + + + + //Обновление состояние первой сигнальной линии + GPIO_PinState Pin1State = HAL_GPIO_ReadPin(Encoder->PortEncSignal1, Encoder->PinEncSignal1); + if (Pin1State == GPIO_PIN_SET) + { + Encoder->ValueSignal1 = 1; + } + else + { + Encoder->ValueSignal1 = 0; + } + + //Обновление состояние второй сигнальной линии + GPIO_PinState Pin2State = HAL_GPIO_ReadPin(Encoder->PortEncSignal2, Encoder->PinEncSignal2); + if (Pin2State == GPIO_PIN_SET) + { + Encoder->ValueSignal2 = 1; + } + else + { + Encoder->ValueSignal2 = 0; + } + + //Рассчитываем в какую сторону повернули энкодер + // Если на первой линии высокий уровень, а на второй линии - низкий, то вращаем в одну сторону + if(Encoder->ValueSignal1 == 1 && Encoder->ValueSignal2 == 0) + { + Encoder->Direction = 1; + } + // Если на первой линии низкий уровень, а на второй линии - высокий, то вращаем в другую сторону + if(Encoder->ValueSignal1 == 0 && Encoder->ValueSignal2 == 1) + { + Encoder->Direction = -1; + } + + // как определились с направлением - ждём когда оба сигнала поднимутся в высокий уровень, фиксируем шаг, и сбрасываем флаг направления. + if(Encoder->Direction != 0 && Encoder->ValueSignal1 == 1 && Encoder->ValueSignal2 == 1) + { + Encoder->State = Encoder->State + Encoder->Direction; + Encoder->Direction = 0; + } + +} + +int8_t DS_EncoderGetState(DS_Encoder *Encoder) +{ + int8_t ValueToReturn = Encoder->State; + Encoder->State = 0; + return ValueToReturn; +}