Эх сурвалжийг харах

Закончил с обработкой результатов от АЦП.

Vladimir N. Shilov 9 жил өмнө
parent
commit
d78b6a1365
11 өөрчлөгдсөн 359 нэмэгдсэн , 226 устгасан
  1. 4 1
      .gitignore
  2. 3 3
      Makefile
  3. 57 31
      ReadMe.txt
  4. 117 15
      lib/adc.c
  5. 10 16
      lib/adc.h
  6. 5 5
      lib/max7219.c
  7. 19 19
      lib/max7219.h
  8. 1 1
      lib/rtos.c
  9. 1 1
      lib/rtos.h
  10. 140 115
      src/main.c
  11. 2 19
      src/stm8l15x_it.c

+ 4 - 1
.gitignore

@@ -2,5 +2,8 @@ Out
 ~*.*~
 ~*.*~
 *.layout
 *.layout
 *.save
 *.save
-Debug
 Result.log
 Result.log
+EWSTM8/Debug
+EWSTM8/Release
+EWSTM8/settings
+*.dep

+ 3 - 3
Makefile

@@ -42,7 +42,7 @@ LIST_DIR = $(OUT_DIR)/List
 
 
 # Models
 # Models
 CODE_MODEL = small
 CODE_MODEL = small
-DATA_MODEL = small
+DATA_MODEL = medium
 
 
 # Application object files
 # Application object files
 APP_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(APP_SRC)/*.c)))
 APP_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(APP_SRC)/*.c)))
@@ -119,7 +119,7 @@ LINKFLAGS = --redirect _Printf=_PrintfTinyNoMb
 LINKFLAGS += --redirect _Scanf=_ScanfSmallNoMb
 LINKFLAGS += --redirect _Scanf=_ScanfSmallNoMb
 LINKFLAGS += --config "$(EWSTM8_DIR)\config\$(ICF)"
 LINKFLAGS += --config "$(EWSTM8_DIR)\config\$(ICF)"
 LINKFLAGS += --config_def _CSTACK_SIZE=0x100
 LINKFLAGS += --config_def _CSTACK_SIZE=0x100
-LINKFLAGS += --config_def _HEAP_SIZE=0x100
+LINKFLAGS += --config_def _HEAP_SIZE=0x000
 LINKFLAGS += --map $(OUT_DIR)
 LINKFLAGS += --map $(OUT_DIR)
 LINKFLAGS += --entry __iar_program_start
 LINKFLAGS += --entry __iar_program_start
 LINKFLAGS += --merge_duplicate_sections
 LINKFLAGS += --merge_duplicate_sections
@@ -128,7 +128,7 @@ LINKFLAGS += -f "$(EWSTM8_DIR)\config\math_small.xcl"
 
 
 DBG_LINKFLAGS = --redirect _Printf=_PrintfTinyNoMb --redirect _Scanf=_ScanfSmallNoMb
 DBG_LINKFLAGS = --redirect _Printf=_PrintfTinyNoMb --redirect _Scanf=_ScanfSmallNoMb
 DBG_LINKFLAGS += --config "$(EWSTM8_DIR)\config\$(ICF)" --config_def
 DBG_LINKFLAGS += --config "$(EWSTM8_DIR)\config\$(ICF)" --config_def
-DBG_LINKFLAGS += _CSTACK_SIZE=0x100 --config_def _HEAP_SIZE=0x100
+DBG_LINKFLAGS += _CSTACK_SIZE=0x100 --config_def _HEAP_SIZE=0x000
 DBG_LINKFLAGS += --entry __iar_program_start
 DBG_LINKFLAGS += --entry __iar_program_start
 
 
 
 

+ 57 - 31
ReadMe.txt

@@ -2,10 +2,10 @@
 * Измеритель напряжения/тока/мощности/ёмкости *
 * Измеритель напряжения/тока/мощности/ёмкости *
 
 
 Немогу никак определиться с диапазонами.
 Немогу никак определиться с диапазонами.
-Думал сначал сделать по два диапозона на напряжение и ток, но что-то мне эта 
-идея разонравилась. Опять же, измерять большие напряжения/токи не особо часто 
+Думал сначал сделать по два диапозона на напряжение и ток, но что-то мне эта
+идея разонравилась. Опять же, измерять большие напряжения/токи не особо часто
 приходится. Напряжения в основном до 20 вольт, токи - до пары ампер.
 приходится. Напряжения в основном до 20 вольт, токи - до пары ампер.
-Тем более, так как это измеритель в конкретное устройство, то нужно под него и 
+Тем более, так как это измеритель в конкретное устройство, то нужно под него и
 подстраиваться.
 подстраиваться.
 Будет по одному диапазону на ток и напряжения.
 Будет по одному диапазону на ток и напряжения.
 
 
@@ -13,11 +13,11 @@
 сделать ввод Кд делителя напряжения умноженного на 1000,
 сделать ввод Кд делителя напряжения умноженного на 1000,
 и сопротивление шунта * Ку услителя тока * 1000.
 и сопротивление шунта * Ку услителя тока * 1000.
 
 
-Далее в программе при вычислениях - получили код ацп, перевели в напряжение, 
+Далее в программе при вычислениях - получили код ацп, перевели в напряжение,
 умножили на 1000 и поделили на коэффициент.
 умножили на 1000 и поделили на коэффициент.
 
 
 Ох и здоровая (85х40мм) плата получилась...
 Ох и здоровая (85х40мм) плата получилась...
-можно попробовать разбить на две -- на одной индикатор и кнопки, на второй всё 
+можно попробовать разбить на две -- на одной индикатор и кнопки, на второй всё
 остальное. получится две платы ~ 45х40 мм.
 остальное. получится две платы ~ 45х40 мм.
 
 
 вариант A -- поменял входной разъём.
 вариант A -- поменял входной разъём.
@@ -31,9 +31,9 @@
 
 
 SVN-инит 2014.12.29
 SVN-инит 2014.12.29
 
 
-появилась мысль -- сделать транзисторный ОК выход, например для управления 
+появилась мысль -- сделать транзисторный ОК выход, например для управления
 релюхой. хотя если брать ардуиновское реле -- то там нужен просто выход.
 релюхой. хотя если брать ардуиновское реле -- то там нужен просто выход.
-реле для управления нагрузкой -- можно сделать тот-же зарядно-разрядный 
+реле для управления нагрузкой -- можно сделать тот-же зарядно-разрядный
 автомат.
 автомат.
 ===
 ===
 2014.12.30
 2014.12.30
@@ -82,24 +82,24 @@ SVN-инит 2014.12.29
 ---
 ---
 2016.03.24
 2016.03.24
 
 
-Так-как по прежнему тишь и глухомань, поднял проект в IAR-е и полез в 
+Так-как по прежнему тишь и глухомань, поднял проект в IAR-е и полез в
 отладку. Всё застряло где-то в Delay - похоже на проблемы с таймером.
 отладку. Всё застряло где-то в Delay - похоже на проблемы с таймером.
-Таки да, забыл включить тактирование таймера -- похоже потерялось при 
+Таки да, забыл включить тактирование таймера -- похоже потерялось при
 переносе инициализации то туда, то сюда...
 переносе инициализации то туда, то сюда...
 
 
 Повторяем заповедь -- "Часы, ноги, перефирия".
 Повторяем заповедь -- "Часы, ноги, перефирия".
 
 
-Вобщем, SPI работает. Проблема была в том, что токозадающий резистор для 
+Вобщем, SPI работает. Проблема была в том, что токозадающий резистор для
 MAX нужно подключать на +5В, а у меня он был на земле. Напаял навесом.
 MAX нужно подключать на +5В, а у меня он был на земле. Напаял навесом.
 Картинка появилась, но на индикаторах какой-то бред.
 Картинка появилась, но на индикаторах какой-то бред.
 
 
 Исправил коды символов. Исправил позиции индикаторов.
 Исправил коды символов. Исправил позиции индикаторов.
-Вылезло два момента -- неправильно запаял индикаторы, собирался красный 
-вниз, под ток, а жёлтый вверх под напряжение. В итоге запаял наоборот. Так 
-ещё и на схеме они местами попутаны, так как на плате DS1 внизу, а DS2 
+Вылезло два момента -- неправильно запаял индикаторы, собирался красный
+вниз, под ток, а жёлтый вверх под напряжение. В итоге запаял наоборот. Так
+ещё и на схеме они местами попутаны, так как на плате DS1 внизу, а DS2
 вверху. Исправил схему и позиции индикаторов под факт.
 вверху. Исправил схему и позиции индикаторов под факт.
 
 
-Добился картинки. Похоже тут какой-то бешенный оптимизатор -- выкинул нах 
+Добился картинки. Похоже тут какой-то бешенный оптимизатор -- выкинул нах
 похожую функцию. Нужно учесть на будущее.
 похожую функцию. Нужно учесть на будущее.
 
 
 ---
 ---
@@ -122,30 +122,30 @@ C_adc = 16 * 10^-12, т.е.:
 Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E == 1662
 Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E == 1662
 Если это мерялось при 3В, то получается -- 1.218 В
 Если это мерялось при 3В, то получается -- 1.218 В
 
 
-Предварительный успех -- читаю три канала АЦП и ПДП складывает их в 
-память, преобразовываю и вывожу на индикаторы. Запуск АЦП каждые 10 мсек 
+Предварительный успех -- читаю три канала АЦП и ПДП складывает их в
+память, преобразовываю и вывожу на индикаторы. Запуск АЦП каждые 10 мсек
 тригером от Т2. Настройка Т2 пока заклинанием -- понимания нету.
 тригером от Т2. Настройка Т2 пока заклинанием -- понимания нету.
-На очереди -- усреднение результатов, вычисление напряжения питания через 
+На очереди -- усреднение результатов, вычисление напряжения питания через
 опорное напряжение.
 опорное напряжение.
 
 
 Пока не сильно нравится -- завышает напругу, скачут показания.
 Пока не сильно нравится -- завышает напругу, скачут показания.
 Мерял аккум - 4.219 В, мой точный показывал 4.207, DT-шка - 4.17-4.18 В.
 Мерял аккум - 4.219 В, мой точный показывал 4.207, DT-шка - 4.17-4.18 В.
 Канал внутреннего опорного напряжения показывает 1.219 - 1.223 В
 Канал внутреннего опорного напряжения показывает 1.219 - 1.223 В
-По каналу тока висит 4 мВ, мой 5-ти разрядный вольтметр показывал 3 мВ на 
+По каналу тока висит 4 мВ, мой 5-ти разрядный вольтметр показывал 3 мВ на
 выводе.
 выводе.
-По каналу напряжения постоянно висит 17-26-35 мВ, вольтметр показывет 
+По каналу напряжения постоянно висит 17-26-35 мВ, вольтметр показывет
 чёткий "0". Замыкание на землю ничего не даёт. Хз, что это такое.
 чёткий "0". Замыкание на землю ничего не даёт. Хз, что это такое.
-Если от итогового напряжения вычесть эти миливольты, то результат будет 
+Если от итогового напряжения вычесть эти миливольты, то результат будет
 больше похож на правду.
 больше похож на правду.
 
 
 На тему усреднения, такая идея:
 На тему усреднения, такая идея:
  - в прерывании ПДП данные перекладываются в быстрый кольцевой буфер
  - в прерывании ПДП данные перекладываются в быстрый кольцевой буфер
    на 10 значений. Можно мерять чаще, хоть каждую 1 мс.
    на 10 значений. Можно мерять чаще, хоть каждую 1 мс.
- - в основном теле каждые 100 мсек отрабатывает процедура, которая 
+ - в основном теле каждые 100 мсек отрабатывает процедура, которая
    усредняет данные из быстрого буфера, отбрасывая слишком мелкие/большие,
    усредняет данные из быстрого буфера, отбрасывая слишком мелкие/большие,
-   и перекладывает в медленный кольцевой буфер. Тут же делать пересчёты 
+   и перекладывает в медленный кольцевой буфер. Тут же делать пересчёты
    значений из кода АЦП в реальные значения.
    значений из кода АЦП в реальные значения.
- - ещё одна процедура раз в секунду усредняет данные из медленного буфера 
+ - ещё одна процедура раз в секунду усредняет данные из медленного буфера
    и сохраняем в текущий секундный результат. Здесь же вычеслять мощности,
    и сохраняем в текущий секундный результат. Здесь же вычеслять мощности,
    ёмкости, время и т.д.
    ёмкости, время и т.д.
 
 
@@ -154,11 +154,11 @@ Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E
 
 
 Причесал настройку Т2.
 Причесал настройку Т2.
 
 
-Считаем среднее, зануляем младшие 4 бита, и потом сравниваем каждое 
+Считаем среднее, зануляем младшие 4 бита, и потом сравниваем каждое
 значение со сброшенными 4-мя младшими битами:
 значение со сброшенными 4-мя младшими битами:
   middle &= 0xFFF0;
   middle &= 0xFFF0;
   if ((value & 0xFFF0) == middle) { ... }
   if ((value & 0xFFF0) == middle) { ... }
-таким образом отберём только те значения, которые отличаются от 
+таким образом отберём только те значения, которые отличаются от
 предварительного среднего не более чем на 1/16
 предварительного среднего не более чем на 1/16
 
 
 ---
 ---
@@ -166,8 +166,8 @@ Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E
 
 
 Период измерений 1.25 мсек, быстрый буфер - на 16 значений.
 Период измерений 1.25 мсек, быстрый буфер - на 16 значений.
 Фильтра нет, только усреднение.
 Фильтра нет, только усреднение.
-Понял, почему скачет опора -- при включеном светодиоде проседает 
-напряжение питания и завышаются показания. Что за хрень в канале напруги 
+Понял, почему скачет опора -- при включеном светодиоде проседает
+напряжение питания и завышаются показания. Что за хрень в канале напруги
 всё равно не понятно.
 всё равно не понятно.
 Нужно срочно увеличивать резисторы в цепи светодиодов.
 Нужно срочно увеличивать резисторы в цепи светодиодов.
 Без светодиодов канал внутренней опоры показывает 1.219 В.
 Без светодиодов канал внутренней опоры показывает 1.219 В.
@@ -177,25 +177,25 @@ Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E
 
 
 Начитался AN3137. Краткие выводы:
 Начитался AN3137. Краткие выводы:
  - конденсаторы по входу АЦП нужно поменять на 220 нФ,
  - конденсаторы по входу АЦП нужно поменять на 220 нФ,
- - период измерения сделать не менее 2 мсек по упрощ'нной формуле,
+ - период измерения сделать не менее 2 мсек по упрощённой формуле,
    или не менее 1,2 мсек по полной формуле,
    или не менее 1,2 мсек по полной формуле,
  - всё остальное -- отталкиваясь от этих данных.
  - всё остальное -- отталкиваясь от этих данных.
 
 
 Подробнее:
 Подробнее:
 
 
- 1. внешний конденсатор (правда в некоторых слачаях его не нужно ставить, 
+ 1. внешний конденсатор (правда в некоторых слачаях его не нужно ставить,
 только я не понял в каких) расчитывается по так:
 только я не понял в каких) расчитывается по так:
 	Cext ~= 1.58 * Csh * (Umax / Ulsb),
 	Cext ~= 1.58 * Csh * (Umax / Ulsb),
  где Csh -- внутрення ёмкость АЦП, 16 пФ,
  где Csh -- внутрення ёмкость АЦП, 16 пФ,
  Umax -- максимальное входное напряжение, принимается 4096,
  Umax -- максимальное входное напряжение, принимается 4096,
  Ulsb -- нужная точность, принимается 0.5 LSB.
  Ulsb -- нужная точность, принимается 0.5 LSB.
 Итого, Cext ~= 1.58 * 0.000000000016 * (4096 / 0.5) >= 207 nF.
 Итого, Cext ~= 1.58 * 0.000000000016 * (4096 / 0.5) >= 207 nF.
-Этот конденсатор должен держать входное напряжение, пока оно меряеться АЦП, 
+Этот конденсатор должен держать входное напряжение, пока оно меряеться АЦП,
 при этом он должен разрядиться не больше чем на Ulsb.
 при этом он должен разрядиться не больше чем на Ulsb.
 Интересно, а можно его использовать для оверсемплинга, расчитав на 1 LSB ?
 Интересно, а можно его использовать для оверсемплинга, расчитав на 1 LSB ?
 Конденсатор на 10 нФ успевает разрдится на 6-10 LSB.
 Конденсатор на 10 нФ успевает разрдится на 6-10 LSB.
 
 
- 2. Период времени между измерениями, за который должен успеть зарядиться 
+ 2. Период времени между измерениями, за который должен успеть зарядиться
 входной конденсатор, расчитывается так:
 входной конденсатор, расчитывается так:
 	tc = - (Rin * Csh) * ln(1 - (Csh/Cext) * (Umax/Ulsb))
 	tc = - (Rin * Csh) * ln(1 - (Csh/Cext) * (Umax/Ulsb))
 или, упрощённая формула tc ~= (Rin * Csh)
 или, упрощённая формула tc ~= (Rin * Csh)
@@ -203,3 +203,29 @@ Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E
  ln(1 - (Csh/Cext) * (Umax/Ulsb)) ~= 0.9058
  ln(1 - (Csh/Cext) * (Umax/Ulsb)) ~= 0.9058
 и в итоге, для канала вольтметра (как более высокоомного и медленного):
 и в итоге, для канала вольтметра (как более высокоомного и медленного):
 	tc = (Rin * Csh) * 0.9058 = 9090 * 0.000000000016 * 0.9058 ~= 1,2 мсек
 	tc = (Rin * Csh) * 0.9058 = 9090 * 0.000000000016 * 0.9058 ~= 1,2 мсек
+
+---
+2016.07.27
+
+Попытка "ADC2" провалилась -- там что-то не то в буфере от АЦП.
+Возвращаюсь на последнюю рабочую версию и пойду другим путём.
+
+План:
+ - меряем два канала (напряжение и ток) каждые 1,5625 мсек;
+ - DMA забирает данные, в прерывании перебрасываем два слова в первичный
+   циклический буфер на 64 значения (два буфера под напряжение и ток?)
+   в этом буфере сырые данные (код от ацп);
+ - раз в 100 мсек усредняем/обрабатываем эти 64 значения и складываем во
+   второй буфер на 10 значений;
+ - раз в секунду усредняем и считаем данные из воторого буфера.
+
+ Закончил.
+ Получился слегка затянутым -- "фронт" изменения показаний около 3-х секунд.
+ Шаг вольтметра в 1 мВ я получил, но смысла особого не вижу :-)
+ Без "оверсэмплинга" показания более сабильны.
+
+ Фильтрация по каналу тока -- её не заметно. хз куда смотреть.
+ В канале тока постоянно "висит" 3-4 мА, когда-то я считал,
+ это похоже на смещение "0" от ОУ. Хз, нужно ли вычитывать их из результата.
+
+ Этот этап можно считать законченым.

+ 117 - 15
lib/adc.c

@@ -6,6 +6,11 @@
   * @date    24-March-2016
   * @date    24-March-2016
   * @brief   This file contains the ADC functions.
   * @brief   This file contains the ADC functions.
   ******************************************************************************
   ******************************************************************************
+  * Tim2 регулярно запускат АЦП.
+  * АЦП измеряет два заданных канала и пинает DMA
+  * DMA забирает данные у ADC и складывает их в ADC_Buffer
+  * В прерывании по окончанию транзакции данные из ADC_Buffer
+  * раскладываем по FastBuffers.
   */
   */
 
 
 /* Includes ------------------------------------------------------------------*/
 /* Includes ------------------------------------------------------------------*/
