Переглянути джерело

Переделал вывод значений. Доьавил обраотку кнопок и всё сопутсвующее.

Vladimir N. Shilov 9 роки тому
батько
коміт
8e810452bb
1 змінених файлів з 457 додано та 72 видалено
  1. 457 72
      src/main.c

+ 457 - 72
src/main.c

@@ -29,12 +29,35 @@
   */
 
 /* Private typedef -----------------------------------------------------------*/
+typedef enum _modes_led {
+  dispNoState = 0x00,
+  displayU,
+  displayI,
+  displayP,
+  displayAH,
+  displayWH,
+  displayT
+} mode_led_t;
+
+typedef enum _events {
+  eventNoEvent  = 0x00,
+  eventShortPress,
+  eventLongPress
+} event_t;
+
 /* Private define ------------------------------------------------------------*/
 #define LED_RED_PORT    GPIOC
 #define LED_RED_PIN     GPIO_Pin_4
 #define LED_GREEN_PORT  GPIOB
 #define LED_GREEN_PIN   GPIO_Pin_7
 
+#define BTNs_PORT       GPIOC
+#define BTN1_PIN        GPIO_Pin_0
+#define BTN2_PIN        GPIO_Pin_1
+#define BTN_SCAN_PERIOD 10
+// кнопка считается нажатой через BTN_FACTOR * BTN_SCAN_PERIOD ms
+#define BTN_FACTOR      5
+
 #define VALUES_BUFFER_SIZE  10
 
 /* Private macro -------------------------------------------------------------*/
@@ -66,16 +89,60 @@ 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 displayTopLine, displayBotLine;
 
 /* Private function prototypes -----------------------------------------------*/
 static void GPIO_Config(void);
 static void CLK_Config(void);
 
