Browse Source

Наполнил фукционалом.

Vladimir N. Shilov 5 năm trước cách đây
mục cha
commit
77e7f40b94
5 tập tin đã thay đổi với 609 bổ sung64 xóa
  1. 3 0
      ReadMe.txt
  2. 2 0
      VAPC2.cbp
  3. 8 8
      inc/board.h
  4. 4 4
      lib/rtos.h
  5. 592 52
      src/main.c

+ 3 - 0
ReadMe.txt

@@ -19,3 +19,6 @@
 Внешний кварц не запускается.
 
 Запустил SPI и MAX7219.
+---
+2019.07.10
+Запустил I2C, INA219, RTOS.

+ 2 - 0
VAPC2.cbp

@@ -126,6 +126,7 @@
 		<Unit filename="StdPerphDrv/src/stm8s_wwdg.c">
 			<Option compilerVar="CC" />
 		</Unit>
+		<Unit filename="inc/board.h" />
 		<Unit filename="inc/stm8s_conf.h" />
 		<Unit filename="inc/stm8s_it.h" />
 		<Unit filename="lib/event-system.c">
@@ -159,6 +160,7 @@
 			<code_completion />
 			<envvars />
 			<debugger />
+			<editor_config active="1" use_tabs="0" tab_indents="1" tab_width="2" indent="2" eol_mode="0" />
 		</Extensions>
 	</Project>
 </CodeBlocks_project_file>

+ 8 - 8
inc/board.h

@@ -2,15 +2,15 @@
 #define __BOARD_H
 
 /* MACROs for SET, RESET or TOGGLE Output port */
-#define GPIO_HIGH(a,b)     a->ODR |= b
-#define GPIO_LOW(a,b)      a->ODR &= ~b
-#define GPIO_TOGGLE(a,b)   a->ODR ^= b
+#define GPIO_HIGH(a,b)    a->ODR |= b
+#define GPIO_LOW(a,b)     a->ODR &= ~b
+#define GPIO_TOGGLE(a,b)  a->ODR ^= b
 
-#define BUTTON1_PORT       GPIOD
-#define BUTTON1_PIN        GPIO_Pin_4
-
-#define BUTTON2_PORT       GPIOA
-#define BUTTON2_PIN        GPIO_Pin_3
+#define BUTTON_NUM        2
+#define BUTTON1_PORT      GPIOD
+#define BUTTON1_PIN       GPIO_PIN_4
+#define BUTTON2_PORT      GPIOA
+#define BUTTON2_PIN       GPIO_PIN_3
 
 #define SPI_PORT          GPIOC
 #define SPI_SCK           GPIO_PIN_5

+ 4 - 4
lib/rtos.h

@@ -35,10 +35,10 @@
  */
 typedef struct task
 {
-   void (*pFunc) (void); // указатель на функцию
-   uint16_t delay;       // задержка перед первым запуском задачи
-   uint16_t period;      // период запуска задачи
-   uint8_t run;          // флаг готовности задачи к запуску
+  void (*pFunc) (void); // указатель на функцию
+  uint16_t delay;       // задержка перед первым запуском задачи
+  uint16_t period;      // период запуска задачи
+  uint8_t run;          // флаг готовности задачи к запуску
 } task;
 
 /**

+ 592 - 52
src/main.c

@@ -25,48 +25,150 @@
 #include "i2c.h"
 #include "ina219.h"
 
-/* Private defines -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+// êíîïêà ñ÷èòàåòñÿ íàæàòîé ÷åðåç BTN_FACTOR * BTN_SCAN_PERIOD ms
+#define BTN_SCAN_PERIOD 10
+#define BTN_FACTOR      5
+
+/* Private typedef -----------------------------------------------------------*/
+typedef enum _mode_led {
+  dispNoState = 0x00,
+  displayV,
+  displayI,
+  displayP,
+  displayCI,
+  displayCP,
+  displayT
+} mode_led_t;
+
+typedef enum _events {
+  eventNoEvent  = 0x00,
+  eventShortPress,
+  eventLongPress
+} event_t;
+
+typedef enum _button_name {
+  S1 = 0x00,
+  S2 = 0x01
+} button_name;
+
+typedef struct _button_pin {
+  GPIO_TypeDef *    port;
+  GPIO_Pin_TypeDef  pin;
+} button_t;
+
+/* Private constants ---------------------------------------------------------*/
+// ïåðåâîä ÷èñëà 0-7 â íîìåð èíäèêàòîðà
 const static max7219_reg_t digitPosition[8] = {
   RegDigit0, RegDigit1, RegDigit2, RegDigit3,
   RegDigit4, RegDigit5, RegDigit6, RegDigit7
 };
