فهرست منبع

Test I2C, INA219, RTOS.

Vladimir N. Shilov 5 سال پیش
والد
کامیت
9eb3e3ad14
9فایلهای تغییر یافته به همراه186 افزوده شده و 271 حذف شده
  1. 1 1
      Makefile
  2. 1 1
      inc/stm8s_conf.h
  3. 36 108
      lib/i2c.c
  4. 2 4
      lib/i2c.h
  5. 57 93
      lib/ina219.c
  6. 12 7
      lib/ina219.h
  7. 2 46
      lib/rtos.c
  8. 3 5
      lib/rtos.h
  9. 72 6
      src/main.c

+ 1 - 1
Makefile

@@ -16,7 +16,7 @@ FLASHOPT=-no_log -no_loop -Device=STM8S003F3
 
 DEFINES = -D USE_STDPERIPH_DRIVER
 DEFINES += -D STM8S003
-#DEFINES += -D USE_RTOS
+DEFINES += -D USE_RTOS
 
 # Sources paths
 APP_SRC = src

+ 1 - 1
inc/stm8s_conf.h

@@ -90,7 +90,7 @@
 /* Exported constants --------------------------------------------------------*/
 /* Uncomment the line below to expanse the "assert_param" macro in the
    Standard Peripheral Library drivers code */
-#define USE_FULL_ASSERT    (1) 
+//#define USE_FULL_ASSERT    (1) 
 
 /* Exported macro ------------------------------------------------------------*/
 #ifdef  USE_FULL_ASSERT

+ 36 - 108
lib/i2c.c

