Selaa lähdekoodia

Скорректировал вычисления под новые условия (Imax 6.6A, shunt R05).

Vladimir N. Shilov 8 vuotta sitten
vanhempi
commit
af871e04ca
2 muutettua tiedostoa jossa 35 lisäystä ja 22 poistoa
  1. 33 20
      lib/adc.c
  2. 2 2
      src/main.c

+ 33 - 20
lib/adc.c

@@ -27,16 +27,20 @@
 #define ADC1_DR_ADDRESS     ((uint16_t)0x5344)
 #define ADC_BUFFER_ADDRESS  ((uint16_t)(&ADC_Buffer))
 
-#define ADC_REF             3300
-// 4095 * 20 (Ку ОУ) * 0.01 (Rш)
-#define ADC_DIV             819
-// 32760 * 20 (Ку ОУ) * 0.01 (Rш)
-#define ADC_ODIV            6552
-#define ADC_DIV_H           410
-#define ADC_ODIV_H          3276
+// Uvcc
+#define ADC_REF             3307
+// 4095 * 10 (Ку ОУ) * 0.05 (Rш)
+#define ADC_DIV             2048
+#define ADC_DIV_H           1024
+// 32760 * 10 (Ку ОУ) * 0.05 (Rш)
+#define ADC_ODIV            16380
+#define ADC_ODIV_H          8190
+// for shunt voltage calcuation
+#define ADC_ORES            32760
+#define ADC_OU_MUL          10
+#define ADC_OU_ZERO_DRIFT   41
+// voltage divider
 #define ADC_VOLT_K          11
-#define ADC_CURR_K          20
-#define ADC_CURR_SH         100
 
 // (Частота МК (16 МHz) / Предделитель таймера (8) * Нужное время в секундах (0.0015625)) - 1
 #define TIM_PERIOD          ((uint16_t)3128)
@@ -216,8 +220,7 @@ INTERRUPT_HANDLER(DMA1_CHANNEL0_1_IRQHandler,2)
   */
 uint16_t * ADC_GetValues(void) {
   static uint16_t avgVal[ADC_BUFFER_SIZE];
-  uint32_t volt=0, curr=0;
-  uint16_t shunt_volt;
+  uint32_t volt=0, curr=0, shunt_volt=0;
   uint8_t i;
 
   /* Summarize buffers values */
@@ -238,15 +241,25 @@ uint16_t * ADC_GetValues(void) {
 
   curr += 4;
   curr /= 8;
-  curr *= ADC_REF;
-  curr += ADC_ODIV_H; // для округления
-  curr /= ADC_ODIV; // делим на К
-
-  /* так как шунт стоит в разрыве земли до выхода из БП
-     компенсируем падение напряжения на нём. */
-  shunt_volt = curr + (ADC_CURR_K/2);
-  shunt_volt /= ADC_CURR_K; // мВ на входе ОУ
-  volt -= shunt_volt; // получили напряжение на клемах
+  // компенсация смещения нуля ОУ
+  if (curr > ADC_OU_ZERO_DRIFT) {
+    curr -= ADC_OU_ZERO_DRIFT;
+
+    curr *= ADC_REF;
+    shunt_volt = curr;
+    curr += ADC_ODIV_H; // для округления
+    curr /= ADC_ODIV; // делим на К -- на выходе ток в мА
+
+    /* так как шунт стоит в разрыве земли до выхода из БП
+       компенсируем падение напряжения на нём. */
+    shunt_volt += (ADC_OU_MUL/2);
+    shunt_volt /= ADC_OU_MUL;
+    shunt_volt += (ADC_ORES/2);
+    shunt_volt /= ADC_ORES; // мВ на входе ОУ
+    volt -= shunt_volt; // получили напряжение на клемах
+  } else {
+    curr = 0;
+  }
 
   avgVal[0] = (uint16_t)volt;
   avgVal[1] = (uint16_t)curr;

+ 2 - 2
src/main.c

@@ -213,7 +213,7 @@ static void getADCValues(void) {
 
 /**
   * Average values from slow buffer.
-  * Calculate Power, Capacitance IH and WH.
+  * Calculate Power, Capacitance AH and WH.
   */
 static void calculateValues(void) {
   uint8_t i;
@@ -228,7 +228,7 @@ static void calculateValues(void) {
   Current = (c + (VALUES_BUFFER_SIZE/2)) / VALUES_BUFFER_SIZE;
   Voltage = (v + (VALUES_BUFFER_SIZE/2)) / VALUES_BUFFER_SIZE;
 
-  if (Current > 4) {
+  if (Current > 0) {
 
     Power = ((Voltage * Current) + 500) / 1000;