@@ -17,21 +22,34 @@
 
 
 /* Private typedef -----------------------------------------------------------*/
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
+#define VOLTAGE_CHANNEL     ADC_Channel_17
+#define CURRENT_CHANNEL     ADC_Channel_18
+#define ADC1_DR_ADDRESS     ((uint16_t)0x5344)
+#define ADC_BUFFER_ADDRESS  ((uint16_t)(&ADC_Buffer))
+
+#define ADC_REF             3300
+#define ADC_DIV             4095
+#define ADC_ODIV            32768
+#define ADC_VOLT_K          11
+#define ADC_CURR_K          20
+
+// (Частота МК (16 МHz) / Предделитель таймера (8) * Нужное время в секундах (0.0015625)) - 1
+#define TIM_PERIOD          ((uint16_t)3128)
+#define TIM_PRESCALER       TIM2_Prescaler_8
+
 /* Private macro -------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-uint16_t ADC_Buffer[ADC_BUFFER_SIZE] = {0, 0, 0};
-
-uint16_t VoltageFastBuffer[FAST_BUFFER_SIZE];
-uint16_t CurrentFastBuffer[FAST_BUFFER_SIZE];
-uint16_t RefVoltFastBuffer[FAST_BUFFER_SIZE];
+static __IO uint16_t ADC_Buffer[ADC_BUFFER_SIZE];
+static __IO uint16_t VoltageFastBuffer[FAST_BUFFER_SIZE];
+static __IO uint16_t CurrentFastBuffer[FAST_BUFFER_SIZE];
 
 
 /* Private constants ---------------------------------------------------------*/
 /* Private constants ---------------------------------------------------------*/
 __near __no_init const unsigned char Factory_VREFINT @ 0x4910;
 __near __no_init const unsigned char Factory_VREFINT @ 0x4910;
 
 
 /* Private function prototypes -----------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
-static void ADC_Config(void);
-static void DMA_Config(void);
-static void TIM2_Config(void);
+static void ADC_ConfigADC(void);
+static void ADC_ConfigDMA(void);
+static void ADC_ConfigTIM2(void);
 
 
 /* Private functions ---------------------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
 
@@ -40,16 +58,16 @@ static void TIM2_Config(void);
   * @param  None
   * @param  None
   * @retval None
   * @retval None
   */
   */
