Prechádzať zdrojové kódy

Merge branch 'master' of shilov.pp.ua:chac-meter

Vladimir N. Shilov 8 rokov pred
rodič
commit
657774653f
6 zmenil súbory, kde vykonal 189 pridanie a 57 odobranie
  1. 1 8
      ChACM.cbp
  2. 12 12
      Makefile
  3. 14 1
      ReadMe.txt
  4. BIN
      hw/china_ampermetr_10a.dch
  5. 154 28
      src/main.c
  6. 8 8
      src/stm8s_it.c

+ 1 - 8
ChACM.cbp

@@ -6,7 +6,7 @@
 		<Option makefile_is_custom="1" />
 		<Option pch_mode="2" />
 		<Option compiler="null" />
-		<Option virtualFolders="RTOS\;SPL\;SPL\src\;SPL\inc\;" />
+		<Option virtualFolders="SPL\;SPL\src\;SPL\inc\;" />
 		<Build>
 			<Target title="Release">
 				<Option output="bin/Release/ChACM" prefix_auto="1" extension_auto="1" />
@@ -197,13 +197,6 @@
 		</Unit>
 		<Unit filename="inc/stm8s_conf.h" />
 		<Unit filename="inc/stm8s_it.h" />
-		<Unit filename="lib/rtos.c">
-			<Option compilerVar="CC" />
-			<Option virtualFolder="RTOS/" />
-		</Unit>
-		<Unit filename="lib/rtos.h">
-			<Option virtualFolder="RTOS/" />
-		</Unit>
 		<Unit filename="src/main.c">
 			<Option compilerVar="CC" />
 		</Unit>

+ 12 - 12
Makefile

@@ -16,25 +16,25 @@ FLASHTOOL=C:/STMicroelectronics/st_toolset/stvp/STVP_CmdLine.exe
 FLASHOPT=-Device=STM8S003x6
 
 DEFINES = -D USE_STDPERIPH_DRIVER
-DEFINES += -D USE_RTOS
 DEFINES += -D STM8S003
+#DEFINES += -D USE_RTOS
 
 # Sources paths
 APP_SRC = src
 LIB_SRC = lib
 
 vpath %.c $(APP_SRC)
-vpath %.c $(LIB_SRC)
+#vpath %.c $(LIB_SRC)
 vpath %.c StdPerphDrv/src
 
 # Include paths
 INCLUDES = -I inc
-INCLUDES += -I lib
+#INCLUDES += -I lib
 INCLUDES += -I StdPerphDrv/inc
 
 
 # CPU part number
-PART=STM8S003
+PART=stm8s003f3
 ICF=lnkstm8s003f3.icf
 LIB_MODEL = dlstm8ssn.h
 
@@ -50,7 +50,7 @@ DATA_MODEL = small
 # Application object files
 APP_OBJECTS = main.o
 APP_OBJECTS += stm8s_it.o
-APP_OBJECTS += rtos.o
+#APP_OBJECTS += rtos.o
 #APP_ASM_OBJECTS = atomport-asm-iar.o
 
 # STM8S Peripheral driver object files
@@ -59,7 +59,7 @@ PERIPH_OBJECTS = stm8s_adc1.o
 #PERIPH_OBJECTS += stm8s_beep.o
 PERIPH_OBJECTS += stm8s_clk.o
 PERIPH_OBJECTS += stm8s_exti.o
-#PERIPH_OBJECTS += stm8s_flash.o
+PERIPH_OBJECTS += stm8s_flash.o
 PERIPH_OBJECTS += stm8s_gpio.o
 #PERIPH_OBJECTS += stm8s_i2c.o
 PERIPH_OBJECTS += stm8s_itc.o
@@ -87,17 +87,16 @@ vpath %.elf .\$(OUT_DIR)
 vpath %.hex .\$(OUT_DIR)
 
 # Compiler/Assembler flags
-CFLAGS = -e -Oh $(DEFINES)
+CFLAGS = -e -Ohs $(DEFINES) -D NDEBUG
 CFLAGS += --code_model $(CODE_MODEL) --data_model $(DATA_MODEL)
 CFLAGS += --dlib_config "$(EWSTM8_DIR)\lib\$(LIB_MODEL)"