+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 showAH(uint8_t pos);
+static void showWH(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);
+
 /* RTOS function prototypes -----------------------------------------------*/
 static void getADCValues(void);
 static void calculateValues(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 btnScan(void);
+static void testButton(uint8_t btnPin, 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);
 
 /* Private functions ---------------------------------------------------------*/
 
@@ -102,34 +169,37 @@ void main(void)
   MAX7219_Config();
 
   /* ROTS tasks */
-  RTOS_SetTask(getADCValues,100,100);
-  RTOS_SetTask(calculateValues,101,1000);
-  RTOS_SetTask(showTopLineU,102,250);
-  RTOS_SetTask(showBotLineI,103,250);
+  RTOS_SetTask(btnScan, 0, BTN_SCAN_PERIOD);
+  RTOS_SetTask(getADCValues, 100, 100);
+  RTOS_SetTask(calculateValues, 101, 1000);
+  RTOS_SetTask(showTopLineU, 102, 200);
+  RTOS_SetTask(showBotLineI, 103, 200);
+  displayTopLine = displayU;
+  displayBotLine = displayI;
 
   /* Infinite loop */
   while (1) {
       RTOS_DispatchTask();
       wfi();
   }
-}
+} // End of main()
 
 /**
   * Забираем обработанные данные из быстрого буфера
   * и складываем в медленный.
   */
 static void getADCValues(void) {
-  static uint8_t idxVal=0;
+  static uint8_t  bufIdx = 0;
   uint16_t * avgVal;
 
   avgVal = ADC_GetValues();
 
-  bufVoltage[idxVal] = *avgVal;
-  bufCurrent[idxVal] = *(avgVal + 1);
+  bufVoltage[bufIdx] = *avgVal;
+  bufCurrent[bufIdx] = *(avgVal + 1);
 
-  idxVal ++;
-  if (idxVal == VALUES_BUFFER_SIZE) {
-    idxVal = 0;
+  bufIdx ++;
+  if (bufIdx == VALUES_BUFFER_SIZE) {
+    bufIdx = 0;
   }
 }
 
@@ -154,12 +224,150 @@ static void calculateValues(void) {
 
   CapacityAH += Current;
   CapacityWH += Power;
+
+  Timer.ss ++;
+  if (Timer.ss > 59) {
+    Timer.ss = 0;
+    Timer.mm ++;
+    if (Timer.mm > 59) {
+      Timer.hh ++;
+    }
+  }
 }
 
 /**
-  * Output voltage values to top indicator
+  * вывод инфы на верхнем индикаторе
   */
 static void showTopLineU(void) {
+  showU(0);
+}
+
+static void showTopLineI(void) {
+  showI(0);
+}
+
+static void showTopLineP(void) {
+  showP(0);
+}
+
+static void showTopLineAH(void) {
+  showAH(0);
+}
+
+static void showTopLineWH(void) {
+  showWH(0);
+}
+
+static void showTopLineT(void) {
+  showT(0);
+}
+
+/**
+  * вывод инфы на нижнем индикаторе
+  */
+static void showBotLineU(void) {
+  showU(4);
+}
+
+static void showBotLineI(void) {
+  showI(4);
+}
+
+static void showBotLineP(void) {
+  showP(4);
+}
+
+static void showBotLineAH(void) {
+  showAH(4);
+}
+
+static void showBotLineWH(void) {
+  showWH(4);
+}
+
+static void showBotLineT(void) {
+  showT(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(dig[pos], num[tmp]);
+
+    tmp = (uint8_t)(val / 10000);
+    val %= 10000;
+    pos ++;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+    tmp = (uint8_t)(val / 1000);
+    val %= 1000;
+    pos ++;
+    MAX7219_WriteData(dig[pos], (num[tmp] | Sym_Dot));
+
+    tmp = (uint8_t)(val / 100);
+    pos ++;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+  } else if(val >= 10000){ // 00.00
+    tmp = (uint8_t)(val / 10000);
+    val %= 10000;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+    tmp = (uint8_t)(val / 1000);
+    val %= 1000;
+    pos ++;
+    MAX7219_WriteData(dig[pos], (num[tmp] | Sym_Dot));
+
+    tmp = (uint8_t)(val / 100);
+    val %= 100;
+    pos ++;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+    tmp = (uint8_t)(val / 10);
+    pos ++;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+  } else { // 0.000
+    tmp = (uint8_t)(val / 1000);
+    val %= 1000;
+    MAX7219_WriteData(dig[pos], (num[tmp] | Sym_Dot));
+
+    tmp = (uint8_t)(val / 100);
+    val %= 100;
+    pos ++;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+    tmp = (uint8_t)(val / 10);
+    val %= 10;
+    pos ++;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+
+    pos ++;
+    tmp = val;
+    MAX7219_WriteData(dig[pos], num[tmp]);
+  }
+
+}
+
+/**
+  * Output voltage values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showU(uint8_t pos) {
   uint32_t vlt = 0;
   uint8_t tmp;
 
@@ -168,48 +376,16 @@ static void showTopLineU(void) {
   }
   vlt /= VALUES_BUFFER_SIZE;
 
-//  LED_RED_ON;
-
-  if(vlt >= 10000){
-    /* Tens Thousands voltage value*/
-    tmp = (uint8_t)(vlt / 10000);
-    vlt %= 10000;
-    MAX7219_WriteData(dig[0], num[tmp]);
-    /* Thousands voltage value*/
-    tmp = (uint8_t)(vlt / 1000);
-    vlt %= 1000;
-    MAX7219_WriteData(dig[1], (num[tmp] | SYM_DOT));
-    /* Hundreds voltage value */
-    tmp = (uint8_t)(vlt / 100);
-    vlt %= 100;
-    MAX7219_WriteData(dig[2], num[tmp]);
-    /* Tens voltage value */
-    tmp = (uint8_t)(vlt / 10);
-    MAX7219_WriteData(dig[3], num[tmp]);
-  } else {
-    /* Thousands voltage value*/
-    tmp = (uint8_t)(vlt / 1000);
-    vlt %= 1000;
-    MAX7219_WriteData(dig[0], (num[tmp] | SYM_DOT));
-    /* Hundreds voltage value */
-    tmp = (uint8_t)(vlt / 100);
-    vlt %= 100;
-    MAX7219_WriteData(dig[1], num[tmp]);
-    /* Tens voltage value */
-    tmp = (uint8_t)(vlt / 10);
-    vlt %= 10;
-    MAX7219_WriteData(dig[2], num[tmp]);
-    /* Ones voltage value */
-    MAX7219_WriteData(dig[3], num[(uint8_t)vlt]);
-  }
+  showValue(vlt, pos);
 }
 
 /**
-  * Output current values to bottom indicator
+  * Output current values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
   */
-static void showBotLineI(void){
-//  LED_RED_OFF; // индикация режима
-  uint16_t crnt = 0;
+static void showI(uint8_t pos) {
+  uint32_t crnt = 0;
   uint8_t tmp;
 
   for (tmp=0; tmp<VALUES_BUFFER_SIZE; tmp++) {
@@ -217,31 +393,45 @@ static void showBotLineI(void){
   }
   crnt /= VALUES_BUFFER_SIZE;
 
-  if (crnt >= 1000) {
-    tmp = crnt / 1000;
-    crnt %= 1000;
-  } else {
-    tmp = 0;
-  }
-  MAX7219_WriteData(dig[4], (num[tmp] | SYM_DOT));
+  showValue(crnt, pos);
+}
 
-  if (crnt >= 100) {
-    tmp = crnt / 100;
-    crnt %= 100;
-  } else {
-    tmp = 0;
-  }
-  MAX7219_WriteData(dig[5], num[tmp]);
+/**
+  * 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);
+}
 
-  if (crnt >= 10) {
-    tmp = crnt / 10;
-    crnt %= 10;
-  } else {
-    tmp = 0;
-  }
-  MAX7219_WriteData(dig[6], num[tmp]);
+/**
+  * Output current capacity values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showAH(uint8_t pos) {
+  showValue(CapacityAH, pos);
+}
+
+/**
+  * Output power capacity values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showWH(uint8_t pos) {
+  showValue(CapacityWH, pos);
+}
 
-  MAX7219_WriteData(dig[7], num[crnt]);
+/**
+  * Output time values to given indicator
+  * param: starting position -- 0 for top
+  * any other for bottom.
+  */
+static void showT(uint8_t pos) {
+  if (pos > 0) {
+    pos = 4;
+  }
 }
 
 /**
@@ -255,6 +445,10 @@ static void GPIO_Config(void)
   GPIO_Init(LED_RED_PORT, LED_RED_PIN, GPIO_Mode_Out_PP_High_Fast);
   GPIO_Init(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_Mode_Out_PP_High_Fast);
 
+  /* Configure GPIO used for buttons */
+  GPIO_Init(BTNs_PORT, BTN1_PIN, GPIO_Mode_In_PU_No_IT);
+  GPIO_Init(BTNs_PORT, BTN2_PIN, GPIO_Mode_In_PU_No_IT);
+
   /* Enable general interrupts */
   enableInterrupts();
 }
@@ -277,6 +471,197 @@ static void CLK_Config(void)
   CLK_HSICmd(ENABLE);
 }
 