-void Init_ADC(void)
+void ADC_Config(void)
 {
 {
     /* ADC configuration */
     /* ADC configuration */
-    ADC_Config();
+    ADC_ConfigADC();
 
 
     /* DMA configuration */
     /* DMA configuration */
-    DMA_Config();
+    ADC_ConfigDMA();
 
 
     /* TIM2 configuration */
     /* TIM2 configuration */
-    TIM2_Config();
+    ADC_ConfigTIM2();
 }
 }
 
 
 /**
 /**
@@ -57,7 +75,7 @@ void Init_ADC(void)
   * @param  None
   * @param  None
   * @retval None
   * @retval None
   */
   */
-static void ADC_Config(void)
+static void ADC_ConfigADC(void)
 {
 {
     /* Enable ADC1 clock */
     /* Enable ADC1 clock */
     CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
     CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
@@ -78,10 +96,12 @@ static void ADC_Config(void)
     ADC_ChannelCmd(ADC1, CURRENT_CHANNEL, ENABLE);
     ADC_ChannelCmd(ADC1, CURRENT_CHANNEL, ENABLE);
     ADC_SchmittTriggerConfig(ADC1, CURRENT_CHANNEL, DISABLE);
     ADC_SchmittTriggerConfig(ADC1, CURRENT_CHANNEL, DISABLE);
 
 
+#ifdef ADC_MEASURE_REF_VOLT
     /* ADC Voltage Reference */
     /* ADC Voltage Reference */
     ADC_VrefintCmd(ENABLE);
     ADC_VrefintCmd(ENABLE);
     /* Enable ADC1 Vrefint Channel */
     /* Enable ADC1 Vrefint Channel */
     ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, ENABLE);
     ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, ENABLE);