+// ïåðåâîä çíà÷åíèÿ 0x00 - 0x0F â êîä èíäèêàòîðà
 const static max7219_sym_t digitValue[16] = {
   Sym_0, Sym_1, Sym_2, Sym_3, Sym_4, Sym_5, Sym_6, Sym_7,
   Sym_8, Sym_9, Sym_A, Sym_b, Sym_c, Sym_d, Sym_E, Sym_F
 };
+// îïðåäåëåíèÿ ïèíîâ êíîïîê
+const static button_t Button[BUTTON_NUM] = {
+  {BUTTON1_PORT, BUTTON1_PIN},
+  {BUTTON2_PORT, BUTTON2_PIN},
+};
+
+/* Private variables ---------------------------------------------------------*/
+static uint16_t Voltage;
+static uint16_t Current;
+static uint32_t Power;
+static uint32_t CapacityAH = 0;
+static uint32_t CapacityWH = 0;
+static struct _timer {
+  uint8_t hh;
+  uint8_t mm;
+  uint8_t ss;
+} Timer;
+
+static uint8_t btn1Cnt;
+static uint8_t btn2Cnt;
+
+static mode_led_t modeTopLine, modeBotLine;
 
 /* Private function prototypes -----------------------------------------------*/
 static void boardInit(void);
-static void showVoltage(void);
 