+/** опрос кнопок */
+static void btnScan(void) {
+  testButton(BTN1_PIN, &btn1Cnt, btn1Short, btn1Long);
+  testButton(BTN2_PIN, &btn2Cnt, btn2Short, btn2Long);
+}
+
+/** проверка конкретной кнопки */
+static void testButton(uint8_t btnPin, uint8_t *pressCount, void (*taskShortPress)(void), void (*taskLongPress)(void)) {
+  if (BTNs_PORT->IDR & (uint8_t)btnPin == 0) {
+
+    if (*pressCount < 255) {
+      *pressCount = *pressCount + 1;
+    }
+/*
+    if (*pressCount ==  BTN_FACTOR) {
+         // short
+      } else if(*pressCount == (BTN_FACTOR * 10)) {
+         // long
+      }
+*/
+  } else {
+    if (*pressCount > (BTN_FACTOR * 10)) {
+      RTOS_SetTask(taskLongPress, 0, 0); // вызов функции при длительном нажатии
+    } else if (*pressCount > BTN_FACTOR) {
+      RTOS_SetTask(taskShortPress, 0, 0); // вызов функции при коротком нажатии
+    }
+    *pressCount = 0;
+  }
+}
+
+/** переключение режимов отображения */
+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, 200);
+      } else {
+        RTOS_SetTask(showBotLineU, 1000, 200);
+      }
+      *disp = displayU;
+      break;
+    case displayU:
+      showLabelI(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineI, 1000, 200);
+      } else {
+        RTOS_SetTask(showBotLineI, 1000, 200);
+      }
+      *disp = displayI;
+      break;
+    case displayI:
+      showLabelP(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineP, 1000, 200);
+      } else {
+        RTOS_SetTask(showBotLineP, 1000, 200);
+      }
+      *disp = displayP;
+      break;
+    case displayP:
+      showLabelAH(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineAH, 1000, 200);
+      } else {
+        RTOS_SetTask(showBotLineAH, 1000, 200);
+      }
+      *disp = displayAH;
+      break;
+    case displayAH:
+      showLabelWH(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineWH, 1000, 200);
+      } else {
+        RTOS_SetTask(showBotLineWH, 1000, 200);
+      }
+      *disp = displayWH;
+      break;
+    case displayWH:
+      showLabelU(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineT, 1000, 200);
+      } else {
+        RTOS_SetTask(showBotLineT, 1000, 200);
+      }
+      *disp = displayT;
+      break;
+    case displayT:
+      showLabelU(pos);
+      if (pos == 0) {
+        RTOS_SetTask(showTopLineU, 1000, 200);
+      } else {
+        RTOS_SetTask(showBotLineU, 1000, 200);
+      }
+      *disp = displayU;
+      break;
+    }
+  }
+}
+
+/** обработчик короткого нажатия первой кнопки */
+static void btn1Short(void) {
+  displayMode(&displayTopLine, eventShortPress, 0);
+}
+
+/** обработчик длинного нажатия первой кнопки */
+static void btn1Long(void) {
+}
+
+/** обработчик короткого нажатия второй кнопки */
+static void btn2Short(void) {
+  displayMode(&displayBotLine, eventShortPress, 4);
+}
+
+/** обработчик длинного нажатия второй кнопки */
+static void btn2Long(void) {
+  Timer.ss = 0;
+  Timer.mm = 0;
+  Timer.hh = 0;
+  CapacityAH = 0;
+  CapacityWH = 0;
+}
+
+/**
+  * show label for selected mode
+  */
+static void showLabelU(uint8_t pos) {
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_U);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_BLANK);
+}
+
+static void showLabelI(uint8_t pos) {
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_1);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_BLANK);
+}
+
+static void showLabelP(uint8_t pos) {
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_P);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_BLANK);
+}
+
+static void showLabelAH(uint8_t pos) {
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_A);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_H);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+}
+
+static void showLabelWH(uint8_t pos) {
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_P);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_H);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+}
+
+static void showLabelT(uint8_t pos) {
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_t);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_Minus);
+  pos ++;
+  MAX7219_WriteData(dig[pos], Sym_BLANK);
+}
+
 
 #ifdef  USE_FULL_ASSERT