+#endif // ADC_MEASURE_REF_VOLT
 
 
     /* Enable ADC1 DMA requests*/
     /* Enable ADC1 DMA requests*/
     ADC_DMACmd(ADC1, ENABLE);
     ADC_DMACmd(ADC1, ENABLE);
@@ -95,7 +115,7 @@ static void ADC_Config(void)
   * @param  None
   * @param  None
   * @retval None
   * @retval None
   */
   */
-static void DMA_Config(void)
+static void ADC_ConfigDMA(void)
 {
 {
     /* Enable DMA1 clock */
     /* Enable DMA1 clock */
     CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);
     CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);
@@ -127,7 +147,7 @@ static void DMA_Config(void)
   * @param  None
   * @param  None
   * @retval None
   * @retval None
   */
   */
-static void TIM2_Config(void)
+static void ADC_ConfigTIM2(void)
 {
 {
     /* Enable TIM2 clock */
     /* Enable TIM2 clock */
     CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
     CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
@@ -145,6 +165,88 @@ static void TIM2_Config(void)
     TIM2_Cmd(ENABLE);
     TIM2_Cmd(ENABLE);
 }
 }
 
 
+/**
+  * @brief DMA1 channel0 and channel1 Interrupt routine.
+  * @param  None
+  * @retval None
+  */
+INTERRUPT_HANDLER(DMA1_CHANNEL0_1_IRQHandler,2)
+{
+    static uint8_t idx = 0;
+
+    VoltageFastBuffer[idx] = ADC_Buffer[0];
+    CurrentFastBuffer[idx] = ADC_Buffer[1];
+
+    idx ++;
+    if(idx >= FAST_BUFFER_SIZE) {
+        idx = 0;
+    }
+
+    /* Clear IT Pending Bit */
+    DMA1_Channel0->CSPR &= (uint8_t)~(uint8_t)(DMA1_IT_TC0 & (uint8_t)0x06);
+}
+
+/**
+  * @brief  Return average values from fast buffers
+  * @param  None
+  * @retval Latest_Voltage
+  */
+uint16_t * ADC_GetValues(void) {
+  static uint16_t avgVal[ADC_BUFFER_SIZE];
+  uint32_t volt=0, curr=0;
+  uint16_t middle, shunt_volt;
+  uint8_t i;
+
+  /* Summarize buffers values */
+  for(i=0;i<FAST_BUFFER_SIZE;i++){
+    volt += VoltageFastBuffer[i];
+    curr += CurrentFastBuffer[i];
+  }
+
+  /* Попытка оверсемплинга, чтобы сделать шаг ~1мВ
+     делим на 8, умножаем на опорное напряжение, умножаем на входной делитель
+     и делим на (12 бит АЦП * 8). */
+
+  volt >>= 3;
+  volt *= ADC_REF;
+  volt *= ADC_VOLT_K;
+  volt /= ADC_ODIV;
+
+  /* получаем среднее по току, затем фильтруем */
+  curr >>= 6;
+  middle = curr + 8;
+  middle &= 0xFFF0;
+  curr = 0;
+  uint8_t cnt = 0;
+  uint16_t tmp;
+   for(i=1; i<FAST_BUFFER_SIZE; i+=2){
+    tmp = CurrentFastBuffer[i];
+    tmp += 8;
+    tmp &= 0xFFF0;
+    if(tmp == middle){
+      cnt ++;
+      curr += CurrentFastBuffer[i];
+    }
+   }
+
+  /* Усредняем преобразованный результат
+     и переводим код АЦП в милиамперы */
+  if(cnt > 0){
+    curr /= cnt;
+  } else {
+    curr = middle;
+  }
+  curr *= ADC_REF;
+  curr /= ADC_DIV;
+
+  shunt_volt = curr / ADC_CURR_K;
+  volt -= shunt_volt;
+
+  avgVal[0] = (uint16_t)volt;
+  avgVal[1] = (uint16_t)curr;
+
+  return avgVal;
+}
 
 
 /**
 /**
   * @}
   * @}

+ 10 - 16
lib/adc.h

@@ -18,25 +18,19 @@
 
 
 /* Exported types ------------------------------------------------------------*/
 /* Exported types ------------------------------------------------------------*/
 /* Exported defines ----------------------------------------------------------*/
 /* Exported defines ----------------------------------------------------------*/
