diff --git a/Source/Button.cpp b/Source/Button.cpp new file mode 100644 index 0000000..6aff510 --- /dev/null +++ b/Source/Button.cpp @@ -0,0 +1,56 @@ +/* + * Button.cpp + * + * Created on: Jun 8, 2024 + * Author: Carst + */ + +#include "STM32G071KBT6.hpp" +#include "Button.hpp" + +namespace ElektronischeLast +{ + void Button::init(GPIO_TypeDef* port, uint16_t pin) + { + LL_GPIO_InitTypeDef GPIO_InitStruct = + { + .Pin = pin, + .Mode = LL_GPIO_MODE_INPUT, + .Pull = LL_GPIO_PULL_UP, + }; + LL_GPIO_Init(port, &GPIO_InitStruct); + + this->port = port; + this->pin = pin; + this->state = LL_GPIO_IsInputPinSet(port, pin); + this->stateLast = this->state; + this->debounceTimer = systick; + } + + void Button::cyclic(void) + { + if((systick - this->debounceTimer) > this->debounce) + { + bool state = LL_GPIO_IsInputPinSet(this->port, this->pin); + this->stateLast = this->state; + if(state != this->state) + { + this->debounceTimer = systick; + this->state = state; + } + } + } + + bool Button::isPressed(void) + { + return !this->state; + } + + bool Button::isReleased(void) + { + bool released = (!this->stateLast && this->state); + this->stateLast = this->state; + return released; + } +} + diff --git a/Source/Button.hpp b/Source/Button.hpp new file mode 100644 index 0000000..7d4976b --- /dev/null +++ b/Source/Button.hpp @@ -0,0 +1,34 @@ +/* + * Button.hpp + * + * Created on: Jun 8, 2024 + * Author: Carst + */ + +#ifndef BUTTON_HPP_ +#define BUTTON_HPP_ + +#include "stm32g0xx_ll_gpio.h" + +namespace ElektronischeLast +{ + class Button + { + private: + GPIO_TypeDef* port; + uint16_t pin; + bool state; + bool stateLast; + const uint32_t debounce = 25UL; + uint32_t debounceTimer; + public: + void init(GPIO_TypeDef* port, uint16_t pin); + void cyclic(void); + bool isPressed(void); + bool isReleased(void); + }; +} + + + +#endif /* BUTTON_HPP_ */ diff --git a/Source/ElektronischeLast.hpp b/Source/ElektronischeLast.hpp new file mode 100644 index 0000000..89ffa14 --- /dev/null +++ b/Source/ElektronischeLast.hpp @@ -0,0 +1,17 @@ +/* + * ElektronischeLast.hpp + * + * Created on: Jun 8, 2024 + * Author: Carst + */ + +#ifndef ELEKTRONISCHELAST_HPP_ +#define ELEKTRONISCHELAST_HPP_ + +#include + +void set_new_sollstrom(uint32_t soll); +uint32_t get_current_sollstrom(void); + + +#endif /* ELEKTRONISCHELAST_HPP_ */ diff --git a/Source/Menu.cpp b/Source/Menu.cpp new file mode 100644 index 0000000..d7c26ef --- /dev/null +++ b/Source/Menu.cpp @@ -0,0 +1,244 @@ +/* + * Menu.cpp + * + * Created on: Jun 8, 2024 + * Author: Carst + */ + +#include +#include +#include +#include "Menu.hpp" +#include "Display.hpp" +#include "Button.hpp" +#include "Timer.hpp" +#include "ElektronischeLast.hpp" +#include "STM32G071KBT6.hpp" + +namespace ElektronischeLast +{ + static Timer timer = Timer(); + static Button ok = Button(); + static Button up = Button(); + static Button down = Button(); + static Display lcd = Display(); + static const uint8_t degreeSymbol[] = { 0x0E, 0x0A, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const uint8_t arrowUp[] = { 0x04, 0x0E, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04 }; + static const uint8_t arrowDown[] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x0E, 0x04 }; + + void Menu::init() + { + timer.start(500U); + ok.init(GPIOA, LL_GPIO_PIN_7); + up.init(GPIOA, LL_GPIO_PIN_9); + down.init(GPIOA, LL_GPIO_PIN_8); + + lcd.init(); + + while(lcd.ready_for_data() == false) + { + lcd.run(); + } + + lcd.lcd_set_user_chars(Display::FirstSign, arrowUp); + while(lcd.ready_for_data() == false) + { + lcd.run(); + } + lcd.lcd_set_user_chars(Display::ThirdSign, arrowDown); + while(lcd.ready_for_data() == false) + { + lcd.run(); + } + lcd.lcd_set_user_chars(Display::SecondSign, degreeSymbol); + while(lcd.ready_for_data() == false) + { + lcd.run(); + } + lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOff, Display::eCursorBlinkOff); + lcd.print(Display::Line1, "Elektronische Last"); + } + + void Menu::set_measurements(uint32_t spannung, uint32_t strom, uint32_t temperatur, uint32_t geschwindigkeit) + { + this->spannung = spannung; + this->strom = strom; + this->temperatur = temperatur; + this->geschwindigkeit = geschwindigkeit; + } + + void Menu::run() + { + ok.cyclic(); + up.cyclic(); + down.cyclic(); + + switch(menu_level) + { + case MenuLevel_Call: + menu_call(); + break; + case MenuLevel_ICallInit: + menu_icall_init(); + break; + case MenuLevel_ICall: + menu_icall(); + break; + case MenuLevel_UCallInit: + menu_ucall_init(); + break; + case MenuLevel_UCall: + menu_ucall(); + break; + case MenuLevel_ISoll: + menu_isoll(); + break; + case MenuLevel_Main: + default: + menu_main(); + break; + } + lcd.run(); + } + + void Menu::menu_main(void) + { + if(timer.elapsed()) + { + if(lcd.ready_for_data()) + { + timer.start(500U); + + char data[17U]; + + int32_t len = snprintf(data, sizeof(data) - 1, "%2" PRIu32 ".%02" PRIu32 "V", + spannung / 1000U, spannung % 1000U / 10U); + std::memset(&data[len], (int)' ', 16U - len); + snprintf(&data[12], sizeof(data) - 12, "%2" PRIu32 "%cC", temperatur, 0x1); + data[16] = '\0'; + lcd.print(Display::Line1, data); + + if(strom < 1000UL) + { + len = snprintf(data, sizeof(data) - 1, "%3" PRIu32 "mA", strom); + } + else + { + len = snprintf(data, sizeof(data) - 1, "%" PRIu32 ".%02" PRIu32 "A", + strom / 1000U, strom % 1000U / 10U); + } + std::memset(&data[len], (int)' ', 16U - len); + snprintf(&data[9], sizeof(data) - 9, "%4" PRIu32 "RPM", geschwindigkeit); + data[16] = '\0'; + lcd.print(Display::Line2, data); + } + } + + if(ok.isReleased()) + { + this->menu_level = MenuLevel_ISoll; + this->configurations = 0UL; + } + } + + void Menu::menu_call(void) + { + } + + void Menu::menu_icall_init(void) + { + } + + void Menu::menu_icall(void) + { + } + + void Menu::menu_ucall_init(void) + { + } + + void Menu::menu_ucall(void) + { + } + + void Menu::menu_isoll(void) + { + const char *header = "Sollstrom: "; + char data[17U]; + int32_t len; + bool changed = false; + + if(lcd.ready_for_data()) + { + switch(this->configurations) + { + case 0UL: + soll = get_current_sollstrom(); + len = snprintf(data, sizeof(data) - 1, "%05" PRIu32 "mA", soll); + std::memset(&data[len], (int)' ', 16U - len); + data[16] = '\0'; + lcd.print(Display::Line1, header); + lcd.print(Display::Line2, data); + this->configurations++; + break; + case 1UL: + cursor = 0U; + lcd.set_cursor(Display::Line2, cursor); + this->configurations++; + break; + case 2UL: + lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOn, Display::eCursorBlinkOn); + this->configurations++; + break; + default: + if(ok.isReleased()) + { + cursor++; + if(cursor > 3U) + { + menu_level = MenuLevel_Main; + set_new_sollstrom(soll); + lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOff, Display::eCursorBlinkOff); + } + else + { + lcd.set_cursor(Display::Line2, cursor); + } + } + else if(up.isReleased()) + { + uint32_t step = 10000UL; + uint32_t i = 0U; + while(i < cursor) + { + step /= 10UL; + i++; + } + this->soll = (this->soll + step) % 11000UL; + changed = true; + } + else if(down.isReleased()) + { + uint32_t step = 10000UL; + uint32_t i = 0U; + while(i < cursor) + { + step /= 10UL; + i++; + } + this->soll = (this->soll - step) % 11000UL; + changed = true; + } + if(changed) + { + len = snprintf(data, sizeof(data) - 1, "%05" PRIu32 "mA", this->soll); + std::memset(&data[len], (int)' ', 16U - len); + data[16] = '\0'; + lcd.print(Display::Line2, data); + } + break; + } + } + } + +} diff --git a/Source/Menu.hpp b/Source/Menu.hpp new file mode 100644 index 0000000..c7758de --- /dev/null +++ b/Source/Menu.hpp @@ -0,0 +1,56 @@ +/* + * Menu.hpp + * + * Created on: Jun 8, 2024 + * Author: Carst + */ + +#ifndef MENU_HPP_ +#define MENU_HPP_ + +#include + +namespace ElektronischeLast +{ + class Menu + { + private: + typedef enum + { + MenuLevel_Main, + MenuLevel_Call, + MenuLevel_ICallInit, + MenuLevel_ICall, + MenuLevel_UCallInit, + MenuLevel_UCall, + MenuLevel_ISoll, + } MenuLevel_t; + + MenuLevel_t menu_level = MenuLevel_Main; + + uint32_t spannung = 0U; + uint32_t strom = 0U; + uint32_t temperatur = 0U; + uint32_t geschwindigkeit = 0U; + + uint32_t soll = 0U; + uint32_t cursor = 0U; + + uint8_t configurations = 0U; + + void menu_main(void); + void menu_call(void); + void menu_icall_init(void); + void menu_icall(void); + void menu_ucall_init(void); + void menu_ucall(void); + void menu_isoll(void); + + public: + void init(void); + void run(void); + void set_measurements(uint32_t spannung, uint32_t strom, uint32_t temperatur, uint32_t geschwindigkeit); + }; +} + +#endif diff --git a/Source/Timer.cpp b/Source/Timer.cpp index 48cb42a..073716d 100644 --- a/Source/Timer.cpp +++ b/Source/Timer.cpp @@ -5,7 +5,9 @@ * Author: Carst */ +#include "stm32G071KBT6.hpp" #include "Timer.hpp" + namespace ElektronischeLast { Timer::Timer() @@ -15,7 +17,8 @@ namespace ElektronischeLast void Timer::start(uint32_t durationMs) { - this->timerValue = durationMs; + this->timeout = durationMs; + this->timer_start = systick; this->isRunning = true; } @@ -26,23 +29,21 @@ namespace ElektronischeLast bool Timer::elapsed(void) { - return !this->isRunning; + bool elapsed = false; + if(this->isRunning) + { + if((systick - this->timer_start) >= this->timeout) + { + elapsed = true; + } + } + return elapsed; } - void Timer::tick(void) - { - if (this->isRunning) - { - if (this->timerValue > 0) - { - this->timerValue--; - } - else - { - this-> isRunning = false; - } - } - } + bool Timer::is_running(void) + { + return this->isRunning; + } } diff --git a/Source/Timer.hpp b/Source/Timer.hpp index 13634ba..b0254be 100644 --- a/Source/Timer.hpp +++ b/Source/Timer.hpp @@ -15,14 +15,16 @@ namespace ElektronischeLast class Timer { private: - volatile uint32_t timerValue; - volatile bool isRunning; + uint32_t timer_start; + uint32_t timeout; + bool isRunning; public: Timer(); void start(uint32_t durationMs); void stop(void); bool elapsed(void); void tick(void); + bool is_running(void); }; }