-CFLAGS += -D NDEBUG -D $(PART)
 CFLAGS += -lCN $(LIST_DIR) -lBN $(LIST_DIR)
-CFLAGS += --diag_suppress Pa050
+CFLAGS += --diag_suppress Pa050 --guard_calls --silent
 
 DBG_CFLAGS = -e -Ol $(DEFINES) --no_cse --no_unroll --no_inline --no_code_motion --no_tbaa
 DBG_CFLAGS += --no_cross_call --debug --code_model $(CODE_MODEL) --data_model $(DATA_MODEL)
-DBG_CFLAGS += --dlib_config "$(EWSTM8_DIR)\lib\$(LIB_MODEL)" -D $(PART)
-DBG_CFLAGS += -lC $(LIST_DIR) -lB $(LIST_DIR)
+DBG_CFLAGS += --dlib_config "$(EWSTM8_DIR)\lib\$(LIB_MODEL)"
+DBG_CFLAGS += -lC $(LIST_DIR) -lB $(LIST_DIR) 
 DBG_CFLAGS += --diag_suppress Pa050
 
 ASMFLAGS = -M'<>' -ld $(OUT_DIR)\list --diag_suppress Pa050
@@ -108,7 +107,7 @@ DBG_ASMFLAGS += --code_model $(CODE_MODEL) --data_model $(DATA_MODEL)
 
 LINKFLAGS = --redirect _Printf=_PrintfTinyNoMb
 LINKFLAGS += --redirect _Scanf=_ScanfSmallNoMb
-LINKFLAGS += --config "$(EWSTM8_DIR)\config\$(ICF)"
+LINKFLAGS += --config "$(EWSTM8_DIR)\config\lnk$(PART).icf"
 LINKFLAGS += --config_def _CSTACK_SIZE=0x100
 LINKFLAGS += --config_def _HEAP_SIZE=0x100
 LINKFLAGS += --map $(OUT_DIR)
@@ -130,6 +129,7 @@ DBG_LINKFLAGS += --entry __iar_program_start
 all: $(OUT_DIR) $(PROJ_S19S) $(PROJ_IHEX)
 Release: all
 flash: all
+cleanRelease: clean
 
 # Make build/output directory
 $(OUT_DIR):

+ 14 - 1
ReadMe.txt

@@ -106,7 +106,20 @@ Vin	    Vout	    R1	    R2	    Error
 2016.11.12
 
 Смотрю на программу и хочу выкинуть "ртос".
-1-ый таймер остаётся пинать АЦП, 4-ый будет каждые 5 мсек переключать 
+1-ый таймер остаётся пинать АЦП, 4-ый будет каждые 5 мсек переключать
 индикаторы, а 2-ой каждый 200 мсек будет обновлять инфу для выхода.
 Обработчик кнопки или паузы прилепить тоже на 4-ый.
 Хотя 2-ой тут и не нужен...
+
+---
+2016.11.14
+
+RTOS выкинул. на очереди SPL? :-)
+
+---
+2016.11.22
+
+Если при включении питания на выводе кнопки (PA2) будет "0", то сработает
+автокоррекция смещения "0" на входе АЦП -- будет получено и сохранено в EEPROM
+значение АЦП при нулевом токе на входе, которое затем будет использовано при
+расчётах.

BIN
hw/china_ampermetr_10a.dch


+ 154 - 28
src/main.c

@@ -21,15 +21,30 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include "stm8s.h"
-#include "rtos.h"
+//#include "rtos.h"
 
 /* Private defines -----------------------------------------------------------*/
+// for 1 msek ticks
+#define TIM4_PERIOD  (uint8_t)124
+
 #define ADC_PORT  GPIOD
 #define ADC_PINS  GPIO_PIN_3
 #define ADC_CHNL  ADC1_CHANNEL_4
 #define ADC_SCHT  ADC1_SCHMITTTRIG_CHANNEL4
 #define ADC_SMPLS 64
 
+#define BTN_PORT  (GPIOA)
+#define BTN_PINS  (GPIO_PIN_2)
+
+/*
+ AAA
+F   B
+F   B
+ GGG
+E   C
+E   C
+ DDD P
+*/
 #define LED_ANOD1_PORT  GPIOA
 #define LED_ANOD1_PIN   GPIO_PIN_3
 #define LED_ANOD2_PORT  GPIOD