-#define VOLTAGE_CHANNEL     ADC_Channel_17
-#define CURRENT_CHANNEL     ADC_Channel_18
-#define ADC1_DR_ADDRESS     ((uint16_t)0x5344)
-#define ADC_BUFFER_SIZE     ((uint8_t) 3)
-#define ADC_BUFFER_ADDRESS  ((uint16_t)(&ADC_Buffer))
-
-#define FAST_BUFFER_SIZE    ((uint8_t) 16)
-/* ADC_RATIO = (( 3.3 * 1000 * 1000 ) + 2048 ) / 4095 */
-#define ADC_RATIO       806UL
-#define ADC_VOLT_RATIO  8864UL
-
-// (×àñòîòà ÌÊ (16 ÌHz) / Ïðåääåëèòåëü òàéìåðà (32) * Íóæíîå âðåìÿ â ñåêóíäàõ (0.00125)) - 1
-#define TIM_PERIOD          ((uint16_t)624)
-#define TIM_PRESCALER       TIM2_Prescaler_32
-
 /* Exported constants --------------------------------------------------------*/
 /* Exported constants --------------------------------------------------------*/
+#define ADC_BUFFER_SIZE     ((uint8_t)2)
+#define FAST_BUFFER_SIZE    ((uint8_t)64)
+
 /* Exported macro ------------------------------------------------------------*/
 /* Exported macro ------------------------------------------------------------*/
+/* Exported variables --------------------------------------------------------*/
+extern __IO uint16_t ADC_Buffer[];
+extern __IO uint16_t VoltageFastBuffer[];
+extern __IO uint16_t CurrentFastBuffer[];
+
 /* Exported functions ------------------------------------------------------- */
 /* Exported functions ------------------------------------------------------- */
-void Init_ADC(void);
+void ADC_Config(void);
+uint16_t * ADC_GetValues(void);
 
 
 #endif /* __ADC_H */
 #endif /* __ADC_H */
 
 

+ 5 - 5
lib/max7219.c

@@ -18,7 +18,7 @@
 #define SPI_MOSI        GPIO_Pin_6
 #define SPI_MOSI        GPIO_Pin_6
 #define SPI_PINS        (SPI_SCK|SPI_MOSI)
 #define SPI_PINS        (SPI_SCK|SPI_MOSI)
 
 