-/* Private functions ---------------------------------------------------------*/
+static void showValue(uint32_t val, uint8_t pos);
+static void showU(uint8_t pos);
+static void showI(uint8_t pos);
+static void showP(uint8_t pos);
+static void showCI(uint8_t pos);
+static void showCP(uint8_t pos);
+static void showT(uint8_t pos);
+
+static void showLabelU(uint8_t pos);
+static void showLabelI(uint8_t pos);
+static void showLabelP(uint8_t pos);
+static void showLabelAH(uint8_t pos);
+static void showLabelWH(uint8_t pos);
+static void showLabelT(uint8_t pos);
+
+static void displayMode(mode_led_t * disp, event_t event, uint8_t pos);
+
+static void blankLine(uint8_t pos);
+
+/* RTOS function prototypes -----------------------------------------------*/
+static void readINAValues(void);
+static void showTopLineU(void);
+static void showTopLineI(void);
+static void showTopLineP(void);
+static void showTopLineAH(void);
+static void showTopLineWH(void);
+static void showTopLineT(void);
+static void showBotLineU(void);
+static void showBotLineI(void);
+static void showBotLineP(void);
+static void showBotLineAH(void);
+static void showBotLineWH(void);
+static void showBotLineT(void);
+
+static void blankTopLine(void);
+static void blankBotLine(void);
+
+static void btnScan(void);
+static void btnTest(button_t const *btn, uint8_t *pressCount, void (*taskShortPress)(void), void (*taskLongPress)(void));
+static void btn1Short(void);
+static void btn1Long(void);
+static void btn2Short(void);
+static void btn2Long(void);
 
 void main(void)
 {
+  /* Board Configuration */
   boardInit();
 
+  /* RTOS Configuration */
   RTOS_Init();
   enableInterrupts();
 
+  /* MAX7219 Configuration */
   MAX7219_Config();
+  blankTopLine();
+  blankBotLine();
 
-  MAX7219_WriteData(digitPosition[0], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[1], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[2], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[3], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[4], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[5], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[6], Sym_BLANK);
-  MAX7219_WriteData(digitPosition[7], Sym_BLANK);
-
+  /* I2C Configuration */
   i2c_master_init();
+
+  /* INA219 Configuration */
   INA219_Config();
 
-  RTOS_SetTask(showVoltage, 70, 250);
+  /* ROTS tasks */
+  RTOS_SetTask(btnScan, 0, BTN_SCAN_PERIOD);
+  RTOS_SetTask(readINAValues, 70, 250);
+  RTOS_SetTask(showTopLineU, 71, 250);
+  RTOS_SetTask(showBotLineI, 72, 250);
+
+  modeTopLine = displayV;
+  modeBotLine = displayI;
 
   /* Infinite loop */
-  while (1)
-  {
+  while (1) {
     RTOS_DispatchTask();
     wfi();
   }
@@ -98,6 +200,15 @@ static void boardInit(void) {
     // set FLAG for
   }
 
+  /* Configure GPIO used for buttons */
+  BUTTON1_PORT->DDR &= (uint8_t)(~(BUTTON1_PIN)); // Input Mode
+  BUTTON1_PORT->CR1 |= (uint8_t)BUTTON1_PIN; // Pull-Up
+  BUTTON1_PORT->CR2 &= (uint8_t)(~(BUTTON1_PIN)); // No Interrupt
+
+  BUTTON2_PORT->DDR &= (uint8_t)(~(BUTTON2_PIN)); // Input Mode
+  BUTTON2_PORT->CR1 |= (uint8_t)BUTTON2_PIN; // Pull-Up
+  BUTTON2_PORT->CR2 &= (uint8_t)(~(BUTTON2_PIN)); // No Interrupt
+
   /* Init GPIO */
   /* Set the MOSI,MISO and SCK at high level */
   SPI_PORT->ODR |= SPI_MOSI;
@@ -118,59 +229,488 @@ static void boardInit(void) {
   SPI->CR2 = 0xC0 | 0x02 | 0x01;
   /* SPI Enable */
   SPI->CR1 |= SPI_CR1_SPE;
-
 }
 
-/** */
-static void showVoltage(void) {
-  uint8_t c = 0;
-
-  uint16_t volt = readBusVoltage();
+static void btnScan(void) {
+  btnTest(&Button[S1], &btn1Cnt, btn1Short, btn1Long);
+  btnTest(&Button[S2], &btn2Cnt, btn2Short, btn2Long);
+}
 
-  if (volt < 10000) {
-    MAX7219_WriteData(digitPosition[2], digitValue[0]);
+/** ïðîâåðêà êîíêðåòíîé êíîïêè */
+static void btnTest(button_t const *btn, uint8_t *pressCount, void (*taskShortPress)(void), void (*taskLongPress)(void)) {
+  if ((btn->port->IDR & btn->pin) == 0) {
+    if (*pressCount < 255) {
+      *pressCount = *pressCount + 1;
+    }
+/*
+    if (*pressCount ==  BTN_FACTOR) {
+         // short
+      } else if(*pressCount == (BTN_FACTOR * 10)) {
+         // long
+      }
+*/
   } else {
-    while (volt >= 10000) {
-      volt -= 10000;
-      c ++;
+    if (*pressCount >= (BTN_FACTOR * 10)) {
+      RTOS_SetTask(taskLongPress, 1, 0); // âûçîâ ôóíêöèè ïðè äëèòåëüíîì íàæàòèè
+    } else if (*pressCount >= BTN_FACTOR) {
+      RTOS_SetTask(taskShortPress, 1, 0); // âûçîâ ôóíêöèè ïðè êîðîòêîì íàæàòèè
     }
-    MAX7219_WriteData(digitPosition[3], digitValue[c]);
+    *pressCount = 0;
   }
+}
 
-  if (volt < 1000) {
-    MAX7219_WriteData(digitPosition[3], digitValue[0] | Sym_Dot);
-  } else {
-    c = 0;
-    while (volt >= 1000) {
-      volt -= 1000;
-      c ++;
+/** ïåðåêëþ÷åíèå ðåæèìîâ îòîáðàæåíèÿ */
+static void displayMode(mode_led_t * disp, event_t event, uint8_t pos) {
+  if (pos != 0) {
+    pos = 4;
+  }
+
+  if (event == eventShortPress) {
+    switch (*disp) {
+    case dispNoState:
+      showLabelU(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineU, 1000, 250);
+      } else {
+        RTOS_SetTask(showBotLineU, 1000, 250);
+      }
+      *disp = displayV;
+      break;
+    case displayV:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineU);
+        RTOS_SetTask(showTopLineI, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineU);
+        RTOS_SetTask(showBotLineI, 1000, 250);
+      }
+      showLabelI(pos);
+      *disp = displayI;
+      break;
+    case displayI:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineI);
+        RTOS_SetTask(showTopLineP, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineI);
+        RTOS_SetTask(showBotLineP, 1000, 250);
+      }
+      showLabelP(pos);
+      *disp = displayP;
+      break;
+    case displayP:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineP);
+        RTOS_SetTask(showTopLineAH, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineP);
+        RTOS_SetTask(showBotLineAH, 1000, 250);
+      }
+      showLabelAH(pos);
+      *disp = displayCI;
+      break;
+    case displayCI:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineAH);
+        RTOS_SetTask(showTopLineWH, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineAH);
+        RTOS_SetTask(showBotLineWH, 1000, 250);
+      }
+      showLabelWH(pos);
+      *disp = displayCP;
+      break;
+    case displayCP:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineWH);
+        RTOS_SetTask(showTopLineT, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineWH);
+        RTOS_SetTask(showBotLineT, 1000, 250);
+      }
+      showLabelT(pos);
+      *disp = displayT;
+      break;
+    case displayT:
+      if (pos == 0) {
+        RTOS_DeleteTask(showTopLineT);
+        RTOS_SetTask(showTopLineU, 1000, 250);
+      } else {
+        RTOS_DeleteTask(showBotLineT);
+        RTOS_SetTask(showBotLineU, 1000, 250);
+      }
+      showLabelU(pos);
+      *disp = displayV;
+      break;
+    }
+  } else if (event == eventLongPress) {
+    /* ÊÀ äîëãèõ íàæàòèé */
+    switch (*disp) {
+    case displayCI:
+      if (pos == 0) {
+        RTOS_SetTask(blankTopLine, 0, 500);
+        RTOS_SetTask(showTopLineAH, 250, 500);
+      } else {
+        RTOS_SetTask(blankBotLine, 0, 500);
+        RTOS_SetTask(showBotLineAH, 250, 500);
+      }
+      showLabelAH(pos);
+      break;
+    case displayCP:
+      if (pos == 0) {
+        RTOS_SetTask(blankTopLine, 0, 500);
+        RTOS_SetTask(showTopLineWH, 250, 500);
+      } else {
+        RTOS_SetTask(blankBotLine, 0, 500);
+        RTOS_SetTask(showBotLineWH, 250, 500);
+      }
+      showLabelWH(pos);
+      break;
+    case displayT:
+      if (pos == 0) {
+        RTOS_SetTask(blankTopLine, 0, 500);
+        RTOS_SetTask(showTopLineT, 250, 500);
+      } else {
+        RTOS_SetTask(blankBotLine, 0, 500);
+        RTOS_SetTask(showBotLineT, 250, 500);
+      }
+      showLabelT(pos);
+      break;
     }
-    MAX7219_WriteData(digitPosition[3], digitValue[c] | Sym_Dot);
   }