@@ -37,19 +52,26 @@
 #define LED_ANOD3_PORT  GPIOD
 #define LED_ANOD3_PIN   GPIO_PIN_4
 
-#define LED_SEG1_PORT  GPIOA
-#define LED_SEG1_PINS  GPIO_PIN_1
-#define LED_SEG2_PORT  GPIOB
-#define LED_SEG2_PINS  (GPIO_PIN_5 | GPIO_PIN_4)
-#define LED_SEG3_PORT  GPIOC
-#define LED_SEG3_PINS  (GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_3 | GPIO_PIN_5)
+#define LED_SEG1_PORT   GPIOA
+#define LED_SEG1_PINS   GPIO_PIN_1
+#define LED_SEG_F       GPIO_PIN_1
 
-#define BTN_PORT  (GPIOA)
-#define BTN_PINS  (GPIO_PIN_2)
+#define LED_SEG2_PORT   GPIOB
+#define LED_SEG2_PINS   (GPIO_PIN_5 | GPIO_PIN_4)
+#define LED_SEG_A       GPIO_PIN_5
+#define LED_SEG_B       GPIO_PIN_4
+
+#define LED_SEG3_PORT   GPIOC
+#define LED_SEG3_PINS   (GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_3 | GPIO_PIN_5)
+#define LED_SEG_G       GPIO_PIN_3
+#define LED_SEG_C       GPIO_PIN_4
+#define LED_SEG_P       GPIO_PIN_5
+#define LED_SEG_D       GPIO_PIN_6
+#define LED_SEG_E       GPIO_PIN_7
 
 #define LED_OUT_OFF   {LED_SEG1_PORT->ODR |= LED_SEG1_PINS; LED_SEG2_PORT->ODR |= LED_SEG2_PINS; LED_SEG3_PORT->ODR |= LED_SEG3_PINS;}
-#define LED_OUT_DP    GPIOC->ODR &= (~GPIO_PIN_5);
-#define LED_OUT_MM    GPIOC->ODR &= 0xF7;
+#define LED_OUT_DP    GPIOC->ODR &= (~LED_SEG_P);
+#define LED_OUT_MM    GPIOC->ODR &= LED_SEG_G;
 #define LED_OUT_0     GPIOA->ODR &= 0xFD; GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0x29;
 #define LED_OUT_1     GPIOB->ODR &= 0xEF; GPIOC->ODR &= 0xE9;
 #define LED_OUT_2     GPIOB->ODR &= 0xCF; GPIOC->ODR &= 0x31;
@@ -67,11 +89,16 @@
 #define LED_ANODE_ON3 LED_ANOD3_PORT->ODR |= LED_ANOD3_PIN;
 
 #define SUB_SECOND_CNT  5
+#define LED_ONE_PERIOD  5
+
+#define ADC_ZERO_EEADDR   FLASH_DATA_START_PHYSICAL_ADDRESS
 
 /* Private function prototypes -----------------------------------------------*/
+static void ADC_CorrectZero(void);
 static void ADC_Config(void);
 static void GPIO_Config(void);
 static void TIM1_Config(void);
+static void TIM4_Config(void);
 static void OutputToLed(void);
 static void PrepareForLed(void);
 //static void CountCapacity(void);
@@ -81,12 +108,14 @@ static void PrepareForLed(void);
 /* Private variables ---------------------------------------------------------*/
 __IO uint16_t ConversionBuffer[ADC_SMPLS];
 __IO uint8_t BufferIndex = 0;
+__IO uint8_t LedCnt = 0;
 static uint16_t Current = 0;
 static uint32_t Capacity = 0;
 static uint8_t LedDigits[3] = {0, 0, 0};
 static uint8_t LedPoint = 3;
 static uint16_t SubSecondBfr = 0;
 static uint8_t SubSecondCnt = SUB_SECOND_CNT;