-void MAX7219_Init(void) {
+void MAX7219_Config(void) {
     SPI_DeInit(SPI1);
     SPI_DeInit(SPI1);
     /* Enable clock for SPI */
     /* Enable clock for SPI */
     CLK_PeripheralClockConfig(CLK_Peripheral_SPI1, ENABLE);
     CLK_PeripheralClockConfig(CLK_Peripheral_SPI1, ENABLE);
@@ -34,10 +34,10 @@ void MAX7219_Init(void) {
     SPI_Cmd(SPI1, ENABLE);
     SPI_Cmd(SPI1, ENABLE);
 
 
     /* Настройка MAX71219 */
     /* Настройка MAX71219 */
-	MAX7219_WriteData(DecodeMode, 0x00);            // все без BCD декодирования
-	MAX7219_WriteData(ScanLimit, MAX7219_DIGITS);   // сколько цифр используем
-	MAX7219_WriteData(Intensity, MAX7219_BRIGHT);   // яркость из 16
-	MAX7219_WriteData(Power, MAX7219_ON);           // включили питание
+	MAX7219_WriteData(RegDecodeMode, 0x00);            // все без BCD декодирования
+	MAX7219_WriteData(RegScanLimit, MAX7219_DIGITS);   // сколько цифр используем
+	MAX7219_WriteData(RegIntensity, MAX7219_BRIGHT);   // яркость из 16
+	MAX7219_WriteData(RegPower, MAX7219_ON);           // включили питание
 
 
 }
 }
 
 

+ 19 - 19
lib/max7219.h

@@ -27,7 +27,7 @@
 #define SEG_E			6
 #define SEG_E			6
 #define SEG_F			0
 #define SEG_F			0
 #define SEG_G			7
 #define SEG_G			7
-#define SEG_DP			4
+#define SEG_DP		4
 
 
 // symbols
 // symbols
 // Для BCD
 // Для BCD
@@ -69,24 +69,24 @@
 #define MAX7219_DIGITS  7
 #define MAX7219_DIGITS  7
 
 
 /* Exported types ------------------------------------------------------------*/
 /* Exported types ------------------------------------------------------------*/
-typedef enum {
-    NoOp        = 0x00,
-    Digit0      = 0x03,
-    Digit1      = 0x08,
-    Digit2      = 0x02,
-    Digit3      = 0x01,
-    Digit4      = 0x07,
-    Digit5      = 0x04,
-    Digit6      = 0x06,
-    Digit7      = 0x05,
-    DecodeMode  = 0x09,
-    Intensity   = 0x0A,
-    ScanLimit   = 0x0B,
-    Power       = 0x0C,
-    Test        = 0x0F
+typedef enum _max7219_reg {
+    RegNoOp        = 0x00,
+    RegDigit0      = 0x03,
+    RegDigit1      = 0x08,
+    RegDigit2      = 0x02,
+    RegDigit3      = 0x01,
+    RegDigit4      = 0x07,
+    RegDigit5      = 0x04,
+    RegDigit6      = 0x06,
+    RegDigit7      = 0x05,
+    RegDecodeMode  = 0x09,
+    RegIntensity   = 0x0A,
+    RegScanLimit   = 0x0B,
+    RegPower       = 0x0C,
+    RegTest        = 0x0F
 } max7219_reg_t;
 } max7219_reg_t;
 
 
-typedef enum {
+typedef enum _max7219_seg {
     SegA    = SEG_A,
     SegA    = SEG_A,
     SegB    = SEG_B,
     SegB    = SEG_B,
     SegC    = SEG_C,
     SegC    = SEG_C,
@@ -97,7 +97,7 @@ typedef enum {
     SegDP   = SEG_DP,
     SegDP   = SEG_DP,
 } max7219_seg_t;
 } max7219_seg_t;
 
 
-typedef enum {
+typedef enum _max7219_sym {
     Sym_0        = SYM_0,
     Sym_0        = SYM_0,
     Sym_1        = SYM_1,
     Sym_1        = SYM_1,
     Sym_2        = SYM_2,
     Sym_2        = SYM_2,
@@ -130,7 +130,7 @@ typedef enum {
 /* Exported macro ------------------------------------------------------------*/
 /* Exported macro ------------------------------------------------------------*/
 /* Exported variables --------------------------------------------------------*/
 /* Exported variables --------------------------------------------------------*/
 /* Exported functions --------------------------------------------------------*/
 /* Exported functions --------------------------------------------------------*/
-void MAX7219_Init(void);
+void MAX7219_Config(void);
 void MAX7219_WriteData(max7219_reg_t reg, uint8_t data);
 void MAX7219_WriteData(max7219_reg_t reg, uint8_t data);
 
 
 #endif /* __MAX7219_H */
 #endif /* __MAX7219_H */

+ 1 - 1
lib/rtos.c

@@ -15,7 +15,7 @@ static __IO uint16_t TimingDelay;
 /******************************************************************************************
 /******************************************************************************************
  * Èíèöèàëèçàöèÿ ÐÒÎÑ, âðåìÿ òèêà - 1 ìñ
  * Èíèöèàëèçàöèÿ ÐÒÎÑ, âðåìÿ òèêà - 1 ìñ
  */
  */
-inline void RTOS_Init()
+inline void RTOS_Config()
 {
 {
   /*
   /*
   TIM4 configuration:
   TIM4 configuration:

+ 1 - 1
lib/rtos.h

@@ -50,7 +50,7 @@ typedef struct task
 /******************************************************************************************
 /******************************************************************************************
  * Ïðîòîòèïû ôóêíöèé
  * Ïðîòîòèïû ôóêíöèé
  */
  */
-void RTOS_Init (void);
+void RTOS_Config (void);
 void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod);
 void RTOS_SetTask (void (*taskFunc)(void), uint16_t taskDelay, uint16_t taskPeriod);
 void RTOS_DeleteTask (void (*taskFunc)(void));
 void RTOS_DeleteTask (void (*taskFunc)(void));
 void RTOS_DispatchTask (void);
 void RTOS_DispatchTask (void);

+ 140 - 115
src/main.c

@@ -35,6 +35,8 @@
 #define LED_GREEN_PORT  GPIOB
 #define LED_GREEN_PORT  GPIOB
 #define LED_GREEN_PIN   GPIO_Pin_7
 #define LED_GREEN_PIN   GPIO_Pin_7
 
 
+#define VALUES_BUFFER_SIZE  10
+
 /* Private macro -------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 #define LED_RED_ON      LED_RED_PORT->ODR &= (uint8_t)(~LED_RED_PIN)
 #define LED_RED_ON      LED_RED_PORT->ODR &= (uint8_t)(~LED_RED_PIN)
 #define LED_RED_OFF     LED_RED_PORT->ODR |= LED_RED_PIN
 #define LED_RED_OFF     LED_RED_PORT->ODR |= LED_RED_PIN
@@ -44,54 +46,36 @@
 /* Private constant ----------------------------------------------------------*/
 /* Private constant ----------------------------------------------------------*/
 // перевод числа 0-7 в номер индикатора
 // перевод числа 0-7 в номер индикатора
 static const max7219_reg_t dig[8] = {
 static const max7219_reg_t dig[8] = {
-	Digit0,
-	Digit1,
-	Digit2,
-	Digit3,
-	Digit4,
-	Digit5,
-	Digit6,
-	Digit7
+	RegDigit0, RegDigit1, RegDigit2, RegDigit3,
+	RegDigit4, RegDigit5, RegDigit6, RegDigit7
 };
 };
 
 
 // перевод значения 0x00 - 0x0F в код индикатора
 // перевод значения 0x00 - 0x0F в код индикатора
 static const max7219_sym_t num[16] = {
 static const max7219_sym_t num[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
+	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
 };
 };
 
 
 /* Private variables ---------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-uint16_t Voltage = 0;
-uint16_t Current = 0;
-uint16_t RefVolt = 0;
+static uint16_t bufVoltage[VALUES_BUFFER_SIZE];
+static uint16_t bufCurrent[VALUES_BUFFER_SIZE];
 
 
-extern uint16_t VoltageFastBuffer[];
-extern uint16_t CurrentFastBuffer[];
-extern uint16_t RefVoltFastBuffer[];
+/* averaged values for 1 sek */
+static uint16_t Voltage;
+static uint16_t Current;
+static uint32_t Power;
+static uint32_t CapacityAH = 0;
+static uint32_t CapacityWH = 0;
 
 
 /* Private function prototypes -----------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 static void GPIO_Config(void);
 static void GPIO_Config(void);
 static void CLK_Config(void);
 static void CLK_Config(void);
 
 
 /* RTOS function prototypes -----------------------------------------------*/
 /* RTOS function prototypes -----------------------------------------------*/
-static void ShowTopLineV(void);
-static void ShowTopLineC(void);
-static void ShowBotLine(void);
-static void ProcessFastBuffer(void);
+static void getADCValues(void);
+static void calculateValues(void);
+static void showTopLineU(void);
+static void showBotLineI(void);
 
 
 /* Private functions ---------------------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 
 
@@ -109,115 +93,156 @@ void main(void)
   GPIO_Config();
   GPIO_Config();
 
 
   /* RTOS Configuration */
   /* RTOS Configuration */
-  RTOS_Init();
+  RTOS_Config();
 
 
    /* ADC Configuration and start */
    /* ADC Configuration and start */
-  Init_ADC();
+  ADC_Config();
 
 
   /* MAX7219 Configuration */
   /* MAX7219 Configuration */
-  MAX7219_Init();
+  MAX7219_Config();
 
 
   /* ROTS tasks */
   /* ROTS tasks */
-  RTOS_SetTask(ProcessFastBuffer,0,100);
-  RTOS_SetTask(ShowTopLineV,101,4000);
-  RTOS_SetTask(ShowTopLineC,2101,4000);
-  RTOS_SetTask(ShowBotLine,101,100);
+  RTOS_SetTask(getADCValues,100,100);
+  RTOS_SetTask(calculateValues,101,1000);
+  RTOS_SetTask(showTopLineU,102,250);
+  RTOS_SetTask(showBotLineI,103,250);
 
 
   /* Infinite loop */
   /* Infinite loop */
-  while (1)
-  {
+  while (1) {
       RTOS_DispatchTask();
       RTOS_DispatchTask();
-      Delay(1);
+      wfi();
   }
   }
 }
 }
 
 
-/*
- * Фильтрация и усреднение данных из быстрого буфера,
- * вычесление значений, перенос в медленный буфер.
- */
-static void ProcessFastBuffer(void){
-    uint16_t volt=0, curr=0, ref=0;
-
-    /* Summarize buffers values */
-    uint8_t i;
-    for(i=0;i<FAST_BUFFER_SIZE;i++){
-        volt += VoltageFastBuffer[i];
-        curr += CurrentFastBuffer[i];
-        ref += RefVoltFastBuffer[i];
-    }
-
-    /* Calculate voltage value*/
-    Voltage = ((volt / FAST_BUFFER_SIZE) * ADC_VOLT_RATIO) / 1000;
-
-    /* Calculate current value*/
-    Current = ((curr / FAST_BUFFER_SIZE) * ADC_RATIO) / 1000;
-
-    /* Calculate reference voltage value*/
-    RefVolt = ((ref / FAST_BUFFER_SIZE) * ADC_RATIO) / 1000;
+/**
+  * Забираем обработанные данные из быстрого буфера
+  * и складываем в медленный.
+  */
+static void getADCValues(void) {
+  static uint8_t idxVal=0;
+  uint16_t * avgVal;
+
+  avgVal = ADC_GetValues();
+
+  bufVoltage[idxVal] = *avgVal;
+  bufCurrent[idxVal] = *(avgVal + 1);
+
+  idxVal ++;
+  if (idxVal == VALUES_BUFFER_SIZE) {
+    idxVal = 0;
+  }
 }
 }
 
 
-/*
- * Output to top indicator line
- */
-static void ShowTopLineV(void){
-    uint8_t voltage1000 = 0;
-    uint8_t voltage100 = 0;
-    uint8_t voltage10 = 0;
-    uint8_t voltage1 = 0;
+/**
+  * Average values from slow buffer.
+  * Calculate Power, Capacitance IH and WH.
+  */
+static void calculateValues(void) {
+  uint8_t i;
+  uint16_t c=0;
+  uint32_t v=0;
+
+  for (i=0; i<VALUES_BUFFER_SIZE; i++) {
+    v += bufVoltage[i];
+    c += bufCurrent[i];
+  }
 
 
-    /* Thousands voltage value*/
-    voltage1000 = (uint8_t)(Voltage / 1000);
-    /* Hundreds voltage value */
-    voltage100 = (uint8_t)((Voltage % 1000) / 100);
-    /* Tens voltage value */
-    voltage10 = (uint8_t)((Voltage % 100 ) / 10);
-    /* Ones voltage value */
-    voltage1 = (uint8_t)(Voltage % 10);
+  Current = (c + (VALUES_BUFFER_SIZE/2)) / VALUES_BUFFER_SIZE;
+  Voltage = (v + (VALUES_BUFFER_SIZE/2)) / VALUES_BUFFER_SIZE;
 
 
-    LED_RED_ON;
+  Power = ((Voltage * Current) + 500) / 1000;
 
 
-    MAX7219_WriteData(dig[0], num[voltage1000]);
-    MAX7219_WriteData(dig[1], num[voltage100]);
-    MAX7219_WriteData(dig[2], num[voltage10]);
-    MAX7219_WriteData(dig[3], num[voltage1]);
+  CapacityAH += Current;
+  CapacityWH += Power;
 }
 }
 
 
-static void ShowTopLineC(void){
-    LED_RED_OFF;
-    uint8_t tmp = Current / 1000;
+/**
+  * Output voltage values to top indicator
+  */
+static void showTopLineU(void) {
+  uint32_t vlt = 0;
+  uint8_t tmp;
+
+  for (tmp=0; tmp<VALUES_BUFFER_SIZE; tmp++) {
+    vlt += bufVoltage[tmp];
+  }
+  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]);
     MAX7219_WriteData(dig[0], num[tmp]);
-    tmp = (Current % 1000) / 100;
-    MAX7219_WriteData(dig[1], num[tmp]);
-    tmp = (Current % 100) / 10;
+    /* 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]);
     MAX7219_WriteData(dig[2], num[tmp]);
-    tmp = Current % 10;
+    /* Tens voltage value */
+    tmp = (uint8_t)(vlt / 10);
     MAX7219_WriteData(dig[3], num[tmp]);
     MAX7219_WriteData(dig[3], num[tmp]);
-}
-
-/*
- * Output to bottom indicator line
- */
-static void ShowBotLine(void){
-    uint8_t voltage1000 = 0;
-    uint8_t voltage100 = 0;
-    uint8_t voltage10 = 0;
-    uint8_t voltage1 = 0;
-
+  } else {
     /* Thousands voltage value*/
     /* Thousands voltage value*/
-    voltage1000 = (uint8_t)(RefVolt / 1000);
+    tmp = (uint8_t)(vlt / 1000);
+    vlt %= 1000;
+    MAX7219_WriteData(dig[0], (num[tmp] | SYM_DOT));
     /* Hundreds voltage value */
     /* Hundreds voltage value */
-    voltage100 = (uint8_t)((RefVolt % 1000) / 100);
+    tmp = (uint8_t)(vlt / 100);
+    vlt %= 100;
+    MAX7219_WriteData(dig[1], num[tmp]);
     /* Tens voltage value */
     /* Tens voltage value */
-    voltage10 = (uint8_t)((RefVolt % 100 ) / 10);
+    tmp = (uint8_t)(vlt / 10);
+    vlt %= 10;
+    MAX7219_WriteData(dig[2], num[tmp]);
     /* Ones voltage value */
     /* Ones voltage value */
-    voltage1 = (uint8_t)(RefVolt % 10);
-
-    MAX7219_WriteData(dig[4], num[voltage1000]);
-    MAX7219_WriteData(dig[5], num[voltage100]);
-    MAX7219_WriteData(dig[6], num[voltage10]);
-    MAX7219_WriteData(dig[7], num[voltage1]);
+    MAX7219_WriteData(dig[3], num[(uint8_t)vlt]);
+  }
 }
 }
 
 
+/**
+  * Output current values to bottom indicator
+  */
+static void showBotLineI(void){
+//  LED_RED_OFF; // индикация режима
+  uint16_t crnt = 0;
+  uint8_t tmp;
+
+  for (tmp=0; tmp<VALUES_BUFFER_SIZE; tmp++) {
+    crnt += bufCurrent[tmp];
+  }
+  crnt /= VALUES_BUFFER_SIZE;
+
+  if (crnt >= 1000) {
+    tmp = crnt / 1000;
+    crnt %= 1000;
+  } else {
+    tmp = 0;
+  }
+  MAX7219_WriteData(dig[4], (num[tmp] | SYM_DOT));
+
+  if (crnt >= 100) {
+    tmp = crnt / 100;
+    crnt %= 100;
+  } else {
+    tmp = 0;
+  }
+  MAX7219_WriteData(dig[5], num[tmp]);
+
+  if (crnt >= 10) {
+    tmp = crnt / 10;
+    crnt %= 10;
+  } else {
+    tmp = 0;
+  }
+  MAX7219_WriteData(dig[6], num[tmp]);
+
+  MAX7219_WriteData(dig[7], num[crnt]);
+}
 
 
 /**
 /**
   * @brief  Configure GPIO for button available on the VAPC board
   * @brief  Configure GPIO for button available on the VAPC board

+ 2 - 19
src/stm8l15x_it.c

@@ -28,7 +28,6 @@
 
 
 /* Includes ------------------------------------------------------------------*/
 /* Includes ------------------------------------------------------------------*/
 #include "stm8l15x_it.h"
 #include "stm8l15x_it.h"
-#include "adc.h"
 
 
 /** @addtogroup STM8L15x_StdPeriph_Template
 /** @addtogroup STM8L15x_StdPeriph_Template
   * @{
   * @{
@@ -38,11 +37,6 @@
 /* Private define ------------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-extern uint16_t VoltageFastBuffer[];
-extern uint16_t CurrentFastBuffer[];
-extern uint16_t RefVoltFastBuffer[];
-extern uint16_t ADC_Buffer[];
-
 /* Private function prototypes -----------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 /* Public functions ----------------------------------------------------------*/
 /* Public functions ----------------------------------------------------------*/
@@ -92,22 +86,11 @@ INTERRUPT_HANDLER(FLASH_IRQHandler,1)
   * @param  None
   * @param  None
   * @retval None
   * @retval None
   */
   */
+/*
 INTERRUPT_HANDLER(DMA1_CHANNEL0_1_IRQHandler,2)
 INTERRUPT_HANDLER(DMA1_CHANNEL0_1_IRQHandler,2)
 {
 {
-    static uint8_t i = 0;
-
-    VoltageFastBuffer[i] = ADC_Buffer[0];
-    CurrentFastBuffer[i] = ADC_Buffer[1];
-    RefVoltFastBuffer[i] = ADC_Buffer[2];
-
-    i ++;
-    if(i >= FAST_BUFFER_SIZE) {
-        i = 0;
-    }
-
-    /* Clear IT Pending Bit */
-    DMA1_Channel0->CSPR &= (uint8_t)~(uint8_t)(DMA1_IT_TC0 & (uint8_t)0x06);
 }
 }
+*/
 /**
 /**
   * @brief DMA1 channel2 and channel3 Interrupt routine.
   * @brief DMA1 channel2 and channel3 Interrupt routine.
   * @param  None
   * @param  None