@@ -57,8 +57,7 @@ void i2c_master_init(void) {
 /**
  * @brief Запись регистра slave-устройства
  */
-t_i2c_status i2c_wr_reg(uint8_t address, uint8_t reg_addr, \
-                        const uint8_t * data, uint8_t length) {
+t_i2c_status i2c_wr_reg(uint8_t address, uint8_t reg_addr, uint16_t data) {
 
   //Ждем освобождения шины I2C
   wait_event((I2C->SR3 & I2C_SR3_BUSY), 10);
@@ -83,12 +82,14 @@ t_i2c_status i2c_wr_reg(uint8_t address, uint8_t reg_addr, \
   I2C->DR = reg_addr;
 
   //Отправка данных
-  while(length --) {
-    //Ждем освобождения регистра данных
-    wait_event(!(I2C->SR1 & I2C_SR1_TXE), 1);
-    //Отправляем адрес регистра
-    I2C->DR = *data++;
-  }
+  //Ждем освобождения регистра данных
+  wait_event(!(I2C->SR1 & I2C_SR1_TXE), 1);
+  //Отправляем адрес регистра
+  I2C->DR = (uint8_t)(data >> 8);
+  //Ждем освобождения регистра данных
+  wait_event(!(I2C->SR1 & I2C_SR1_TXE), 1);
+  //Отправляем адрес регистра
+  I2C->DR = (uint8_t)data;
 
   //Ловим момент, когда DR освободился и данные попали в сдвиговый регистр
   wait_event(!((I2C->SR1 & I2C_SR1_TXE) && (I2C->SR1 & I2C_SR1_BTF)), 1);
@@ -105,8 +106,7 @@ t_i2c_status i2c_wr_reg(uint8_t address, uint8_t reg_addr, \
  * @brief Чтение регистра slave-устройства
  * @note Start -> Slave Addr -> Reg. addr -> Restart -> Slave Addr <- data ... -> Stop
  */
-t_i2c_status i2c_rd_reg(uint8_t address, uint8_t reg_addr, \
-                        uint8_t * data, uint8_t length) {
+t_i2c_status i2c_rd_reg(uint8_t address, uint8_t reg_addr, uint16_t * data) {
 
   //Ждем освобождения шины I2C
   wait_event((I2C->SR3 & I2C_SR3_BUSY), 10);
@@ -143,104 +143,32 @@ t_i2c_status i2c_rd_reg(uint8_t address, uint8_t reg_addr, \
   //в режим чтения (установкой младшего бита в 1)
   I2C->DR = address | 0x01;
 
-  //Дальше алгоритм зависит от количества принимаемых байт
-  //N=1
-  if(length == 1){
-    //Запрещаем подтверждение в конце посылки
-    I2C->CR2 &= ~I2C_CR2_ACK;
-    //Ждем подтверждения передачи адреса
-    wait_event(!(I2C->SR1 & I2C_SR1_ADDR), 1);
-
-    //Заплатка из Errata
-    disableInterrupts();
-    //Очистка бита ADDR чтением регистра SR3
-    I2C->SR3;
-
-    //Устанавлием бит STOP
-    I2C->CR2 |= I2C_CR2_STOP;
-    //Заплатка из Errata
-    enableInterrupts();
-
-    //Ждем прихода данных в RD
-    wait_event(!(I2C->SR1 & I2C_SR1_RXNE), 1);
-
-    //Читаем принятый байт
-    *data = I2C->DR;
-  }
-  //N=2
-  else if(length == 2){
-    //Бит который разрешает NACK на следующем принятом байте
-    I2C->CR2 |= I2C_CR2_POS;
-    //Ждем подтверждения передачи адреса
-    wait_event(!(I2C->SR1 & I2C_SR1_ADDR), 1);
-    //Заплатка из Errata
-    disableInterrupts();
-    //Очистка бита ADDR чтением регистра SR3
-    I2C->SR3;
-    //Запрещаем подтверждение в конце посылки
-    I2C->CR2 &= (uint8_t)(~I2C_CR2_ACK);
-    //Заплатка из Errata
-    enableInterrupts();
-    //Ждем момента, когда первый байт окажется в DR,
-    //а второй в сдвиговом регистре
-    wait_event(!(I2C->SR1 & I2C_SR1_BTF), 1);
-
-    //Заплатка из Errata
-    disableInterrupts();
-    //Устанавлием бит STOP
-    I2C->CR2 |= I2C_CR2_STOP;
-    //Читаем принятые байты
-    *data++ = I2C->DR;
-    //Заплатка из Errata
-    enableInterrupts();
-    *data = I2C->DR;
-  }
-  //N>2
-  else if(length > 2){
-    //Ждем подтверждения передачи адреса
-    wait_event(!(I2C->SR1 & I2C_SR1_ADDR), 1);
-
-    //Заплатка из Errata
-    disableInterrupts();
-
-    //Очистка бита ADDR чтением регистра SR3
-    I2C->SR3;
-
-    //Заплатка из Errata
-    enableInterrupts();
-
-    I2C_timeout = 10; // 10 ms ???
-    while (length-- > 3 && I2C_timeout) {
-      //Ожидаем появления данных в DR и сдвиговом регистре
-      wait_event(!(I2C->SR1 & I2C_SR1_BTF), 1);
-      //Читаем принятый байт из DR
-      *(data++) = I2C->DR;
-    }
-    //Время таймаута вышло
-    if(!I2C_timeout) return I2C_TIMEOUT;
-
-    //Осталось принять 3 последних байта
-    //Ждем, когда в DR окажется N-2 байт, а в сдвиговом регистре
-    //окажется N-1 байт
-    wait_event(!(I2C->SR1 & I2C_SR1_BTF), 1);
-    //Запрещаем подтверждение в конце посылки
-    I2C->CR2 &= (uint8_t)(~I2C_CR2_ACK);
-    //Заплатка из Errata
-    disableInterrupts();
-    //Читаем N-2 байт из RD, тем самым позволяя принять в сдвиговый
-    //регистр байт N, но теперь в конце приема отправится посылка NACK
-    *(data++) = I2C->DR;
-    //Посылка STOP
-    I2C->CR2 |= I2C_CR2_STOP;
-    //Читаем N-1 байт
-    *(data++) = I2C->DR;
-    //Заплатка из Errata
-    enableInterrupts();
-    //Ждем, когда N-й байт попадет в DR из сдвигового регистра
-    wait_event(!(I2C->SR1 & I2C_SR1_RXNE), 1);
-    //Читаем N байт
-    *(data++) = I2C->DR;
-  }
+  //Отправка двух байт данных
+  //Бит который разрешает NACK на следующем принятом байте
+  I2C->CR2 |= I2C_CR2_POS;
+  //Ждем подтверждения передачи адреса
+  wait_event(!(I2C->SR1 & I2C_SR1_ADDR), 1);
+  //Заплатка из Errata
+  disableInterrupts();
+  //Очистка бита ADDR чтением регистра SR3
+  I2C->SR3;
+  //Запрещаем подтверждение в конце посылки
+  I2C->CR2 &= (uint8_t)(~I2C_CR2_ACK);
+  //Заплатка из Errata
+  enableInterrupts();
+  //Ждем момента, когда первый байт окажется в DR,
+  //а второй в сдвиговом регистре
+  wait_event(!(I2C->SR1 & I2C_SR1_BTF), 1);
+
+  //Заплатка из Errata
+  disableInterrupts();
+  //Устанавлием бит STOP
+  I2C->CR2 |= I2C_CR2_STOP;
+  //Читаем принятые байты
+  *data = I2C->DR << 8;
+  //Заплатка из Errata
+  enableInterrupts();
+  *data |= I2C->DR;
 
   //Ждем отправки СТОП посылки
   wait_event((I2C->CR2 & I2C_CR2_STOP), 1);

+ 2 - 4
lib/i2c.h

@@ -26,10 +26,8 @@ typedef enum {
 extern void i2c_master_init(void);
 
 // Запись регистра slave-устройства
-extern t_i2c_status  i2c_wr_reg(uint8_t address, uint8_t reg_addr, \
-                                const uint8_t * data, uint8_t length);
+extern t_i2c_status  i2c_wr_reg(uint8_t address, uint8_t reg_addr, uint16_t data);
 
 // Чтение регистра slave-устройства
-extern t_i2c_status  i2c_rd_reg(uint8_t address, uint8_t reg_addr, \
-                                uint8_t * data, uint8_t length);
+extern t_i2c_status  i2c_rd_reg(uint8_t address, uint8_t reg_addr, uint16_t * data);
 #endif // I2C_H

+ 57 - 93
lib/ina219.c

@@ -21,112 +21,54 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "INA219.h"
 #include "i2c.h"
 
-static uint8_t inaAddress;
 static uint16_t currentLSB, powerLSB;
-static uint16_t vShuntMax;
-static uint16_t vBusMax;
-static uint16_t Rshunt;
+static uint16_t vShuntMax; // millivolt
+static uint16_t vBusMax; // millivolt
+static uint16_t rShunt; // milliohms
 
-/**
-  * Configure I2C, INA219
-  */
-void INA219_Config(INA219_InitTypeDef * INA219_InitStruct) {
-  uint16_t config;
+static uint8_t flagCNVR; // Conversion Ready
+static uint8_t flagOVF; // Math Overflow Flag
 
-  /** INA219 configure */
-  config  = INA219_InitStruct->INA219_RST;
-  config |= INA219_InitStruct->INA219_BVR;
-  config |= INA219_InitStruct->INA219_PG;
-  config |= INA219_InitStruct->INA219_BADC;
-  config |= INA219_InitStruct->INA219_SADC;
-  config |= INA219_InitStruct->INA219_MODE;
-
-  inaAddress = INA219_InitStruct->INA219_Addr;
-
-  switch(INA219_InitStruct->INA219_BVR) {
-  case INA219_RANGE_32V:
-    vBusMax = 32000;
-    break;
-  case INA219_RANGE_16V:
-    vBusMax = 16000;
-    break;
-  }
-
-  switch(INA219_InitStruct->INA219_PG) {
-  case INA219_GAIN_320MV:
-    vShuntMax = 320;
-    break;
-  case INA219_GAIN_160MV:
-    vShuntMax = 160;
-    break;
-  case INA219_GAIN_80MV:
-    vShuntMax = 80;
-    break;
-  case INA219_GAIN_40MV:
-    vShuntMax = 40;
-    break;
-  }
-
-  I2C_Write_Transaction(inaAddress, INA219_REG_CONFIG, config);
-}
+static t_i2c_status status = I2C_SUCCESS;
 
 /**
-  * @brief  Fills each INA219_InitStruct member with its default value.
-  * @param  INA219_InitStruct: pointer to a INA219_InitTypeDef structure which will
-  *         be initialized.
-  * @retval None
-  */
-void INA219_StructInit(INA219_InitTypeDef * INA219_InitStruct) {
-  /* Reset INA219 init structure parameters values */
-  INA219_InitStruct->INA219_Addr = INA219_ADDRESS;
-  INA219_InitStruct->INA219_RST  = INA219_RESET_OFF;
-  INA219_InitStruct->INA219_BVR  = INA219_RANGE_32V;
-  INA219_InitStruct->INA219_PG   = INA219_GAIN_320MV;
-  INA219_InitStruct->INA219_BADC = INA219_BUS_RES_12BIT;
-  INA219_InitStruct->INA219_SADC = INA219_SHUNT_RES_12BIT;
-  INA219_InitStruct->INA219_MODE = INA219_MODE_SHUNT_BUS_CONT;
-}
-
-/**
-  * Calculate calibration values.
-  * rShuntValue in miliohms, iMaxExpected in miliampers.
+  * Configure I2C, INA219
   */
-void INA219_Calibrate(void) {
+void INA219_Config(void) {
+  uint16_t config;
   uint16_t calibrationValue;
-  /* uint64_t tmp; */
 
-  Rshunt = CURRENT_SHUNT_RESISTENCE; // in milli ohms
+  vBusMax = 32000; // !!! Maximum input voltage only 26V !!!
+  vShuntMax = 80; // !! for shunt 10 mOhm and maximum 8A input current
+  rShunt = CURRENT_SHUNT_RESISTANCE; // in mOhm
 
-  /*
-  tmp = iMaxExpected * 1000UL;
-  currentLSB = (uint16_t)((tmp + 16384) / 32768); // uA
-  powerLSB = (uint16_t)(((tmp * 20) + 16384) / 32768); // uW
+  /** INA219 configure */
+  config  = INA219_RESET_OFF; // INA219_RST
+  config |= INA219_RANGE_32V; // INA219_BVR
+  config |= INA219_GAIN_80MV; // INA219_PG
+  config |= INA219_BUS_RES_12BIT_128S; // INA219_BADC
+  config |= INA219_SHUNT_RES_12BIT_128S; //INA219_SADC
+  config |= INA219_MODE_SHUNT_BUS_CONT; //INA219_MODE
 
-  tmp = ((tmp * rShuntValue * 1000UL) + 16384) / 32768UL;
-  calibrationValue = (uint16_t)((40960000000UL + (tmp >> 1)) / tmp);
-  */
+  i2c_wr_reg(INA219_ADDRESS, INA219_REG_CONFIG, config);
 
   /**
-   * Íàõåð òàêèå ðàñ÷¸òû...
    * ôîðìóëû èç ìàíóàëà:
    * Current_LSB = Maximum Expected Current / 2^15
    * Power_LSB = 20 * Current_LSB
    * Calibration_Value = trunc( 0.04096 / (Current_LSB * Rshunt) )
    */
+  currentLSB = 244; // 8000000 uA / 32768
+  powerLSB = 4880;
 
-  /* íàãðóçêà 50Âò, ìàêñ òîê 4, øóíò ó íàñ 20 ìÎ,
-     Çíà÷åíèÿ LSB â ìèêðîàìïåðàõ è ìèêðîâàòàõ äëÿ äàëüíåéøèõ ðàñ÷¸òîâ */
-  currentLSB = 122; // 4000000 uA / 32768
-  powerLSB = 2440;
-
-  calibrationValue = 16777; // 0.04096 / ((4/32768) * 0.02)
+  calibrationValue = 16777; // 0.04096 / ((8/32768) * 0.01)
 
-  I2C_Write_Transaction(inaAddress, INA219_REG_CALIBRATION, calibrationValue);
+  i2c_wr_reg(INA219_ADDRESS, INA219_REG_CALIBRATION, calibrationValue);
 }
 
 /** */
 uint16_t getMaxPossibleCurrent(void) {
-  return (((1000 * vShuntMax) + (Rshunt>>1)) / Rshunt);
+  return (((1000 * vShuntMax) + (rShunt>>1)) / rShunt);
 }
 
 /** */
@@ -143,7 +85,7 @@ uint16_t getMaxCurrent(void) {
 
 /** */
 uint16_t getMaxShuntVoltage(void) {
-  uint16_t maxVoltage = ((getMaxCurrent() * Rshunt) + 500) / 1000;
+  uint16_t maxVoltage = ((getMaxCurrent() * rShunt) + 500) / 1000;
 
   if (maxVoltage >= vShuntMax) {
     return vShuntMax;
@@ -162,7 +104,11 @@ uint16_t readBusCurrent(void) {
   uint16_t current;
   int16_t tmp;
 
-  I2C_Read_Transaction(inaAddress, INA219_REG_CURRENT, (uint16_t *)&tmp);
+  status = i2c_rd_reg(INA219_ADDRESS, INA219_REG_CURRENT, (uint16_t *)&tmp);
+  if (status != I2C_SUCCESS) {
+    return 9999;
+  }
+
   if (tmp < 0) {
     tmp = - tmp;
   }
@@ -174,7 +120,7 @@ uint16_t readBusCurrent(void) {
 /** */
 uint32_t readBusPower(void) {
   uint16_t power;
-  I2C_Read_Transaction(inaAddress, INA219_REG_POWER, &power);
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_POWER, &power);
   return (((power * powerLSB) + 500) / 1000);
 }
 
@@ -183,7 +129,10 @@ uint32_t readBusPower(void) {
   */
 int16_t readShuntVoltage(void) {
   uint16_t shvolt;
-  I2C_Read_Transaction(inaAddress, INA219_REG_SHUNTVOLTAGE, &shvolt);
+  status = i2c_rd_reg(INA219_ADDRESS, INA219_REG_SHUNTVOLTAGE, &shvolt);
+  if (status != I2C_SUCCESS) {
+    return 999;
+  }
   return shvolt;
 }
 
@@ -192,14 +141,29 @@ int16_t readShuntVoltage(void) {
   */
 uint16_t readBusVoltage(void) {
   uint16_t volt;
-  I2C_Read_Transaction(inaAddress, INA219_REG_BUSVOLTAGE, &volt);
+
+  flagCNVR = 0;
+  flagOVF = 0;
+
+  status = i2c_rd_reg(INA219_ADDRESS, INA219_REG_BUSVOLTAGE, &volt);
+  if (status != I2C_SUCCESS) {
+    return 65535;
+  }
+
+  if ((volt & 0x0001) != 0) {
+    flagOVF = 1;
+  }
+  if ((volt & 0x0002) != 0) {
+    flagCNVR = 1;
+  }
+
   return ((volt >> 3) * 4);
 }
 
 ina219_bvr_t getRange(void) {
   uint16_t value;
 
-  I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
   value &= 0x2000;
   value >>= 13;
 
@@ -209,7 +173,7 @@ ina219_bvr_t getRange(void) {
 ina219_pg_t getGain(void) {
   uint16_t value;
 
-  I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
   value &= 0x1800;
   value >>= 11;
 
@@ -219,7 +183,7 @@ ina219_pg_t getGain(void) {
 ina219_badc_t getBusRes(void) {
   uint16_t value;
 
-  I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
   value &= 0x0780;
   value >>= 7;
 
@@ -229,7 +193,7 @@ ina219_badc_t getBusRes(void) {
 ina219_sadc_t getShuntRes(void) {
   uint16_t value;
 
-  I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
   value &= 0x0078;
   value >>= 3;
 
@@ -239,7 +203,7 @@ ina219_sadc_t getShuntRes(void) {
 ina219_mode_t getMode(void) {
   uint16_t value;
 
-  I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
+  i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
   value &= 0x0007;
 
   return (ina219_mode_t)value;

+ 12 - 7
lib/ina219.h

@@ -23,8 +23,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "stm8s.h"
 
-#define CURRENT_SHUNT_RESISTENCE    20
-#define INA219_ADDRESS              (uint8_t)(0x40<<1)
+#define CURRENT_SHUNT_RESISTANCE    10
+#define INA219_ADDRESS              (uint8_t)(0x40 << 1)
 #define INA219_ADDR_RD              (INA219_ADDRESS | 0x01)
 
 /* INA219 Registers */
@@ -60,7 +60,15 @@ typedef enum
   INA219_BUS_RES_9BIT         = 0x0000,
   INA219_BUS_RES_10BIT        = 0x0080,
   INA219_BUS_RES_11BIT        = 0x0100,
-  INA219_BUS_RES_12BIT        = 0x0180
+  INA219_BUS_RES_12BIT        = 0x0180,
+  INA219_BUS_RES_12BIT_1S     = 0x0400,
+  INA219_BUS_RES_12BIT_2S     = 0x0480,
+  INA219_BUS_RES_12BIT_4S     = 0x0500,
+  INA219_BUS_RES_12BIT_8S     = 0x0580,
+  INA219_BUS_RES_12BIT_16S    = 0x0600,
+  INA219_BUS_RES_12BIT_32S    = 0x0680,
+  INA219_BUS_RES_12BIT_64S    = 0x0700,
+  INA219_BUS_RES_12BIT_128S   = 0x0780
 } ina219_badc_t;
 
 typedef enum
@@ -104,10 +112,7 @@ typedef struct {
   ina219_mode_t   INA219_MODE; /* Operating Mode */
 } INA219_InitTypeDef;
 
-void INA219_Config(INA219_InitTypeDef * INA219_InitStruct);
-void INA219_StructInit(INA219_InitTypeDef * INA219_InitStruct);
-
-void INA219_Calibrate(void);
+void INA219_Config(void);
 
 ina219_bvr_t getRange(void);
 ina219_pg_t getGain(void);

+ 2 - 46
lib/rtos.c

@@ -146,24 +146,6 @@ void RTOS_DispatchTask(void)
    }
 }
 
-/******************************************************************************************
- * Òàéìåðíàÿ ñëóæáà ÐÒÎÑ (ïðåðûâàíèå àïïàðàòíîãî òàéìåðà)
- */
-/*
-static void RTOS_Timer(void)
-{
-   uint8_t i;
-
-   for (i=0; i<arrayTail; i++)         // ïðîõîäèì ïî ñïèñêó çàäà÷
-   {
-      if  (TaskArray[i].delay == 0) {  // åñëè âðåìÿ äî âûïîëíåíèÿ èñòåêëî
-         TaskArray[i].run = 1;         // âçâîäèì ôëàã çàïóñêà,
-      } else {
-         TaskArray[i].delay--;         // èíà÷å óìåíüøàåì âðåìÿ
-      }
-   }
-}
-*/
 /**
   * @brief  Inserts a delay time.
   * @param  nTime: specifies the delay time length, in milliseconds.
@@ -178,31 +160,6 @@ void Delay(__IO uint16_t nTime)
   }
 }
 
-/**
-  * @brief  Decrements the TimingDelay variable.
-  * @note   This function should be called in the
-  *         TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler in the stm8l15x_it.c file.
-  *
-  *       // INTERRUPT_HANDLER(TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler, 19)
-  *       // {
-  *           // TimingDelay_Decrement();
-  *           // TIM2_ClearITPendingBit(TIM2_IT_Update);
-  *
-  *       // }
-  * @param  None
-  * @retval None
-  */
-/*
-static void TimingDelay_Decrement(void)
-{
-  if (TimingDelay != 0x00)
-  {
-    TimingDelay--;
-  }
-}
-*/
-
-#ifdef USE_RTOS
 /**
   * @brief TIM4 Update/Overflow/Trigger Interrupt routine.
   * @param  None
@@ -218,12 +175,12 @@ INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler,23)
     I2C_timeout --;
    }
 
-   /* TimingDelay_Decrement() */
+   /* Decrements the TimingDelay variable */
    if (TimingDelay > 0) {
       TimingDelay --;
    }
 
-   /* RTOS_Timer() */
+   /* Òàéìåðíàÿ ñëóæáà ÐÒÎÑ */
    uint8_t i;
    for (i=0; i<arrayTail; i++) {       // ïðîõîäèì ïî ñïèñêó çàäà÷
       if  (TaskArray[i].delay == 0) {  // åñëè âðåìÿ äî âûïîëíåíèÿ èñòåêëî
@@ -234,4 +191,3 @@ INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler,23)
    }
 
 }
-#endif // USE_RTOS

+ 3 - 5
lib/rtos.h

@@ -30,7 +30,7 @@
 #define  ENABLE_INTERRUPT enableInterrupts()
 #define DISABLE_INTERRUPT disableInterrupts()
 
-/******************************************************************************************
+/**
  * Ñòðóêòóðà çàäà÷è
  */
 typedef struct task
@@ -41,20 +41,18 @@ typedef struct task
    uint8_t run;          // ôëàã ãîòîâíîñòè çàäà÷è ê çàïóñêó
 } task;
 
-/******************************************************************************************
+/**
  * Ïåðåìåííûå
  */
 
-/******************************************************************************************
+/**
  * Ïðîòîòèïû ôóêíöèé
  */
 void RTOS_Init (void);
 void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod);
 void RTOS_DeleteTask (void (*taskFunc)(void));
 void RTOS_DispatchTask (void);
-//void RTOS_Timer(void);
 
 void Delay(__IO uint16_t nTime);
-//void TimingDelay_Decrement(void);
 
 #endif /* __RTOS_H */

+ 72 - 6
src/main.c

@@ -2,7 +2,7 @@
   ******************************************************************************
   * @file    Project/main.c
   * @author  "Vladimir N. Shilov" <shilow@ukr.net>
-  * @version v.0.1
+  * @version v.0.2
   * @date    08-July-2019
   * @brief   Main program body
    ******************************************************************************
@@ -19,7 +19,10 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include "stm8s.h"
+#include "rtos.h"
 #include "max7219.h"
+#include "i2c.h"
+#include "ina219.h"
 
 /* Private defines -----------------------------------------------------------*/
 const static max7219_reg_t digitPosition[8] = {
@@ -33,6 +36,7 @@ const static max7219_sym_t digitValue[16] = {
 
 /* Private function prototypes -----------------------------------------------*/
 static void boardInit(void);
+static void showVoltage(void);
 
 /* Private functions ---------------------------------------------------------*/
 
@@ -40,6 +44,9 @@ void main(void)
 {
   boardInit();
 
+  RTOS_Init();
+  enableInterrupts();
+
   MAX7219_Config();
 
   MAX7219_WriteData(digitPosition[0], Sym_BLANK);
@@ -51,14 +58,21 @@ void main(void)
   MAX7219_WriteData(digitPosition[6], Sym_BLANK);
   MAX7219_WriteData(digitPosition[7], Sym_BLANK);
 
+  if (CLK_GetSYSCLKSource() == CLK_SOURCE_HSE) {
+    MAX7219_WriteData(digitPosition[3], Sym_E);
+  } else {
+    MAX7219_WriteData(digitPosition[3], Sym_i);
+  }
+
+  i2c_master_init();
+  INA219_Config();
+
+  RTOS_SetTask(showVoltage, 70, 250);
+
   /* Infinite loop */
   while (1)
   {
-    if (CLK_GetSYSCLKSource() == CLK_SOURCE_HSE) {
-      MAX7219_WriteData(digitPosition[3], Sym_E);
-    } else {
-      MAX7219_WriteData(digitPosition[3], Sym_i);
-    }
+    wfi();
   }
 
 }
@@ -111,6 +125,58 @@ static void boardInit(void) {
 
 }
 
+/** */
+static void showVoltage(void) {
+  uint8_t c = 0;
+
+  uint16_t volt = readBusVoltage();
+
+  if (volt < 10000) {
+    MAX7219_WriteData(digitPosition[2], digitValue[0]);
+  } else {
+    while (volt >= 10000) {
+      volt -= 10000;
+      c ++;
+    }
+    MAX7219_WriteData(digitPosition[3], digitValue[c]);
+  }
+
+  if (volt < 1000) {
+    MAX7219_WriteData(digitPosition[3], digitValue[0]);
+  } else {
+    c = 0;
+    while (volt >= 1000) {
+      volt -= 1000;
+      c ++;
+    }
+    MAX7219_WriteData(digitPosition[4], digitValue[c] | Sym_Dot);
+  }
+
+  if (volt < 100) {
+    MAX7219_WriteData(digitPosition[5], digitValue[0]);
+  } else {
+    c = 0;
+    while (volt >= 100) {
+      volt -= 100;
+      c ++;
+    }
+    MAX7219_WriteData(digitPosition[5], digitValue[c]);
+  }
+
+  if (volt < 10) {
+    MAX7219_WriteData(digitPosition[6], digitValue[0]);
+  } else {
+    c = 0;
+    while (volt >= 10) {
+      volt -= 10;
+      c ++;
+    }
+    MAX7219_WriteData(digitPosition[6], digitValue[c]);
+  }
+
+  MAX7219_WriteData(digitPosition[7], digitValue[volt]);
+}
+
 #ifdef USE_FULL_ASSERT
 /**
   * @brief  Reports the name of the source file and the source line number