+static uint16_t ADC_ZeroFix = 0;
 
 void main(void)
 {
@@ -112,19 +141,39 @@ void main(void)
   TIM1_Config();
 
   /* Initialize dispatcher */
-  RTOS_Init();
-  RTOS_SetTask(OutputToLed, 0, 5);
-  RTOS_SetTask(PrepareForLed, 210, 200);
+  //RTOS_Init();
+  //RTOS_SetTask(OutputToLed, 0, 5);
+  //RTOS_SetTask(PrepareForLed, 210, 200);
   //RTOS_SetTask(CountCapacity, 1005, 1000);
 
+  /* TIM4 configuration -----------------------------------------*/
+  TIM4_Config();
+
+  /* enable interrupts */
+  enableInterrupts();
+
+  /** If btn pin == 0 -- auto fix adc zero level
+      else -- read zero value from eeprom
+      Value stored in MSB:LSB
+  */
+  if((BTN_PORT->IDR & BTN_PINS) == 0){
+    ADC_CorrectZero();
+  } else {
+    ADC_ZeroFix = (uint16_t)(FLASH_ReadByte(ADC_ZERO_EEADDR) << 8);
+    ADC_ZeroFix |= FLASH_ReadByte((ADC_ZERO_EEADDR+1));
+  }
+
   /* Infinite loop */
   while (1)
   {
+    if (LedCnt >= LED_ONE_PERIOD) {
+      LedCnt = 0;
+      OutputToLed();
+    }
+
     if (BufferIndex >= ADC_SMPLS) {
         BufferIndex = 0;
 
-        /* èëè îáðàáàòûâàåì ñðàçó, èëè çàäà÷ó ñ 0-îé çàäåðæêîé? */
-
         /* Oversampling */
         uint32_t tbuf = 0;
         uint8_t i = 0;
@@ -141,32 +190,76 @@ void main(void)
          ïîäåëèëè íà ìíîæèòåëü ÎÓ -- 250 ìÂ
          è ïîäåëèëè íà ñîïðîòèâëåíèå øóíòà -- 5000 ìÀ
         */
-        tbuf >>= 3; // pre div
-        tbuf *= 3300; // Vref = Vcc
-        tbuf = (tbuf + 4096) / 8191; // get ADC input voltage in mV
-        tbuf *= 1000; // get voltage in uV
-        tbuf = (tbuf + 14) / 28; // get voltage from shunt
-        /* â Current òîê â ìèëèàìïåðàõ */
-        Current = (tbuf + 3) / 6; // shunt resistance in mOhms
-
-        SubSecondBfr += Current;
+        if(tbuf > ADC_ZeroFix){
+          tbuf -= ADC_ZeroFix;
+
+          tbuf >>= 3; // pre div
+          tbuf *= 3335; // Vref = Vcc
+          tbuf = (tbuf + 4096) / 8191; // get ADC input voltage in mV
+          tbuf *= 1000; // -- for OU divider //get voltage in uV
+          tbuf = (tbuf + 3147) / 6294; // get voltage from shunt
+          /* â Current òîê â ìèëèàìïåðàõ */
+          tbuf *= 1000; // get voltage in uV
+          Current = (tbuf + 25) / 50; // shunt resistance in mOhms
+
+          SubSecondBfr += Current;
+
+        } else {
+          tbuf = 0;
+          Current = 0;
+        }
+
         SubSecondCnt --;
 
         if(SubSecondCnt == 0){
-          Capacity += SubSecondBfr;
+          Capacity += ( (SubSecondBfr + (SUB_SECOND_CNT/2)) / SUB_SECOND_CNT );
           SubSecondBfr = 0;
           SubSecondCnt = SUB_SECOND_CNT;
         }
 
+        PrepareForLed();
+
     } // End of if (BufferIndex >= ADC_SMPLS)
 
-    RTOS_DispatchTask();
+    //RTOS_DispatchTask();
     wfi();
   } // End of infinity
 
 } // End of main()
 
 