+}
 
-  if (volt < 100) {
-    MAX7219_WriteData(digitPosition[5], digitValue[0]);
-  } else {
-    c = 0;
-    while (volt >= 100) {
-      volt -= 100;
-      c ++;
+/** îáðàáîò÷èê êîðîòêîãî íàæàòèÿ ïåðâîé êíîïêè */
+static void btn1Short(void) {
+  displayMode(&modeTopLine, eventShortPress, 0);
+}
+
+/** îáðàáîò÷èê äëèííîãî íàæàòèÿ ïåðâîé êíîïêè */
+static void btn1Long(void) {
+  displayMode(&modeTopLine, eventLongPress, 0);
+}
+
+/** îáðàáîò÷èê êîðîòêîãî íàæàòèÿ âòîðîé êíîïêè */
+static void btn2Short(void) {
+  displayMode(&modeBotLine, eventShortPress, 4);
+}
+
+/** îáðàáîò÷èê äëèííîãî íàæàòèÿ âòîðîé êíîïêè */
+static void btn2Long(void) {
+  Timer.ss = 0;
+  Timer.mm = 0;
+  Timer.hh = 0;
+  CapacityAH = 0;
+  CapacityWH = 0;
+  displayMode(&modeBotLine, eventLongPress, 4);
+}
+
+/** Get values from INA219 and store to local variables. */
+static void readINAValues(void) {
+  Voltage = readBusVoltage();
+  Current = readBusCurrent();
+  Power = readBusPower();
+}
+
+/**
+  * âûâîä èíôû íà âåðõíåì èíäèêàòîðå
+  */
+static void showTopLineU(void) {
+  showU(0);
+}
+
+static void showTopLineI(void) {
+  showI(0);
+}
+
+static void showTopLineP(void) {
+  showP(0);
+}
+
+static void showTopLineAH(void) {
+  showCI(0);
+}
+
+static void showTopLineWH(void) {
+  showCP(0);
+}
+
+static void showTopLineT(void) {
+  showT(0);
+}
+
+static void blankTopLine(void) {
+  blankLine(0);
+}
+
+/**
+  * âûâîä èíôû íà íèæíåì èíäèêàòîðå
+  */
+static void showBotLineU(void) {
+  showU(4);
+}
+
+static void showBotLineI(void) {
+  showI(4);
+}
+
+static void showBotLineP(void) {
+  showP(4);
+}
+
+static void showBotLineAH(void) {
+  showCI(4);
+}
+
+static void showBotLineWH(void) {
+  showCP(4);
+}
+
+static void showBotLineT(void) {
+  showT(4);
+}
+
+static void blankBotLine(void) {
+  blankLine(4);
+}
+
+/**
+  * Output given value to given indicator
+  * param1: value to show, from '0.000' to '999.9'
+  * param2: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showValue(uint32_t val, uint8_t pos) {
+  uint8_t tmp;
+
+  if (pos != 0) {
+    pos = 4;
+  }
+
+  if (val >= 100000) { // 000.0
+    tmp = (uint8_t)(val / 100000);
+    val %= 100000;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+    tmp = (uint8_t)(val / 10000);
+    val %= 10000;
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+    tmp = (uint8_t)(val / 1000);
+    val %= 1000;
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], (digitValue[tmp] | Sym_Dot));
+
+    tmp = (uint8_t)(val / 100);
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+  } else if (val >= 10000) { // 00.00
+    tmp = (uint8_t)(val / 10000);
+    val %= 10000;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+    tmp = (uint8_t)(val / 1000);
+    val %= 1000;
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], (digitValue[tmp] | Sym_Dot));
+
+    tmp = (uint8_t)(val / 100);
+    val %= 100;
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+    tmp = (uint8_t)(val / 10);
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+  } else { // 0.000
+    tmp = (uint8_t)(val / 1000);
+    val %= 1000;
+    MAX7219_WriteData(digitPosition[pos], (digitValue[tmp] | Sym_Dot));
+
+    tmp = (uint8_t)(val / 100);
+    val %= 100;
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+    tmp = (uint8_t)(val / 10);
+    val %= 10;
+    pos ++;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+
+    pos ++;
+    tmp = val;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+  }
+
+}
+
+/**
+  * fill line by blank symbol
+  */
+void blankLine(uint8_t pos) {
+  uint8_t i = pos;
+  for (i=0; i<pos+4; i++) {
+    MAX7219_WriteData(digitPosition[i], Sym_BLANK);
+  }
+}
+
+/**
+  * Output voltage values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showU(uint8_t pos) {
+  //showValue(slowBuf.Voltage[slowBuf.idx], pos);
+  showValue(Voltage, pos);
+}
+
+/**
+  * Output current values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showI(uint8_t pos) {
+  //showValue(slowBuf.Current[slowBuf.idx], pos);
+  showValue(Current, pos);
+}
+
+/**
+  * Output power values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showP(uint8_t pos) {
+  showValue(Power, pos);
+}
+
+/**
+  * Output current capacity values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showCI(uint8_t pos) {
+  showValue(((CapacityAH + 1800) / 3600), pos);
+}
+
+/**
+  * Output power capacity values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showCP(uint8_t pos) {
+  showValue(((CapacityWH + 1800) / 3600), pos);
+}
+
+/**
+  * Output time values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showT(uint8_t pos) {
+  static uint8_t halfsek = 0;
+  uint8_t tmp;
+
+  if (Timer.hh > 0) {
+    tmp = Timer.hh / 10;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+    pos ++;
+    tmp = Timer.hh % 10;
+    if (halfsek == 0) {
+      MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+    } else {
+      MAX7219_WriteData(digitPosition[pos], (digitValue[tmp] | Sym_Dot));
     }
-    MAX7219_WriteData(digitPosition[5], digitValue[c]);
+    pos ++;
+    tmp = Timer.mm / 10;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+    pos ++;
+    tmp = Timer.mm % 10;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+  } else {
+    tmp = Timer.mm / 10;
+    MAX7219_WriteData(digitPosition[pos], digitValue[Timer.mm >> 4]);
+    pos ++;
+    tmp = Timer.mm % 10;
+    MAX7219_WriteData(digitPosition[pos], (digitValue[tmp] | Sym_Dot));
+    pos ++;
+    tmp = Timer.ss / 10;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
+    pos ++;
+    tmp = Timer.ss % 10;
+    MAX7219_WriteData(digitPosition[pos], digitValue[tmp]);
   }
 
-  if (volt < 10) {
-    MAX7219_WriteData(digitPosition[6], digitValue[0]);
+  if (halfsek == 0) {
+    halfsek = 1;
   } else {
-    c = 0;
-    while (volt >= 10) {
-      volt -= 10;
-      c ++;
-    }
-    MAX7219_WriteData(digitPosition[6], digitValue[c]);
+    halfsek = 0;
   }
+}
+
+/**
+  * show label for selected mode
+  */
+static void showLabelU(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_U);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_BLANK);
+}
+
+static void showLabelI(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_1);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_BLANK);
+}
+
+static void showLabelP(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_P);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_BLANK);
+}
+
+static void showLabelAH(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_A);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_H);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+}
+
+static void showLabelWH(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_P);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_H);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+}
 
-  MAX7219_WriteData(digitPosition[7], digitValue[volt]);
+static void showLabelT(uint8_t pos) {
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_t);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(digitPosition[pos], Sym_BLANK);
 }
 
 #ifdef USE_FULL_ASSERT