+/** Êîððåêòèðóåì íàïðÿæåíèå ñìåùåíèÿ íóëÿ ÎÓ íà âõîäå ÀÖÏ */
+static void ADC_CorrectZero(void) {
+  /* æä¸ì îêîí÷àíèÿ öèêëà èçìåðåíèé */
+  do {
+  } while (BufferIndex < ADC_SMPLS);
+
+  BufferIndex = 0;
+
+  /* Ïîëó÷àåì 16-òè áèòíîå çíà÷åíèå îò ÀÖÏ */
+  uint8_t i = 0;
+  for(i=0; i<ADC_SMPLS; i++){
+    ADC_ZeroFix += ConversionBuffer[i];
+  }
+
+  /* Ñîõðàíÿåì ïîëó÷åííîå çíà÷åíèå â EEPROM */
+
+  /*Define FLASH programming time*/
+  FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);
+
+  /* Unlock Data memory */
+  FLASH_Unlock(FLASH_MEMTYPE_DATA);
+
+  /* MSB */
+  FLASH_ProgramByte(ADC_ZERO_EEADDR, (uint8_t)(ADC_ZeroFix>>8));
+  /* LSB */
+  FLASH_ProgramByte((ADC_ZERO_EEADDR+1), (uint8_t)(ADC_ZeroFix));
+
+  /* Lock Data memory */
+  FLASH_Lock(FLASH_MEMTYPE_DATA);
+
+}
+
 /** Prepare current value for output ot led */
 static void PrepareForLed(void) {
   uint16_t value;
@@ -178,19 +271,22 @@ static void PrepareForLed(void) {
   }
 
   if(value > 9999){
+    /* XX.X Amper */
     LedPoint = 1;
     LedDigits[0] = value / 10000;
     value = value % 10000;
     LedDigits[1] = value / 1000;
     LedDigits[2] = (value % 1000) / 100;
   } else if(value > 999){
+    /* X.XX Amper */
     LedPoint = 0;
     LedDigits[0] = value / 1000;
     value = value % 1000;
     LedDigits[1] = value / 100;
     LedDigits[2] = (value % 100) / 10;
   } else {
-    LedPoint = 2;
+    /* XXX mili Amper */
+    LedPoint = 3;
     LedDigits[0] = value / 100;
     value = value % 100;
     LedDigits[1] = value / 10;
@@ -348,6 +444,36 @@ static void TIM1_Config(void)
   TIM1_Cmd(ENABLE);
 }
 
+/**
+  * @brief  Configure TIM4.
+  * @param  None
+  * @retval None
+  */
+static void TIM4_Config(void)
+{
+  TIM4_DeInit();
+
+  /*
+  TIM4 configuration:
+   - TIM4CLK is set to 16 MHz, the TIM4 Prescaler is equal to 128 so the TIM1 counter
+     clock used is 16 MHz / 128 = 125 000 Hz
+   - With 125 000 Hz we can generate time base:
+     max time base is 2.048 ms if TIM4_PERIOD = 255 --> (255 + 1) / 125000 = 2.048 ms
+     min time base is 0.016 ms if TIM4_PERIOD = 1   --> (  1 + 1) / 125000 = 0.016 ms
+   - In this example we need to generate a time base equal to 1 ms
+     so TIM4_PERIOD = (0.001 * 125000 - 1) = 124
+   */
+
+  /* Time base configuration */
+  TIM4_TimeBaseInit(TIM4_PRESCALER_128, TIM4_PERIOD);
+  /* Clear TIM4 update flag */
+  TIM4_ClearFlag(TIM4_FLAG_UPDATE);
+  /* Enable update interrupt */
+  TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
+
+  /* Enable TIM4 */
+  TIM4_Cmd(ENABLE);
+}
 
 #ifdef USE_FULL_ASSERT
 

+ 8 - 8
src/stm8s_it.c

@@ -40,6 +40,7 @@
 /* Private variables ---------------------------------------------------------*/
 extern __IO uint16_t ConversionBuffer[64];
 extern __IO uint8_t BufferIndex;
+extern __IO uint8_t LedCnt;
 
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
@@ -496,19 +497,18 @@ INTERRUPT_HANDLER(TIM6_UPD_OVF_TRG_IRQHandler, 23)
   */
  }
 #else /* STM8S208 or STM8S207 or STM8S105 or STM8S103 or STM8AF52Ax or STM8AF62Ax or STM8AF626x */
-#ifndef USE_RTOS
 /**
   * @brief Timer4 Update/Overflow Interrupt routine.
   * @param  None
   * @retval None
   */
- INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
- {
-  /* In order to detect unexpected events during development,
-     it is recommended to set a breakpoint on the following instruction.
-  */
- }
-#endif
+INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
+{
+   /* Cleat Interrupt Pending bit */
+   TIM4->SR1 = (uint8_t)(~(uint8_t)TIM4_IT_UPDATE);
+
+   LedCnt ++;
+}
 #endif /* (STM8S903) || (STM8AF622x)*/
 
 /**