Преглед на файлове

Signed-off-by: zhuhongbin <kptzhu@163.com>221012
Signed-off-by: zhuhongbin <kptzhu@163.com>221012new
Signed-off-by: zhuhongbin <kptzhu@163.com>

zhuhongbin преди 2 години
родител
ревизия
a721edc3bf

+ 1 - 1
Inc/dma.h

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,

+ 1 - 1
Inc/gpio.h

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,

+ 1 - 1
Inc/iwdg.h

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,

+ 12 - 7
Inc/main.h

@@ -58,27 +58,32 @@ void Error_Handler(void);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
-#define t 8
 #define AD_DIN_Pin GPIO_PIN_0
 #define AD_DIN_GPIO_Port GPIOC
 #define AD_CS_Pin GPIO_PIN_1
 #define AD_CS_GPIO_Port GPIOC
 #define AD_CLK_Pin GPIO_PIN_2
 #define AD_CLK_GPIO_Port GPIOC
-#define B1_Pin GPIO_PIN_15
-#define B1_GPIO_Port GPIOB
-#define B2_Pin GPIO_PIN_14
-#define B2_GPIO_Port GPIOB
-#define B3_Pin GPIO_PIN_13
-#define B3_GPIO_Port GPIOB
+#define pwr_Pin GPIO_PIN_5
+#define pwr_GPIO_Port GPIOC
 #define B4_Pin GPIO_PIN_12
 #define B4_GPIO_Port GPIOB
+#define B3_Pin GPIO_PIN_13
+#define B3_GPIO_Port GPIOB
+#define B2_Pin GPIO_PIN_14
+#define B2_GPIO_Port GPIOB
+#define B1_Pin GPIO_PIN_15
+#define B1_GPIO_Port GPIOB
 #define beep_Pin GPIO_PIN_6
 #define beep_GPIO_Port GPIOC
 #define led_Pin GPIO_PIN_7
 #define led_GPIO_Port GPIOC
 #define alarm_Pin GPIO_PIN_8
 #define alarm_GPIO_Port GPIOC
+#define pwr_lock_Pin GPIO_PIN_9
+#define pwr_lock_GPIO_Port GPIOC
+#define ble_c_Pin GPIO_PIN_8
+#define ble_c_GPIO_Port GPIOA
 #define output1_Pin GPIO_PIN_6
 #define output1_GPIO_Port GPIOB
 #define output2_Pin GPIO_PIN_7

+ 52 - 0
Inc/rtc.h

@@ -0,0 +1,52 @@
+/**
+  ******************************************************************************
+  * @file    rtc.h
+  * @brief   This file contains all the function prototypes for
+  *          the rtc.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __RTC_H__
+#define __RTC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern RTC_HandleTypeDef hrtc;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_RTC_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RTC_H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 1 - 1
Inc/stm32f1xx_hal_conf.h

@@ -56,7 +56,7 @@
 /*#define HAL_HCD_MODULE_ENABLED   */
 /*#define HAL_PWR_MODULE_ENABLED   */
 /*#define HAL_RCC_MODULE_ENABLED   */
-/*#define HAL_RTC_MODULE_ENABLED   */
+#define HAL_RTC_MODULE_ENABLED
 /*#define HAL_SD_MODULE_ENABLED   */
 /*#define HAL_MMC_MODULE_ENABLED   */
 /*#define HAL_SDRAM_MODULE_ENABLED   */

+ 1 - 0
Inc/stm32f1xx_it.h

@@ -63,6 +63,7 @@ void USART1_IRQHandler(void);
 void USART2_IRQHandler(void);
 void USART3_IRQHandler(void);
 void UART4_IRQHandler(void);
+void UART5_IRQHandler(void);
 void DMA2_Channel3_IRQHandler(void);
 void DMA2_Channel4_5_IRQHandler(void);
 /* USER CODE BEGIN EFP */

+ 1 - 1
Inc/usart.h

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,

+ 1 - 1
Src/dma.c

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,

+ 27 - 3
Src/gpio.c

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,
@@ -51,7 +51,11 @@ void MX_GPIO_Init(void)
 
   /*Configure GPIO pin Output Level */
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|AD_DIN_Pin|AD_CS_Pin|AD_CLK_Pin
-                          |GPIO_PIN_3|beep_Pin|led_Pin|alarm_Pin, GPIO_PIN_RESET);
+                          |GPIO_PIN_3|beep_Pin|led_Pin|alarm_Pin
+                          |pwr_lock_Pin, GPIO_PIN_RESET);
+
+  /*Configure GPIO pin Output Level */
+  HAL_GPIO_WritePin(ble_c_GPIO_Port, ble_c_Pin, GPIO_PIN_RESET);
 
   /*Configure GPIO pin Output Level */
   HAL_GPIO_WritePin(GPIOB, output1_Pin|output2_Pin|AD_SYNC_Pin, GPIO_PIN_RESET);
@@ -65,14 +69,34 @@ void MX_GPIO_Init(void)
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
+  /*Configure GPIO pin : PtPin */
+  GPIO_InitStruct.Pin = pwr_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  HAL_GPIO_Init(pwr_GPIO_Port, &GPIO_InitStruct);
+
   /*Configure GPIO pins : PBPin PBPin PBPin PBPin
                            PBPin */
-  GPIO_InitStruct.Pin = B1_Pin|B2_Pin|B3_Pin|B4_Pin
+  GPIO_InitStruct.Pin = B4_Pin|B3_Pin|B2_Pin|B1_Pin
                           |AD_DOUT_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_PULLDOWN;
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
+  /*Configure GPIO pin : PtPin */
+  GPIO_InitStruct.Pin = pwr_lock_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(pwr_lock_GPIO_Port, &GPIO_InitStruct);
+
+  /*Configure GPIO pin : PtPin */
+  GPIO_InitStruct.Pin = ble_c_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(ble_c_GPIO_Port, &GPIO_InitStruct);
+
   /*Configure GPIO pins : PBPin PBPin PBPin */
   GPIO_InitStruct.Pin = output1_Pin|output2_Pin|AD_SYNC_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

+ 1 - 1
Src/iwdg.c

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,

+ 56 - 16
Src/main.c

@@ -21,6 +21,7 @@
 #include "main.h"
 #include "dma.h"
 #include "iwdg.h"
+#include "rtc.h"
 #include "usart.h"
 #include "gpio.h"
 
@@ -35,6 +36,7 @@
 #include "display.h"
 #include "plan.h"
 
+#include "syswatch.h"
 #include <cm_backtrace.h>
 /* USER CODE END Includes */
 
@@ -120,6 +122,7 @@ int main(void)
 {
   /* USER CODE BEGIN 1 */
 	extern IWDG_HandleTypeDef hiwdg;
+	extern unsigned char XbeeConst_FrameNum;
   /* USER CODE END 1 */
 
   /* MCU Configuration--------------------------------------------------------*/
@@ -130,10 +133,10 @@ int main(void)
   /* USER CODE BEGIN Init */
 	
    /* CmBacktrace initialize */
-  //  cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION);
+   // cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION);
     
     /* set exception hook */
-  //  rt_hw_exception_install(exception_hook);
+   // rt_hw_exception_install(exception_hook);
 	
   /* USER CODE END Init */
 
@@ -141,6 +144,8 @@ int main(void)
   SystemClock_Config();
 
   /* USER CODE BEGIN SysInit */
+	MX_GPIO_Init();	
+	pwr_lock_on();
 	MX_IWDG_Init();  
   onbordflash_init();
 	HAL_IWDG_Refresh(&hiwdg);
@@ -155,16 +160,37 @@ int main(void)
   MX_USART2_UART_Init();
   MX_USART3_UART_Init();
   MX_IWDG_Init();
+  MX_RTC_Init();
   /* USER CODE BEGIN 2 */
   rt_show_version();  
+	
+ /* 使能备份时钟:备份寄存器 */
+	__HAL_RCC_BKP_CLK_ENABLE();
+	HAL_PWR_EnableBkUpAccess();
+  XbeeConst_FrameNum = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);
+  if(READ_BIT(RCC->CSR, RCC_CSR_IWDGRSTF) != RESET)  //看门狗重启不需要获取时间
+  {	     
+      uint16_t timeval1,timeval2;
+			timeval1 = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);
+			timeval2 = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);	      	
+			TimeConst.Buffer[0]=timeval1 & 0xFF;
+			TimeConst.Buffer[1]=(timeval1>>8) & 0xFF;
+			TimeConst.Buffer[2]=timeval2 & 0xFF;
+			TimeConst.Buffer[3]=(timeval2>>8) & 0xFF;
+	}
 
 	thread_init();
+	WeightConst_Product_Run_time= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);	
+	WeightConst_DELAYON= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);	
+	WeightConst_DELAYTIME= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5);	
+	pf_comp.data.delaytime= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR6);
 	thread_beep_init();
 	output1_off();
 	output2_off();
+	AT_off();
  // rt_kprintf("\n \\ | /\n");
 	rt_sem_take(thread_init_sem, RT_WAITING_FOREVER);   //等待初始化进程完毕
-//				 init_allflash();
+//			 init_allflash();
 //			 beep();			
 //			 rt_sem_take(thread_init_sem, RT_WAITING_FOREVER);   //等待初始化进程完毕
 	if (WeightConst_SBType == 4)
@@ -205,25 +231,27 @@ int main(void)
 			}	
 	  }
 	}	
-	
+	MX_IWDG_Init();
   threadUart_init();
+//	threadUart5_init();
 	ReadWeight_thread();
 	
 	if (inMenu==1)
 	{		
-		  beep();
-			MenuButtonthread();
-    	threadMenuDisplay_init();
+		beep();
+		MenuButtonthread();
+    threadMenuDisplay_init();
 	}
   else {		
-		  Button_thread();
-			SendWifi_thread();	
-		  if (WeightConst_SBType != 2) 
+		Button_thread();
+		SendWifi_thread();	
+		if (WeightConst_SBType != 2) 
       {	
 				if (WeightConst_SBType == 4)  threadDisplay_delay_init();		
         delay_key_thread();			
 				threadDisplay_init();	
 				setTIME_thread();
+				if (WeightConst_DELAYON==0) 
 				setWeightConst_initProduct();
 				threadRemoteDisplay_init();
 				sendgetTime();
@@ -237,10 +265,6 @@ int main(void)
 		    CanButton = 1; 	
 			}
 	}
-	
-
-
-
   /* USER CODE END 2 */
 
   /* Infinite loop */
@@ -250,7 +274,6 @@ int main(void)
     /* USER CODE END WHILE */
 
     /* USER CODE BEGIN 3 */
-//		rt_kprintf("\n \\ | /\n");
     rt_thread_mdelay(500);
     HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);		
     HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
@@ -266,6 +289,7 @@ void SystemClock_Config(void)
 {
   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
   /** Initializes the RCC Oscillators according to the specified parameters
   * in the RCC_OscInitTypeDef structure.
@@ -295,10 +319,26 @@ void SystemClock_Config(void)
   {
     Error_Handler();
   }
+  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
+  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
+  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+  {
+    Error_Handler();
+  }
 }
 
 /* USER CODE BEGIN 4 */
-
+uint8_t rDataBuffer;
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{  
+	if (huart->Instance == UART5 && isTag>0){
+		if (isTag) {
+			USART_Push(5, rDataBuffer);
+			rt_sem_release(thread_EmptyBuffer_sem); 	
+		}		
+		HAL_UART_Receive_IT(&huart5, &rDataBuffer, 1); 
+  }
+}
 /* USER CODE END 4 */
 
 /**

+ 84 - 0
Src/rtc.c

@@ -0,0 +1,84 @@
+/**
+  ******************************************************************************
+  * @file    rtc.c
+  * @brief   This file provides code for the configuration
+  *          of the RTC instances.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtc.h"
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+RTC_HandleTypeDef hrtc;
+
+/* RTC init function */
+void MX_RTC_Init(void)
+{
+
+  /** Initialize RTC Only
+  */
+  hrtc.Instance = RTC;
+  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
+  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
+  if (HAL_RTC_Init(&hrtc) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+}
+
+void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
+{
+
+  if(rtcHandle->Instance==RTC)
+  {
+  /* USER CODE BEGIN RTC_MspInit 0 */
+
+  /* USER CODE END RTC_MspInit 0 */
+    HAL_PWR_EnableBkUpAccess();
+    /* Enable BKP CLK enable for backup registers */
+    __HAL_RCC_BKP_CLK_ENABLE();
+    /* RTC clock enable */
+    __HAL_RCC_RTC_ENABLE();
+  /* USER CODE BEGIN RTC_MspInit 1 */
+
+  /* USER CODE END RTC_MspInit 1 */
+  }
+}
+
+void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
+{
+
+  if(rtcHandle->Instance==RTC)
+  {
+  /* USER CODE BEGIN RTC_MspDeInit 0 */
+
+  /* USER CODE END RTC_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_RTC_DISABLE();
+  /* USER CODE BEGIN RTC_MspDeInit 1 */
+
+  /* USER CODE END RTC_MspDeInit 1 */
+  }
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 21 - 1
Src/stm32f1xx_it.c

@@ -26,6 +26,7 @@
 #include "usart.h"
 #include "buffer.h"
 #include <rtthread.h>
+#include "flash.h"
 /* USER CODE END Includes */
 
 /* Private typedef -----------------------------------------------------------*/
@@ -68,6 +69,7 @@ extern DMA_HandleTypeDef hdma_usart2_tx;
 extern DMA_HandleTypeDef hdma_usart3_rx;
 extern DMA_HandleTypeDef hdma_usart3_tx;
 extern UART_HandleTypeDef huart4;
+extern UART_HandleTypeDef huart5;
 extern UART_HandleTypeDef huart1;
 extern UART_HandleTypeDef huart2;
 extern UART_HandleTypeDef huart3;
@@ -310,6 +312,20 @@ void UART4_IRQHandler(void)
   /* USER CODE END UART4_IRQn 1 */
 }
 
+/**
+  * @brief This function handles UART5 global interrupt.
+  */
+void UART5_IRQHandler(void)
+{
+  /* USER CODE BEGIN UART5_IRQn 0 */
+
+  /* USER CODE END UART5_IRQn 0 */
+  HAL_UART_IRQHandler(&huart5);
+  /* USER CODE BEGIN UART5_IRQn 1 */
+
+  /* USER CODE END UART5_IRQn 1 */
+}
+
 /**
   * @brief This function handles DMA2 channel3 global interrupt.
   */
@@ -344,6 +360,7 @@ void USART_IRQHandler(UART_HandleTypeDef *huart)
   uint32_t tmp_flag = 0;
 	uint32_t temp;
 	extern unsigned char inMenu;
+
 	tmp_flag =__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE); //»ñÈ¡IDLE±ê־λ
 	if((tmp_flag != RESET))//idle±êÖ¾±»ÖÃλ
 	{ 
@@ -392,8 +409,11 @@ void USART_IRQHandler(UART_HandleTypeDef *huart)
       rt_memset(rx_buffer4, 0, BUFFER_SIZE);	
       HAL_UART_Receive_DMA(huart, rx_buffer4, BUFFER_SIZE);
 		}	
-		if (rx_len>0) rt_sem_release(thread_EmptyBuffer_sem); 
+
+		if (rx_len>0) rt_sem_release(thread_EmptyBuffer_sem); 	
 	}
+		
+ 
 }
 
 /* USER CODE END 1 */

+ 8 - 3
Src/usart.c

@@ -6,7 +6,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
   * All rights reserved.</center></h2>
   *
   * This software component is licensed by ST under BSD 3-Clause license,
@@ -77,7 +77,7 @@ void MX_UART5_Init(void)
 {
 
   huart5.Instance = UART5;
-  huart5.Init.BaudRate = 115200;
+  huart5.Init.BaudRate = 9600;
   huart5.Init.WordLength = UART_WORDLENGTH_8B;
   huart5.Init.StopBits = UART_STOPBITS_1;
   huart5.Init.Parity = UART_PARITY_NONE;
@@ -134,7 +134,7 @@ void MX_USART3_UART_Init(void)
 {
 
   huart3.Instance = USART3;
-  huart3.Init.BaudRate = 9600;
+  huart3.Init.BaudRate = 115200;//9600;
   huart3.Init.WordLength = UART_WORDLENGTH_8B;
   huart3.Init.StopBits = UART_STOPBITS_1;
   huart3.Init.Parity = UART_PARITY_NONE;
@@ -239,6 +239,9 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
+    /* UART5 interrupt Init */
+    HAL_NVIC_SetPriority(UART5_IRQn, 1, 0);
+    HAL_NVIC_EnableIRQ(UART5_IRQn);
   /* USER CODE BEGIN UART5_MspInit 1 */
 
   /* USER CODE END UART5_MspInit 1 */
@@ -477,6 +480,8 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
 
     HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
 
+    /* UART5 interrupt Deinit */
+    HAL_NVIC_DisableIRQ(UART5_IRQn);
   /* USER CODE BEGIN UART5_MspDeInit 1 */
 
   /* USER CODE END UART5_MspDeInit 1 */

+ 504 - 0
syswatch/LICENSE

@@ -0,0 +1,504 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+(This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.)
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    {description}
+    Copyright (C) {year} {fullname}
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+    USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random
+  Hacker.
+
+  {signature of Ty Coon}, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!

BIN
syswatch/figures/syswatch_test_mode_0.JPG


BIN
syswatch/figures/syswatch_test_mode_1.JPG


BIN
syswatch/figures/syswatch_test_mode_2_1.JPG


BIN
syswatch/figures/syswatch_test_mode_2_2.JPG


+ 30 - 0
syswatch/inc/syswatch.h

@@ -0,0 +1,30 @@
+/*
+ * File      : syswatch.h
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2020-01-10     qiyongzhong       first version
+ */
+
+#ifndef __SYSWATCH_H__
+#define __SYSWATCH_H__
+
+#include <syswatch_config.h>
+
+#ifdef SYSWATCH_USING
+
+typedef enum{
+    SYSWATCH_EVENT_SYSTEM_RESET = 0,    //系统复位事件,事件前回调
+    SYSWATCH_EVENT_THREAD_KILL,         //杀掉线程事件,事件前回调
+    SYSWATCH_EVENT_THREAD_RESUMED,      //恢复线程事件,事件后回调
+}syswatch_event_t;   
+
+typedef void ( * syswatch_event_hook_t)(syswatch_event_t eid, rt_thread_t except_thread);
+
+void syswatch_set_event_hook(syswatch_event_hook_t hook);//set syswatch event callback function
+int syswatch_init(void);//Initialize syswatch components 
+
+#endif  //SYSWATCH_USING
+#endif  //__SYSWATCH_H__
+
+

+ 66 - 0
syswatch/inc/syswatch_config.h

@@ -0,0 +1,66 @@
+/*
+ * File      : syswatch.h
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2020-01-10     qiyongzhong       first version
+ */
+     
+#ifndef __SYSWATCH_CONFIG_H__
+#define __SYSWATCH_CONFIG_H__
+
+#include <rtconfig.h>
+
+#define PKG_USING_SYSWATCH
+//#define SYSWATCH_USING_TEST
+
+#ifdef PKG_USING_SYSWATCH
+
+#define SYSWATCH_USING
+
+/* thread exception resolve mode:
+ * 0--system reset
+ * 1--kill exception thread 
+ * 2--resume exception thread
+ */
+#ifndef SYSWATCH_EXCEPT_RESOLVE_MODE
+#define SYSWATCH_EXCEPT_RESOLVE_MODE    2
+#endif
+
+#ifndef SYSWATCH_EXCEPT_TIMEOUT
+#define SYSWATCH_EXCEPT_TIMEOUT         2//thread exception blocking timeout, unit : s
+#endif
+
+#ifndef SYSWATCH_EXCEPT_CONFIRM_TMO
+#define SYSWATCH_EXCEPT_CONFIRM_TMO     2//exception thread confirm timeout, unit : s
+#endif
+
+#ifndef SYSWATCH_EXCEPT_RESUME_DLY
+#define SYSWATCH_EXCEPT_RESUME_DLY      1//exception thread resume delay, unit : s
+#endif
+
+#ifndef SYSWATCH_THREAD_PRIO
+#define SYSWATCH_THREAD_PRIO            0//the highest priority allowed in your system
+#endif
+
+#ifndef SYSWATCH_THREAD_STK_SIZE
+#define SYSWATCH_THREAD_STK_SIZE        512//stack size of system watcher
+#endif
+
+#ifndef SYSWATCH_THREAD_NAME
+#define SYSWATCH_THREAD_NAME            "syswatch"//thread name of system watcher 
+#endif
+
+#ifndef SYSWATCH_WDT_NAME
+#define SYSWATCH_WDT_NAME               "wdt"//name of watchdog device used
+#endif
+
+#ifndef SYSWATCH_WDT_TIMEOUT
+#define SYSWATCH_WDT_TIMEOUT            2//timeout of watchdog device used
+#endif
+
+#endif  //PKG_USING_SYSWATCH
+
+#endif  //__SYSWATCH_CONFIG_H__
+
+

+ 99 - 0
syswatch/readme.md

@@ -0,0 +1,99 @@
+# 系统看守
+
+## 1.简介
+
+**系统看守(syswatch)组件** 主要功能是保障实时操作系统正常运行,防止系统死机以及各种异常引起的线程阻塞,保障整个系统长期正常运行。系统看守具备以下几种行为模式:
+1.系统崩溃或硬件异常导致系统失去调度时,执行 `系统复位` 恢复系统正常运行。
+2.当有异常导致某些线程长时间阻塞时,可根据用户的配置实施 `系统复位` / `杀掉阻塞线程` / `重启阻塞线程` 的方式恢复系统正常运行。
+
+### 1.1工作原理简述 
+
+**系统看守(syswatch)组件** 使用实时操作系统中允许的最高优先级作为看守线程的优先级,保障看守线程不会被阻塞,同时看守线程由看门狗提供看护,保障看守线程正常运行;系统看守通过 `线程调度回调接口` 监测线程的调度情况,当检测到有线程发生异常阻塞时,开始检测和确认具体哪个线程发生了异常阻塞,最后根据异常解决模式执行  `系统复位` / `杀掉阻塞线程` / `重启阻塞线程` 清除异常,使系统恢复正常运行。
+
+### 1.2目录结构
+
+`syswatch` 软件包目录结构如下所示:
+
+``` 
+syswatch
+├───inc                             // 头文件目录
+│   |   syswatch.h                  // API 接口头文件
+│   └───syswatch_config.h           // 参数配置头文件
+├───src                             // 源码目录
+│   |   syswatch.c                  // 主功能模块
+│   └───syswatch_test.c             // 功能测试模块
+├───figures                         // 文档使用图片
+│   LICENSE                         // 软件包许可证
+│   README.md                       // 软件包使用说明
+└───SConscript                      // RT-Thread 默认的构建脚本
+```
+
+### 1.3许可证
+
+syswatch package 遵循 LGPLv2.1 许可,详见 `LICENSE` 文件。
+
+### 1.4依赖
+
+- RT_Thread 4.0
+- RT_Thread watchdog device
+- RT_Thread enable system hook
+
+## 2.使用
+
+### 2.1获取组件
+
+- **方式1:**
+1.下载[syswatch软件包](https://github.com/qiyongzhong0/rt-thread-syswatch),并将软件包`syswatch`文件夹复制到工程原码目录下
+2.将软件包中syswatch.c和syswatch_test.c加入项目工程中
+3.将软件包中syswatch_config.h中 `RT_USING_SYSWATCH` 和 `SYSWATCH_USING_TEST` 两个宏的注释去掉;并根据需要修改各项配置参数
+
+- **方式2:**
+通过 *Env配置工具* 或 *RT-Thread studio* 开启软件包,根据需要配置各项参数;配置路径为 *RT-Thread online packages -> system packages -> syswatch* 
+
+
+### 2.2配置参数说明
+
+|参数宏|说明|
+|----|----|
+|`SYSWATCH_EXCEPT_RESOLVE_MODE`|异常解决模式,可配置值0~2,默认值 2,0--复位系统,1--杀掉异常线程,2--重启异常线程
+|`SYSWATCH_EXCEPT_TIMEOUT`|判定存在线程异常的超时时间,单位:秒,默认值 60
+|`SYSWATCH_EXCEPT_CONFIRM_TMO`|确认异常线程的超时时间,单位:秒,默认值 15
+|`SYSWATCH_EXCEPT_RESUME_DLY`|重启异常线程的延时时间,单位:秒,默认值 15
+|`SYSWATCH_THREAD_PRIO`|系统看守线程的优先级,默认值 0
+|`SYSWATCH_THREAD_STK_SIZE`|系统看守线程的堆栈尺寸,默认值 512
+|`SYSWATCH_THREAD_NAME`|系统看守线程的名称,默认值 `syswatch`
+|`SYSWATCH_WDT_NAME`|使用看门狗设备的名称,默认值 `wdt`
+|`SYSWATCH_WDT_TIMEOUT`|使用看门设备的超时时间,单位:秒,默认值 5
+
+## 3.注意事项
+
+- syswatch 依赖于看门狗设备而工作,使用本组件时请确认已注册了看门狗设备。
+- syswatch 全权管理看门狗,请不要在其它线程中使用和操作看门狗。
+- syswatch 提供了3种异常解决模式,请根据实际需要配置适合的工作模式。
+- `syswatch_set_event_hook` 提供用户安装事件回调函数,以便针对重要事件发生时进行一些必要处理,如系统复位前须对重要数据进行保存时,可设置回调函数完成相应处理,如不需要可不设置。
+
+## 4.测试验证
+
+组件安装后,为了验证其功能是否正常,组件提供了测试例程,可通过shell命令`syswatch_test`创建异常模拟线程。
+`syswatch_test`命令参数有2个,第1个是创建线程的优先级,第2个是发生异常阻塞的延时时间。
+如执行命令`syswatch_test 20 30`后,会创建一个优先级为20的线程,在线程开始运行30秒后,线程进入异常阻塞状态。
+
+### 4.1模式0测试示例
+
+![syswatch_test_mode_0.JPG](figures/syswatch_test_mode_0.JPG)
+
+### 4.2模式1测试示例
+
+![syswatch_test_mode_1.JPG](figures/syswatch_test_mode_1.JPG)
+
+### 4.3模式2测试示例
+
+![syswatch_test_mode_2_1.JPG](figures/syswatch_test_mode_2_1.JPG)
+![syswatch_test_mode_2_2.JPG](figures/syswatch_test_mode_2_2.JPG)
+
+## 5. 联系方式
+
+* 维护:qiyongzhong
+* 主页:https://github.com/qiyongzhong0/rt-thread-syswatch
+
+

+ 370 - 0
syswatch/src/syswatch.c

@@ -0,0 +1,370 @@
+/*
+ * File      : syswatch.c
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2020-01-08     qiyongzhong       first version
+ * 2020-05-08     qiyongzhong       optimized initialization operation 
+ */
+     
+#include <rtthread.h>
+#include <rthw.h>
+#include <syswatch.h>
+#include "iwdg.h"
+#ifdef SYSWATCH_USING
+
+//#define SYSWATCH_DEBUG
+
+#define DBG_TAG                         SYSWATCH_THREAD_NAME
+#ifdef SYSWATCH_DEBUG
+#define DBG_LVL                         DBG_LOG
+#else
+#define DBG_LVL                         DBG_INFO
+#endif
+#include <rtdbg.h>
+
+typedef struct{
+    rt_bool_t init_ok;
+    rt_uint16_t sec_cnt;//time counter
+    rt_uint16_t op_step;//opration step : 0--wait thread except, 1--check except thread
+    syswatch_event_hook_t event_hook;
+    rt_thread_t lowest_thread;//the lowest priority thread that the system can switch to,except for idle thread 
+    rt_slist_t wait_resume_slist;//list of threads waiting for resume
+}syswatch_data_t;
+
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 2)
+typedef struct thread_msg{
+    rt_slist_t slist;
+    void * thread;
+    void * entry;
+    void * parameter;
+    void * stack_addr;
+    rt_uint32_t stack_size;
+    rt_uint32_t init_tick;
+    rt_uint8_t priority;
+    char name[RT_NAME_MAX];
+}thread_msg_t;
+#endif
+
+static syswatch_data_t sw_data = {RT_FALSE,0,0,RT_NULL,RT_NULL,RT_NULL};
+
+static void syswatch_event_hook_call(syswatch_event_t eid, rt_thread_t except_thread)
+{
+    if (sw_data.event_hook)
+    {
+        (sw_data.event_hook)(eid, except_thread);
+    }
+}
+
+static int syswatch_wdt_startup(void)
+{
+    MX_IWDG_Init();  
+
+    return RT_EOK;
+}
+
+static void syswatch_wdt_feed(void)
+{
+   HAL_IWDG_Refresh(&hiwdg);
+}
+
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 0)
+/* thread except resolve mode 0--system reset */
+static void syswatch_thread_except_resolve_reset(rt_thread_t thread)
+{
+    LOG_E("%.*s thread exception, priority = %d, execute system reset", RT_NAME_MAX, thread->name, thread->current_priority);
+    syswatch_event_hook_call(SYSWATCH_EVENT_SYSTEM_RESET, thread);
+    rt_thread_mdelay(100);
+    rt_hw_cpu_reset();
+}
+#endif
+
+#if ((SYSWATCH_EXCEPT_RESOLVE_MODE == 1)||(SYSWATCH_EXCEPT_RESOLVE_MODE == 2))
+/* thread except resolve mode 1 or 2--kill exception thread  */
+static void syswatch_thread_except_resolve_kill(rt_thread_t thread)
+{
+    syswatch_event_hook_call(SYSWATCH_EVENT_THREAD_KILL, thread);
+    
+    if (rt_object_is_systemobject((rt_object_t)thread))
+    {
+        rt_thread_detach(thread);
+    }
+    else
+    {
+        rt_thread_delete(thread);
+    }
+    
+    LOG_E("%.*s thread exception, priority = %d, successfully killed", RT_NAME_MAX, thread->name, thread->current_priority);
+}
+#endif
+
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 2)
+/* thread except resolve mode 2--save exception thread message */
+static void syswatch_thread_except_resolve_resume_save_msg(rt_thread_t thread)
+{
+    thread_msg_t *thread_msg;
+
+    thread_msg = rt_malloc(sizeof(thread_msg_t));
+    if (thread_msg == RT_NULL)
+    {
+        LOG_E("save exception thread message fail, no memory");
+        return;
+    }
+    
+    thread_msg->thread = thread;
+    thread_msg->entry = thread->entry;
+    thread_msg->parameter = thread->parameter;
+    thread_msg->stack_addr = thread->stack_addr;
+    thread_msg->stack_size = thread->stack_size;
+    thread_msg->init_tick = thread->init_tick;
+    #if (RTTHREAD_VERSION < 40100)
+    thread_msg->priority= thread->init_priority;
+    #else
+    thread_msg->priority= thread->current_priority;
+    #endif
+    rt_strncpy(thread_msg->name, thread->name, RT_NAME_MAX);
+
+    rt_slist_append(&(sw_data.wait_resume_slist), (rt_slist_t *)thread_msg);
+
+    LOG_I("save exception thread message successfully");
+}
+
+/* thread except resolve mode 2--resume exception thread from thread message */
+static void syswatch_thread_except_resolve_resume_from_msg(thread_msg_t * thread_msg)
+{
+    if (rt_object_is_systemobject((rt_object_t)(thread_msg->thread)))
+    {
+        rt_thread_init( thread_msg->thread, 
+                        thread_msg->name, 
+                        (void (*)(void*))(thread_msg->entry), 
+                        thread_msg->parameter, 
+                        thread_msg->stack_addr, 
+                        thread_msg->stack_size, 
+                        thread_msg->priority,
+                        thread_msg->init_tick
+                        );
+        rt_thread_startup(thread_msg->thread);
+        syswatch_event_hook_call(SYSWATCH_EVENT_THREAD_RESUMED, thread_msg->thread);
+        LOG_I("%.*s exception thread, priority = %d, successfully resumed", RT_NAME_MAX, thread_msg->name, thread_msg->priority);
+    }
+    else
+    {
+        rt_thread_t thread = rt_thread_create(  thread_msg->name, 
+                                                (void (*)(void*))(thread_msg->entry),
+                                                thread_msg->parameter, 
+                                                thread_msg->stack_size, 
+                                                thread_msg->priority,
+                                                thread_msg->init_tick
+                                                );
+        if (thread)
+        {
+            rt_thread_startup(thread);
+            syswatch_event_hook_call(SYSWATCH_EVENT_THREAD_RESUMED, thread);
+            LOG_I("%.*s exception thread, priority = %d, successfully resumed", RT_NAME_MAX, thread_msg->name, thread_msg->priority);
+        }
+        else
+        {
+            LOG_E("%.*s exception thread, priority = %d, resume fail", RT_NAME_MAX, thread_msg->name, thread_msg->priority);
+        }
+    }
+}
+
+/* thread except resolve mode 2--resume all exception thread  */
+static void syswatch_thread_except_resolve_resume_all(void)
+{
+    thread_msg_t *thread_msg;
+
+    while(1)
+    {
+        thread_msg = (thread_msg_t *)rt_slist_first(&(sw_data.wait_resume_slist));
+        if (thread_msg == RT_NULL)
+        {
+            break;
+        }
+        syswatch_thread_except_resolve_resume_from_msg(thread_msg);
+        rt_slist_remove(&(sw_data.wait_resume_slist), (rt_slist_t *)thread_msg);
+        rt_free(thread_msg);				
+    }
+}
+#endif
+
+static void syswatch_thread_except_resolve(rt_thread_t thread)
+{
+    if ((thread == RT_NULL) || thread == rt_thread_self())
+    {
+        LOG_D("exception thread is null or self");
+        return;
+    }
+    
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 0)//mode 0--system reset
+    syswatch_thread_except_resolve_reset(thread);
+#elif (SYSWATCH_EXCEPT_RESOLVE_MODE == 1)//mode 1--kill exception thread 
+    syswatch_thread_except_resolve_kill(thread);
+#elif (SYSWATCH_EXCEPT_RESOLVE_MODE == 2)//mode 2--resume exception thread 
+    syswatch_thread_except_resolve_resume_save_msg(thread);
+    syswatch_thread_except_resolve_kill(thread);
+#else
+#error "SYSWATCH_EXCEPT_DEAL_MODE define error,it must be 0/1/2"
+#endif
+}
+
+static void syswatch_thread_switch_hook(struct rt_thread * from, struct rt_thread * to)
+{
+    if (from->current_priority > to->current_priority)//low->high or same, no care
+    {
+        return;
+    }
+    if (to->current_priority == RT_THREAD_PRIORITY_MAX-1)//switch to idle thread
+    {
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 2)
+        switch(sw_data.op_step)
+        {
+        case 0://waiting thread exception
+            sw_data.sec_cnt = 0;
+            break;
+        case 1://confirming exception thread 
+            sw_data.sec_cnt = 0;
+            if (! rt_slist_isempty(&(sw_data.wait_resume_slist)))//mode 2 : all exception threads have been killed
+            {
+                sw_data.op_step = 2;//to resume
+            }
+            else
+            {
+                sw_data.op_step = 0;//to waiting
+            }
+            break;
+        case 2://resuming exception thread 
+            break;
+        default:
+            break;
+        }
+#else
+        sw_data.sec_cnt = 0;
+        sw_data.op_step = 0;
+#endif
+        return;
+    }
+    if (sw_data.op_step != 1)//no confirming exception thread
+    {
+        return;
+    }
+    if (sw_data.lowest_thread == RT_NULL)//begin confirming exception thread 
+    {
+        sw_data.lowest_thread = to;
+        return;
+    }
+    if (to->current_priority > sw_data.lowest_thread->current_priority)//to lower
+    {
+        sw_data.lowest_thread = to;
+        return;
+    }
+    if (to->current_priority < sw_data.lowest_thread->current_priority)//to higher
+    {
+        return;
+    }
+    if (to->current_priority == from->current_priority)//same priority task switching 
+    {
+        if ((from->stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)//is yield
+        {
+            sw_data.lowest_thread = from;
+        }
+    }
+}
+
+static rt_bool_t syswatch_check_timeout(rt_uint16_t tmo_s)
+{
+    sw_data.sec_cnt++;
+    if (sw_data.sec_cnt < tmo_s)
+    {
+        return(RT_FALSE);
+    }
+    sw_data.sec_cnt = 0;
+    return(RT_TRUE);
+}
+
+static void syswatch_fsm(void)
+{       
+    switch(sw_data.op_step)
+    {
+    case 0://waiting thread except
+        if (syswatch_check_timeout(SYSWATCH_EXCEPT_TIMEOUT))
+        {
+            sw_data.op_step = 1;
+            sw_data.lowest_thread = RT_NULL;
+        }
+        break;
+    case 1://confirming except thread 
+        if (syswatch_check_timeout(SYSWATCH_EXCEPT_CONFIRM_TMO))
+        {
+            syswatch_thread_except_resolve(sw_data.lowest_thread);
+            sw_data.lowest_thread = RT_NULL; 
+        }
+        break;    
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 2)
+    case 2://resuming except thread
+        if (syswatch_check_timeout(SYSWATCH_EXCEPT_RESUME_DLY))
+        {
+            syswatch_thread_except_resolve_resume_all();
+            sw_data.op_step = 0;
+        }
+        break;
+#endif
+    default:
+        sw_data.op_step = 0;
+        sw_data.sec_cnt = 0;
+        break;
+    }
+}
+
+static void syswatch_thread_entry(void *parameter)
+{
+    if (syswatch_wdt_startup() != RT_EOK)
+    {
+        LOG_E("watch dog startup fail");
+        return;
+    }
+    
+    LOG_I("system watch startup successfully");
+    
+    rt_slist_init(&(sw_data.wait_resume_slist));
+    rt_scheduler_sethook(syswatch_thread_switch_hook);
+    
+    while(1)
+    {
+        rt_thread_delay(RT_TICK_PER_SECOND);
+        syswatch_wdt_feed();
+        syswatch_fsm();
+    }
+}
+
+void syswatch_set_event_hook(syswatch_event_hook_t hook)
+{
+    sw_data.event_hook = hook;
+}
+
+int syswatch_init(void)
+{
+    rt_thread_t tid;
+
+    if(sw_data.init_ok)
+    {
+        return RT_EOK;
+    }
+
+    tid = rt_thread_create(SYSWATCH_THREAD_NAME, syswatch_thread_entry, RT_NULL,
+                           SYSWATCH_THREAD_STK_SIZE, SYSWATCH_THREAD_PRIO, 20);
+    if (tid == RT_NULL)
+    {
+        LOG_E("create syswatch thread failed.");
+        return -RT_ERROR;
+    }
+   
+    LOG_I("create syswatch thread success.");
+    rt_thread_startup(tid);
+    sw_data.init_ok = RT_TRUE;
+    
+    return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(syswatch_init);
+
+#endif  //SYSWATCH_USING

+ 109 - 0
syswatch/src/syswatch_test.c

@@ -0,0 +1,109 @@
+/*
+ * File      : syswatch_test.c
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2020-01-10     qiyongzhong       first version
+ */
+     
+#include <stdlib.h>
+#include <stdio.h>
+#include <rtthread.h>
+#include <syswatch_config.h>
+
+#ifdef SYSWATCH_USING_TEST
+
+#define DBG_TAG                     "syswatch_test"
+#define DBG_LVL                     DBG_LOG
+#include <rtdbg.h>
+
+static rt_uint32_t thread_cnt = 0;
+static rt_uint32_t thread_sign = 0;
+
+static void syswatch_test_thread_entry(void *parameter)
+{
+    rt_uint32_t delay_s = (rt_uint32_t)parameter;
+    rt_thread_t thread = rt_thread_self();
+
+#if (SYSWATCH_EXCEPT_RESOLVE_MODE == 2)
+
+    rt_uint32_t idx;
+
+    idx = atoi(thread->name+6);
+    idx %= 32;
+    
+    if ((thread_sign & (1<<idx)) == 0)//first entry
+    {
+        thread_sign |= (1<<idx);
+
+        LOG_I("system watch test thread startup, name = %.*s, priority = %d", RT_NAME_MAX, thread->name, thread->current_priority);
+        LOG_I("system watch thread exception timeout = %d s, delay = %d s", SYSWATCH_EXCEPT_TIMEOUT, delay_s);
+        LOG_I("system watch exception resolve mode = %d", SYSWATCH_EXCEPT_RESOLVE_MODE);
+
+        rt_thread_mdelay(delay_s * 1000);
+        LOG_I("%.*s thread exception begin. priority = %d", RT_NAME_MAX, thread->name ,thread->current_priority);
+        while(1);
+    }
+    else//second entry
+    {
+        thread_sign &= ~(1<<idx);
+        
+        LOG_I("%.*s thread test completion, it will be closed after 10s .", RT_NAME_MAX, thread->name);
+        rt_thread_mdelay(10 * 1000);
+        LOG_I("%.*s thread closed.", RT_NAME_MAX, thread->name);
+    }
+#else
+    LOG_I("system watch test thread startup, name = %.*s, priority = %d", RT_NAME_MAX, thread->name, thread->current_priority);
+    LOG_I("system watch thread exception timeout = %d s, delay = %d s", SYSWATCH_EXCEPT_TIMEOUT, delay_s);
+    LOG_I("system watch exception resolve mode = %d", SYSWATCH_EXCEPT_RESOLVE_MODE);
+
+    rt_thread_mdelay(delay_s * 1000);
+    LOG_I("%.*s thread exception begin. priority = %d", RT_NAME_MAX, thread->name ,thread->current_priority);
+    while(1);
+#endif
+}
+
+static void syswatch_test_startup(rt_uint8_t prio, rt_uint32_t except_delay_s)
+{
+    rt_thread_t tid;
+    char name[RT_NAME_MAX+1];
+
+    thread_cnt++;
+    rt_sprintf(name, "swtst_%02d", thread_cnt);
+
+    tid = rt_thread_create(name, syswatch_test_thread_entry, (void *)(except_delay_s),
+                        512, prio, 20);
+    if ( ! tid)
+    {
+         LOG_E("create syswatch test thread failed.");
+         return;
+    }
+
+    rt_thread_startup(tid);
+}
+
+static void syswatch_test(int argc, char **argv)
+{
+    rt_uint8_t prio = 0;
+    rt_uint32_t delay_s = 0;
+
+    if(argc < 2)
+    {
+        rt_kprintf("Usage: syswatch_test <priority 0-%d> [delay_s]\n", RT_THREAD_PRIORITY_MAX-2);
+        return ;
+    }
+    prio = atoi(argv[1]);
+    if (prio > RT_THREAD_PRIORITY_MAX-2)
+    {
+        prio = RT_THREAD_PRIORITY_MAX-2;
+    }
+    if (argc == 3)
+    {
+        delay_s = atoi(argv[2]);
+    }
+    syswatch_test_startup(prio, delay_s);
+}
+MSH_CMD_EXPORT(syswatch_test, system watch test);
+ 
+#endif //SYSWATCH_TEST_USING
+

+ 32 - 2
tmr/Ad.c

@@ -129,7 +129,10 @@ ulng get_weight(void)
         ad_sample=ad_sample_temp;
     // ad_sample_=ad_sample;
     //  ad_sample=(int)((float)ad_sample * 0.01 + (1.0 - 0.01) * (float)ad_sample);
-    ad_sample = AdFilter_xf(ad_sample);  //限幅滤波	 FLT_XF_CNT=32;
+   // ad_sample = AdFilter_xf(ad_sample);  //限幅滤波	 FLT_XF_CNT=32;
+		ad_sample = middleFilter(ad_sample);
+		
+		
 		tempvalw = ad_sample;
 		
 		switch(fs[1])
@@ -160,7 +163,7 @@ ulng get_weight(void)
 				break;
 		}	  
 	
-		ad_sample = AdFilter(ad_sample);     //滑动滤波	  FLT_CNT=32;		
+		//ad_sample = AdFilter(ad_sample);     //滑动滤波	  FLT_CNT=32;		
 						
 		if (tempWeighttime<100){	
 			tempWeighttime ++;	
@@ -677,6 +680,33 @@ ulng Kalman_Filter(const double ResrcData, double ProcessNiose_Q,double MeasureN
     return x_now;
 }
 
+
+ulng middleFilterdata[128];
+ulng middleFilter(ulng x)
+{
+	ulng i;
+	ulng j;
+	ulng temp;
+	for (j = 0; j < 31-1; j++)
+	  middleFilterdata[j] = middleFilterdata[j+1];
+	middleFilterdata[31] = x;
+	
+	for (j = 0; j < 31-1; j++)
+	{
+		for (i = 0; i < 31-j; i++)
+		{
+			if (middleFilterdata[i] > middleFilterdata[i+1])
+			{
+				temp = middleFilterdata[i];
+				middleFilterdata[i] = middleFilterdata[i+1];
+				middleFilterdata[i+1] = temp;
+			}
+		}
+	}
+	
+	return middleFilterdata[floor((FLT_CNT-1)/2)];
+} 
+
 /****************************/
 ulng AdFilter(ulng x)
 {

+ 1 - 0
tmr/Ad.h

@@ -109,6 +109,7 @@ extern void fullcalculate(void);
 
 extern ulng AdFilter(ulng x);
 extern ulng AdFilter_xf(ulng x);
+extern ulng middleFilter(ulng x);
 extern ulng Kalman_Filter(const double ResrcData, double ProcessNiose_Q,double MeasureNoise_R);
 extern ulng EX_QR_Filter(ulng x);//函数说明,在应用文件中说明为外部函数
 

+ 153 - 12
tmr/buffer.c

@@ -77,7 +77,43 @@ unsigned char ccsend = 0;
 extern unsigned char  iscowweight;
 		
 unsigned char readyPop = 0;			
-static unsigned char XbeeConst_FRxBuf12[100];        //处理完整无线临时表																							 
+static unsigned char XbeeConst_FRxBuf12[100];        //处理完整无线临时表					
+
+
+unsigned char* BleApp2MakeFrame(unsigned short dist,unsigned char cmd,unsigned char type,unsigned char* buf)//返回一个处理完成后的数组的首地址
+{
+    unsigned char len = buf[0];
+	  unsigned char BLEMakeFrame[100];//makeFrame保存转义完成后的数据
+    unsigned char l;
+    unsigned char xLen = 1;//处理后的数组长度,放在数组的第一位
+
+    BLEMakeFrame[xLen++] = 0x41;
+    BLEMakeFrame[xLen++] = 0x54;
+    BLEMakeFrame[xLen++] = 0x2b;
+    BLEMakeFrame[xLen++] = 0x4d;
+    BLEMakeFrame[xLen++] = 0x45;
+    BLEMakeFrame[xLen++] = 0x53;
+    BLEMakeFrame[xLen++] = 0x48;
+    BLEMakeFrame[xLen++] = cmd;
+    BLEMakeFrame[xLen++] = (dist>>8)&0xFF;
+    BLEMakeFrame[xLen++] = dist&0xFF;
+	  if (type==0)
+		{			
+			BLEMakeFrame[xLen++] = type;	
+			for(l = 4; l < 15; l++)	BLEMakeFrame[xLen++] = buf[l];
+		}
+		else{	
+      BLEMakeFrame[xLen++] = type;			
+			for(l = 4; l < 7; l++) BLEMakeFrame[xLen++] = buf[l];
+			for(l = 15; l < 23; l++)	BLEMakeFrame[xLen++] = buf[l];
+		}
+    BLEMakeFrame[xLen++] = 0x0D;
+    BLEMakeFrame[xLen++] = 0x0A;
+    BLEMakeFrame[0] = xLen - 1;
+    return BLEMakeFrame;//返回最终数组
+}
+
+
 void RB_init(void)
 {
     rb_usart1 = &usart1_buf;
@@ -239,6 +275,7 @@ void RX_API(void) {
 }
 
 static unsigned char planreget_save,planreget = 0;
+static uint8_t foundlastplan_ ; 
 void RX(void) {
     unsigned char tempval, checksum = 0;
 
@@ -268,7 +305,7 @@ void RX(void) {
                 if ((0xff - checksum) == XbeeConst_FRxBuf0[XbeeConst_FrameLength0])  //校验成功
                 {
 									  rt_strncpy(dataframehead.Buffer, XbeeConst_FRxBuf0, 4);
-                    if ((dataframehead.data.addr&0x0F) == XbeeConst_DeviceAddress || dataframehead.data.addr == 0xFF) { //收到本设备的数据,不是本设备的不处理
+                    if ((dataframehead.data.addr&0x1F) == XbeeConst_DeviceAddress || dataframehead.data.addr == 0xFF) { //收到本设备的数据,不是本设备的不处理
                         if (dataframehead.data.frameType == 0x10) {   //实时重量
                             if (XbeeConst_FRxBuf0[XbeeConst_FrameLength0-1] == XbeeConst_FrameNumLast) {
 															  save_read_ts('w');	
@@ -325,20 +362,20 @@ void RX(void) {
 																		rt_sem_release(pop_product_sem);//需要弹出最新内容																		
 																}			
 																if (planreget_save==0 && planreget==1){																  
-																	 XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-2] = XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-2] || 0x01;
+																	 XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-2] = XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-2] | 0x01;
 																}
 																planreget_save =1; 
 																
-																uint8_t foundlastplan_ = 0xF0;
+																foundlastplan_ = 0xF0;
 																foundlastplan_ = findlastplan();
-																if (XbeeConst_lastsort != XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1] 
+																if ((XbeeConst_lastsort != XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1] 
 																	    && foundlastplan_ != XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1])
+																      || XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1]>0xFD)
 																		ts_pushArrary(&ts_plandb, XbeeConst_FRxBuf0, XbeeConst_FRxBuf0[1]+2); 
 																save_read_ts('k');																
 																XbeeConst_CanSend=0x01;//取消无线发送锁定	
 																
-																if (XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1]<0xFD && getPlaning==0) { //如果没有结束,则发送05协议			
-																															
+																if (XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1]<0xFD && getPlaning==0) { //如果没有结束,则发送05协议																																		
 																			XbeeConst_lastsort = XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-1];
 																			XbeeConst_lastinorout = XbeeConst_FRxBuf0[XbeeConst_FRxBuf0[1]-3]>>7;
 //															    		rt_kprintf("XbeeConst_lastsort get:%02X \n", XbeeConst_lastsort);				
@@ -356,7 +393,7 @@ void RX(void) {
                             RemoteSendDisplay = 0;
 
                             if (isCC)
-                                checksum =0x7E + 0x05 +  ((XbeeConst_FRxBuf0_Remote[2] & 0x0F) << 4 ) || XbeeConst_DeviceAddress
+                                checksum =0x7E + 0x05 +  ((XbeeConst_FRxBuf0_Remote[2] & 0x0F) << 4 ) | XbeeConst_DeviceAddress
                                           + 0xA4 + XbeeConst_FRxBuf0[4] + XbeeConst_FRxBuf0[5];
                             else
                                 checksum =0x7E + 0x05 + XbeeConst_DeviceAddress + 0xA4 + XbeeConst_FRxBuf0[4] + XbeeConst_FRxBuf0[5];
@@ -520,9 +557,9 @@ void RX_Remote(void) {
                 if ((0xff - checksum) == XbeeConst_FRxBuf0_Remote[XbeeConst_FrameLength0_Remote])  //校验成功
                 {
                     if (
-                        (((XbeeConst_FRxBuf0_Remote[2] & 0x0F) == XbeeConst_RemoteAddress && (WeightConst_SBType == 2 || WeightConst_SBType == 7))
+                        (((XbeeConst_FRxBuf0_Remote[2] & 0x1F) == XbeeConst_RemoteAddress && (WeightConst_SBType == 2 || WeightConst_SBType == 7))
                          ||
-                         ((XbeeConst_FRxBuf0_Remote[2] & 0x0F) == XbeeConst_DeviceAddress && (WeightConst_SBType != 2 && WeightConst_SBType != 7)))
+                         ((XbeeConst_FRxBuf0_Remote[2] & 0x1F) == XbeeConst_DeviceAddress && (WeightConst_SBType != 2 && WeightConst_SBType != 7)))
                         ||
                         (XbeeConst_RemoteAddress==0 && XbeeConst_FRxBuf0_Remote[2]==0x0A)) { //收到本设备的数据,不是本设备的不处理
                         if ((XbeeConst_FRxBuf0_Remote[3] == 0xA1 && (WeightConst_SBType == 2 || WeightConst_SBType == 7) )
@@ -609,7 +646,7 @@ void RX_Remote(void) {
                             XbeeConst_FRemoteTxBuf[1] = 0x7E;
                             XbeeConst_FRemoteTxBuf[2] = 0x05;
                             if (isCC)
-                                XbeeConst_FRemoteTxBuf[3] = ((XbeeConst_FRxBuf0_Remote[2] & 0x0F) << 4 ) | XbeeConst_DeviceAddress;
+                                XbeeConst_FRemoteTxBuf[3] = ((XbeeConst_FRxBuf0_Remote[2] & 0x0F) << 5 ) | (XbeeConst_DeviceAddress&0x1F);
                             else
                                 XbeeConst_FRemoteTxBuf[3] = XbeeConst_DeviceAddress;
                             XbeeConst_FRemoteTxBuf[4] = 0xA4;
@@ -703,10 +740,110 @@ void RX_Remote(void) {
     }
 }
 
+
+static unsigned char Rec_watchTag[50];  //接收标签
+unsigned char Rec_watchTag_point=0;  //接收标签
+unsigned char ReadTag_state=0;   //读标签状态  0  没读或已读成功,1  开始读 ,2  正在读
+unsigned char WriteTag_state=0;  //写标签状态  0  没写或已写成功,1  开始写 ,2  正在写
+
+void ReadTag(unsigned char x) {  //发送标签
+	unsigned char sendchar;
+	sendchar=0x7E;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=0x03;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=XbeeConst_DeviceAddress;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=0xB2;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=x;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar = 0x7E + 03 + XbeeConst_DeviceAddress + 0xB2 + x;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	if (x==1) ReadTag_state=1;
+	else ReadTag_state=0;
+}
+
+void WriteTag(void) {  //发送标签
+	unsigned char sendchar;
+	sendchar=0x7E;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=0x0A;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=XbeeConst_DeviceAddress;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar=0xB1;
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	sendchar = 0x7E + 0x0A + XbeeConst_DeviceAddress + 0xB1;
+	for (int i = 0; i < 8; i++)	{
+		sendchar = sendchar + WeightConst_feed[i]; 
+		HAL_UART_Transmit(&huart5, (uint8_t *)&WeightConst_feed[i], 1, 1);
+	}
+	HAL_UART_Transmit(&huart5, (uint8_t *)&sendchar, 1, 1);
+	WriteTag_state = 1;
+}
+
+void watchTag(){
+	unsigned char tempval, checksum = 0;
+	tempval = rb_remove(rb_uart5);
+	//HAL_UART_Transmit(&huart5, &tempval, 1,1);		
+	if (tempval==0x7e || Rec_watchTag_point>49){   //头 过长回头
+		Rec_watchTag_point=0;
+	}
+	Rec_watchTag[Rec_watchTag_point++] = tempval;
+	if (Rec_watchTag_point>1 && Rec_watchTag_point>(Rec_watchTag[1]+2) ){  //符合长度
+		Rec_watchTag_point=0;		
+		for (int i = 0; i < Rec_watchTag[1]+2; i++)	
+		{
+			checksum = checksum + Rec_watchTag[i]; 
+			if (checksum== Rec_watchTag[Rec_watchTag[1]+2] && Rec_watchTag[2]==XbeeConst_DeviceAddress)
+			{//校验通过
+				 if (Rec_watchTag[3]==0xB2)
+				 {
+					 if (Rec_watchTag[1]==2 && ReadTag_state==1)
+						 {  //收到唤醒回复
+						  ReadTag_state=2;
+					 }else if (ReadTag_state==2){//收到标签
+						  ReadTag_state=0;
+						  for (int j = 0; j < 8; j++) {
+                if (WeightConst_feed[j] != Rec_watchTag[4+j]) ReadTag_state=2;
+              }
+						  if (ReadTag_state ==0 && pf_comp.data.needBegin==1 && WeightConst_WeightHaveBegin==0)
+              {
+								beep();
+								WeightConst_WeightBegin = WeightConst_WeightCur;
+								//	FLKey_SaveQPOrder(pf_comp.data.pfsort);
+								rt_sem_take(setTIME_lock, RT_WAITING_FOREVER);
+								write_Flash("begintime", &TimeConst, sizeof(TimeConst));
+								rt_sem_release(setTIME_lock);							
+								write_Flash("beginweight", &WeightConst_WeightBegin, sizeof(WeightConst_WeightBegin)); 
+								getTargetWeight();
+								ReadTag(0);//关闭唤醒
+              }
+						  beep();					
+					 }
+				 }
+				 else if (Rec_watchTag[3]==0xB1 && WriteTag_state>0){
+					 if (Rec_watchTag[1]==2){  //收到写入回复
+							WriteTag_state=2;
+					 }else if(WriteTag_state==2){//写入成功
+						  beep();
+						  ReadTag(1);//kai唤醒
+					 }
+				 }
+			}
+	  }
+	}
+}
+
+
+	
+extern uint8_t rDataBuffer;
 static void threadEmptyBuffer_entry(void *parameter)
 {
 		unsigned char tempval;
-	
+	  if (isTag > 0 )
+  	  HAL_UART_Receive_IT(&huart5, &rDataBuffer, 1); 
 		while(1)
 		{
 			 rt_sem_take(thread_EmptyBuffer_sem, RT_WAITING_FOREVER);   //等待串口消息
@@ -748,6 +885,10 @@ static void threadEmptyBuffer_entry(void *parameter)
 				 tempval = rb_remove(rb_uart4);  //继续存数据
          //if (tempval==0x59 && finish_send==0) finish_send=1;
 			 }
+
+			 while (rb_full_count(rb_uart5) > 0) {
+				 watchTag();
+			 }
 		}
 }
 

+ 9 - 0
tmr/buffer.h

@@ -16,6 +16,13 @@ extern uint8_t flag_uart4_send;
 extern ring_buffer *SendWeightQueue,*XbeeQueue,*XbeeAPIQueue,*RemoteQueue;
 extern ring_buffer *RecWeightQueue;
 
+extern unsigned char Rec_watchTag_point;  //接收标签
+extern unsigned char ReadTag_state;   //读标签状态  0  没读或已读成功,1  开始读 ,2  正在读
+extern unsigned char WriteTag_state;  //写标签状态  0  没写或已写成功,1  开始写 ,2  正在写
+extern void WriteTag(void);
+extern void ReadTag(unsigned char x);
+
+
 extern uint8_t XbeeConst_CenterAddress[8];  //开始地址 0xFF
 extern uint8_t XbeeConst_CCAddress[8];      //开始地址 0xFF    
 extern uint8_t XbeeConst_RemoteAddress;
@@ -40,4 +47,6 @@ extern rt_sem_t uart5_lock;
 extern void USART_Push(unsigned char address, unsigned char data);
 extern void RB_init(void);
 extern void threadUart_init(void);
+extern unsigned char* BleApp2MakeFrame(unsigned short dist,unsigned char cmd,unsigned char type,unsigned char* buf);//返回一个处理完成后的数组的首地址
+extern void threadUart5_init(void);
 #endif

+ 88 - 31
tmr/button.c

@@ -1,4 +1,5 @@
 #include <rtthread.h>
+#include "rtc.h"
 #include "flash.h"
 #include "main.h"
 #include "ad.h"
@@ -19,7 +20,7 @@ uint8_t WeightConst_ZD_ = 8;          //
 
 uint8_t CanButton=0;
 
-struct button_state_t button_state = {0,0,0,0,0};
+struct button_state_t button_state = {1,1,1,1,1,1,1};
 
 //static rt_uint8_t MenuItem__=0; //当前菜单值序号
 
@@ -34,6 +35,7 @@ void sendshowCC(void)
     XbeeConst_FRemoteTxBuf[4] = 0xB2;
     XbeeConst_FRemoteTxBuf[5] = XbeeConst_UseAPI;
     XbeeConst_FRemoteTxBuf[6] = XbeeConst_FrameNum++;
+		HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, XbeeConst_FRemoteTxBuf[6]);
     XbeeConst_FRemoteTxBuf[XbeeConst_FRemoteTxBuf[0]] = 0;
     for (int i = 1; i < XbeeConst_FRemoteTxBuf[0]; i++) {
         XbeeConst_FRemoteTxBuf[XbeeConst_FRemoteTxBuf[0]] =
@@ -51,6 +53,7 @@ void sendshowCC(void)
 }
 
 static void CheckMenuButton_entry(void *parameter) {
+	extern uint8_t isBLE;
 	while(1)
 	{
 		if (button_state.b1>0)	button_state.b1 ++;
@@ -58,14 +61,23 @@ static void CheckMenuButton_entry(void *parameter) {
 		if (button_state.b3>0)	button_state.b3 ++;
 		if (button_state.b4>0)	button_state.b4 ++;
 		if (button_state.b5>0)	button_state.b5 ++;
-
+    if (button_state.b7>0)	button_state.b7 ++;
+		
 		if (button_state.b1>=5)	button_state.b1 = 0;
 		if (button_state.b2>=5)	button_state.b2 = 0;
 		if (button_state.b3>=5)	button_state.b3 = 0;
 		if (button_state.b4>=5)	button_state.b4 = 0;
 		if (button_state.b5>=5)	button_state.b5 = 0;
-
-
+		if (button_state.b7>=15)	button_state.b7 = 0;
+
+//    if (HAL_GPIO_ReadPin(pwr_GPIO_Port, pwr_Pin) == 0) {
+//			rt_thread_mdelay(2000);
+//			if ((HAL_GPIO_ReadPin(pwr_GPIO_Port, pwr_Pin) == 0) ) {
+//				beep();
+//				pwr_lock_off();
+//			}
+//    }
+		
 		//  if (WeightConst_TQ==14)  ad_sample=Ad_Sample1();//get_weight();
 		if (WeightConst_SBType<5)
 		{
@@ -73,7 +85,7 @@ static void CheckMenuButton_entry(void *parameter) {
 						beep();
 						if (MenuItem==0)
 						{
-								if (XbeeConst_DeviceAddress>1)  XbeeConst_DeviceAddress--; else  XbeeConst_DeviceAddress = 10;
+								if (XbeeConst_DeviceAddress>1)  XbeeConst_DeviceAddress--; else  XbeeConst_DeviceAddress = 30;
 								write_Flash("CH", &XbeeConst_DeviceAddress, sizeof(XbeeConst_DeviceAddress));							
 							  WeightConst_Weight_display[6] = XbeeConst_DeviceAddress + 0x30;
 						}
@@ -99,12 +111,12 @@ static void CheckMenuButton_entry(void *parameter) {
 						}
 						else if (MenuItem==4)
 						{
-								if (WeightConst_ChanCheShu>1) WeightConst_ChanCheShu--;  else WeightConst_ChanCheShu=10;
+								if (WeightConst_ChanCheShu>1) WeightConst_ChanCheShu--;  else WeightConst_ChanCheShu=30;
 								write_Flash("CC", &WeightConst_ChanCheShu, sizeof(WeightConst_ChanCheShu));
 						}
 						else if (MenuItem==5)
 						{
-								if (XbeeConst_UseAPI>0) XbeeConst_UseAPI--; else XbeeConst_UseAPI=3;
+								if (XbeeConst_UseAPI>0) XbeeConst_UseAPI--; else {XbeeConst_UseAPI=3; if(isBLE>0) XbeeConst_UseAPI=5;}
 								setAPI();
 								write_Flash("API", &XbeeConst_UseAPI, sizeof(XbeeConst_UseAPI));                   
 						}
@@ -158,7 +170,7 @@ static void CheckMenuButton_entry(void *parameter) {
 						beep();
 						if (MenuItem==0)
 						{
-								if (XbeeConst_DeviceAddress<10)	XbeeConst_DeviceAddress++; else XbeeConst_DeviceAddress = 1 ;
+								if (XbeeConst_DeviceAddress<30)	XbeeConst_DeviceAddress++; else XbeeConst_DeviceAddress = 1 ;
 								write_Flash("CH", &XbeeConst_DeviceAddress, sizeof(XbeeConst_DeviceAddress));
 						}
 						else if (MenuItem==1)
@@ -187,7 +199,7 @@ static void CheckMenuButton_entry(void *parameter) {
 						}
 						else if (MenuItem==4)
 						{
-								if (WeightConst_ChanCheShu<10)	WeightConst_ChanCheShu++;
+								if (WeightConst_ChanCheShu<30)	WeightConst_ChanCheShu++;
 								else	WeightConst_ChanCheShu=1;
 								write_Flash("CC", &WeightConst_ChanCheShu, sizeof(WeightConst_ChanCheShu));
 
@@ -195,7 +207,7 @@ static void CheckMenuButton_entry(void *parameter) {
 						}
 						else if (MenuItem==5)
 						{
-								if (XbeeConst_UseAPI<3)	XbeeConst_UseAPI++;	else	XbeeConst_UseAPI=0;
+								if ((XbeeConst_UseAPI<3 && isBLE==0) || (XbeeConst_UseAPI<5 && isBLE>0))	XbeeConst_UseAPI++;	else	XbeeConst_UseAPI=0;
 								setAPI();
 								write_Flash("API", &XbeeConst_UseAPI, sizeof(XbeeConst_UseAPI));       
 						}
@@ -351,6 +363,17 @@ void alarm_on(void)
 	HAL_GPIO_WritePin(alarm_GPIO_Port, alarm_Pin, GPIO_PIN_SET);
 }
 
+void pwr_lock_off(void)
+{
+	HAL_GPIO_WritePin(GPIOC, pwr_lock_Pin, GPIO_PIN_RESET);
+}
+
+void pwr_lock_on(void)
+{
+	HAL_GPIO_WritePin(GPIOC, pwr_lock_Pin, GPIO_PIN_SET);
+}
+
+
 void output1_off(void)
 {
 	HAL_GPIO_WritePin(output1_GPIO_Port, output1_Pin, GPIO_PIN_SET);
@@ -370,6 +393,17 @@ void output2_on(void)
 {
 	HAL_GPIO_WritePin(output2_GPIO_Port, output2_Pin, GPIO_PIN_RESET);
 }
+
+void AT_off(void)
+{
+	HAL_GPIO_WritePin(ble_c_GPIO_Port, ble_c_Pin, GPIO_PIN_SET);
+}
+
+void AT_on(void)
+{
+	HAL_GPIO_WritePin(ble_c_GPIO_Port, ble_c_Pin, GPIO_PIN_RESET);
+}
+
 void beep(void)
 {
 	rt_sem_release(thread_beep_sem); 
@@ -401,7 +435,7 @@ void thread_beep_init(void)
         rt_thread_startup(tid_beep);
 }
 
-
+extern uint8_t  isnewBan; 
 static unsigned int button4_press=0;
 static unsigned int button4_press_=0;
 static void CheckButton_entry(void *parameter) {
@@ -421,19 +455,32 @@ static void CheckButton_entry(void *parameter) {
 				if (button_state.b2>0)	button_state.b2 ++;
 				if (button_state.b3>0)	button_state.b3 ++;
 				if (button_state.b4>0)	button_state.b4 ++;
+				if (button_state.b7>0)	button_state.b7 ++;
 
 				if (button_state.b1>=15)	button_state.b1 = 0;
 				if (button_state.b2>=15)	button_state.b2 = 0;
 				if (button_state.b3>=5)	button_state.b3 = 0;
 				if (button_state.b4>=5)	button_state.b4 = 0;
-
+				
+				if (button_state.b7>=15)	button_state.b7 = 0;
+				if (WeightConst_SBType == 3 && isnewBan==1)
+				{					
+					if ((HAL_GPIO_ReadPin(pwr_GPIO_Port, pwr_Pin) == 0) ) {
+						rt_thread_mdelay(2000);
+						if ((HAL_GPIO_ReadPin(pwr_GPIO_Port, pwr_Pin) == 0) ) {
+							beep();
+							pwr_lock_off();
+						}
+					}
+		  	}
+				
         if ((HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) > 0) && button_state.b1 == 0 && CanButton==1 && iscowweight==0)	{
             if (WeightConst_SBType != 2 && WeightConst_SBType != 7) {
                 if (pf_comp.data.pfsort!=0xFE) {
-                    if (WeightConst_DELAYON>0)
+                    if (WeightConst_DELAYON>0)   
                     {
-                      //  beep();
-                      //  WeightConst_DELAYTIME = (pf_comp.data.delaytime*60)+1;
+                      //  beep(); 
+                      //  WeightConst_DELAYTIME = (pf_comp.data.delaytime*60)+1;    //允许按键跳过搅拌延时
                     }
                     else if (pf_comp.data.needBegin==1 && WeightConst_WeightHaveBegin==0)
                     {
@@ -464,15 +511,16 @@ static void CheckButton_entry(void *parameter) {
                 XbeeConst_FRemoteTxBuf[1] = 0x7E;
                 XbeeConst_FRemoteTxBuf[2] = 0x05;
                 if (isCC)
-                    XbeeConst_FRemoteTxBuf[3] = ((XbeeConst_DeviceAddress&0x0F) << 4 ) |(XbeeConst_RemoteAddress&0xf);
+                    XbeeConst_FRemoteTxBuf[3] = ((XbeeConst_DeviceAddress&0x0F) << 5 ) |(XbeeConst_RemoteAddress&0x1f);
                 else
-                    XbeeConst_FRemoteTxBuf[3] = XbeeConst_RemoteAddress&0xf;
+                    XbeeConst_FRemoteTxBuf[3] = XbeeConst_RemoteAddress&0x1f;
                 if (XbeeConst_UseAPI==1||XbeeConst_UseAPI==3)
                     XbeeConst_FRemoteTxBuf[4] = 0xA2;
                 else
                     XbeeConst_FRemoteTxBuf[4] = 0x14;
                 XbeeConst_FRemoteTxBuf[5] = 0x01;
-                XbeeConst_FRemoteTxBuf[6] = XbeeConst_FrameNum++;;
+                XbeeConst_FRemoteTxBuf[6] = XbeeConst_FrameNum++;
+								HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, XbeeConst_FRemoteTxBuf[6]);
                 XbeeConst_FRemoteTxBuf[XbeeConst_FRemoteTxBuf[0]] = 0;
                 for (int i = 1; i < XbeeConst_FRemoteTxBuf[0]; i++) {
                     XbeeConst_FRemoteTxBuf[XbeeConst_FRemoteTxBuf[0]] =
@@ -490,7 +538,7 @@ static void CheckButton_entry(void *parameter) {
 										rt_sem_release(uart2_lock);
                 }
                 else	{	 
-									 if (iscowweight<1 )
+									 if (iscowweight<1)
 									 {
 											rt_sem_take(uart3_lock, RT_WAITING_FOREVER);
 											for (int i = 1; i <= XbeeConst_FRemoteTxBuf[0]; i++) //将缓冲区发出
@@ -504,6 +552,7 @@ static void CheckButton_entry(void *parameter) {
 						button_state.b2 = 0;
 						button_state.b3 = 0;
 						button_state.b4 = 0;
+						button_state.b7 = 0;
         }
 
         if ((HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin) > 0) && button_state.b2 == 0 && CanButton==1 && iscowweight==0) {
@@ -522,9 +571,9 @@ static void CheckButton_entry(void *parameter) {
                 XbeeConst_FRemoteTxBuf[1] = 0x7E;
                 XbeeConst_FRemoteTxBuf[2] = 0x05;
                 if (isCC)
-                    XbeeConst_FRemoteTxBuf[3] = ((XbeeConst_DeviceAddress&0x0F) << 4 ) | (XbeeConst_RemoteAddress&0xf);
+                    XbeeConst_FRemoteTxBuf[3] = ((XbeeConst_DeviceAddress&0x0F) << 5 ) | (XbeeConst_RemoteAddress&0x1f);
                 else
-                    XbeeConst_FRemoteTxBuf[3] = XbeeConst_RemoteAddress&0xf;
+                    XbeeConst_FRemoteTxBuf[3] = XbeeConst_RemoteAddress&0x1f;
 
                 if (XbeeConst_UseAPI==1||XbeeConst_UseAPI==3)
                     XbeeConst_FRemoteTxBuf[4] = 0xA2;
@@ -532,6 +581,7 @@ static void CheckButton_entry(void *parameter) {
                     XbeeConst_FRemoteTxBuf[4] = 0x14;
                 XbeeConst_FRemoteTxBuf[5] = 0x02;
                 XbeeConst_FRemoteTxBuf[6] = XbeeConst_FrameNum++;
+								HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, XbeeConst_FRemoteTxBuf[6]);
                 XbeeConst_FRemoteTxBuf[XbeeConst_FRemoteTxBuf[0]] = 0;
                 for (int i = 1; i < XbeeConst_FRemoteTxBuf[0]; i++) {
                     XbeeConst_FRemoteTxBuf[XbeeConst_FRemoteTxBuf[0]] =
@@ -563,6 +613,7 @@ static void CheckButton_entry(void *parameter) {
 						button_state.b2 = 1;
 						button_state.b3 = 0;
 						button_state.b4 = 0;
+						button_state.b7 = 0;
         }
 
         if ((HAL_GPIO_ReadPin(B3_GPIO_Port, B3_Pin) > 0) && button_state.b3 == 0) {
@@ -586,7 +637,7 @@ static void CheckButton_entry(void *parameter) {
 											if (button_state.b4>0) button4_press = button4_press + button4_press_;
 											else button4_press=1;
 									}
-									if(button4_press>1500){
+									if((button4_press>1500) || (iscowweight==1 && WeightConst_TQ==14)){
 										beep();
 										button4_press = 0;
 										setZero();
@@ -625,17 +676,19 @@ static void CheckButton_entry(void *parameter) {
 						button_state.b2 = 0;
 						button_state.b3 = 1;
 						button_state.b4 = 0;
+						button_state.b7 = 0;
         }
         if ((HAL_GPIO_ReadPin(B4_GPIO_Port, B4_Pin) > 0) && button_state.b4 == 0  && iscowweight==0) {
+					  WriteTag();					
             if (WeightConst_SBType != 2 && WeightConst_SBType != 7) {
-//							  if (isTag==1)
-//								{
-//									 if (WriteTag_state <2 && pf_comp.data.needBegin == 1 && WeightConst_WeightHaveBegin==0)
-//									 {
-//										 beep();
-//										 WriteTag();										 
-//									 }
-//								}
+							  if (isTag==1)
+								{
+									 //if (WriteTag_state <2 && pf_comp.data.needBegin == 1 && WeightConst_WeightHaveBegin==0)
+									 {
+										 beep();
+										 WriteTag();										 
+									 }
+								}
                 if (WeightConst_SBType==6)
                 {
                     if (WeightConst_remoteDisplay==0)
@@ -644,7 +697,9 @@ static void CheckButton_entry(void *parameter) {
                         WeightConst_remoteDisplay = 0;
                     beep();
                 }
-								
+								else {
+								  Planback();
+								}
             }
             else
             {
@@ -665,9 +720,11 @@ static void CheckButton_entry(void *parameter) {
 						button_state.b2 = 0;
 						button_state.b3 = 0;
 						button_state.b4 = 1;
+						button_state.b7 = 0;
         }
         else if (button_state.b4==0)
             button4_press = 0;
+							
 				rt_thread_mdelay(200);
     }
 }

+ 6 - 0
tmr/button.h

@@ -7,6 +7,8 @@ struct button_state_t {
 	  rt_uint8_t b3;
 	  rt_uint8_t b4;
 	  rt_uint8_t b5;
+	  rt_uint8_t b6;
+	  rt_uint8_t b7;
 };
 
 extern struct button_state_t button_state;
@@ -18,10 +20,14 @@ extern uint32_t Maxval;
 extern uint8_t CanButton;
 extern void alarm_off(void);
 extern void alarm_on(void);
+extern void pwr_lock_off(void);
+extern void pwr_lock_on(void);
 extern void output1_off(void);
 extern void output1_on(void);
 extern void output2_off(void);
 extern void output2_on(void);
+extern void AT_off(void);
+extern void AT_on(void);
 extern void beep(void);
 extern void MenuButtonthread(void);
 extern void Button_thread(void);

+ 52 - 0
tmr/daScreen.c

@@ -447,6 +447,58 @@ void display_KPT_TMRWatch_(void)
 		rt_thread_mdelay(50);
 }
 
+void display_KPT_TMRWatch_weight_()
+{
+	  signed long Weight_displayW;   //显示重量
+	  unsigned char i;
+//    unsigned char KPT_TMRWatch[0x24] = {0x20,0x20,0xBF,0xC6,0xC5,0xC8,0xCC,0xDA,
+//                                        0x54,0x4D,0x52,0x57,0x61,0x74,0x63,0x68,
+//                                        0x20,0x20,0xC8,0xAB,0xBB,0xEC,0xBA,0xCF,
+//                                        0xC8,0xD5,0xC1,0xB8,0xBC,0xE0,0xBF,0xD8,
+//                                        0xCF,0xB5,0xCD,0xB3
+//                                     };
+		 unsigned char KPT_TMRWatch[0x36] = {0x20,0x20,0xBF,0xC6,0xC5,0xC8,0xCC,0xDA,
+                                         0x54,0x4D,0x52,0x57,0x61,0x74,0x63,0x68,
+                                         0x20,0x20,
+			                                   0xC8,0xAB,0xBB,0xEC,0xBA,0xCF,0xC8,0xD5,
+			                                   0xC1,0xB8,0xBC,0xE0,0xBF,0xD8,0xCF,0xB5,
+			                                   0xCD,0xB3,
+			                                   0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+			                                   0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+			                                   0x20,0x20
+                                        };
+		i=47; 
+		Weight_displayW = abs(WeightConst_WeightCurTem);
+    if (Weight_displayW==0)
+    {
+        i--;
+        KPT_TMRWatch[i] = 0x30;
+    }
+    else
+        for(;;) {
+            if (Weight_displayW>0)
+            {
+                i--;
+                KPT_TMRWatch[i] = (Weight_displayW)%10 + '0';
+                Weight_displayW = Weight_displayW/10;
+            }
+            else break;
+        }
+    if (WeightConst_WeightCurTem<0) KPT_TMRWatch[40] = 0x2d;
+    display_New_(KPT_TMRWatch, 0x36,
+                 0,  // 是否清除
+                 1, // 区域数
+                 0x1A,  //区域x
+                 0x1E, //区域Y
+                 0x96, //区域宽
+                 0x34,//区域高
+                 0, //区域编号
+                 2, //行间隔
+                 2,//是否多行
+                 2);//是否换行    
+		rt_thread_mdelay(50);
+}
+
 
 extern unsigned short WeightConst_Product_Run_time; //开始运行时间
 void display_productName_(unsigned char x) //显示产品名称

+ 1 - 0
tmr/daScreen.h

@@ -16,6 +16,7 @@ extern void display_Current_(int weight);
 extern void display_Current_noweight_(void);
 extern void display_KPT_TMRWatch_(void);
 extern void display_KPT_TMRWatch(void);
+extern void display_KPT_TMRWatch_weight_();
 
 extern void display_Now(void);
 extern void display_Next(void);

+ 30 - 11
tmr/display.c

@@ -291,7 +291,7 @@ static void MenuDisplay_entry(void *parameter) {
 						display_Now_(WeightConst_WeightCurTem);
 				}
 		}
-	  HAL_IWDG_Refresh(&hiwdg);
+//	  HAL_IWDG_Refresh(&hiwdg);
 		rt_thread_mdelay(400);
 	}
 }
@@ -521,10 +521,9 @@ static void sendRemote(void *parameter)
 	{
     if (RemoteSendDisplay == 1 )
     {
-        if ((flag_uart2_send==0 && (XbeeConst_UseAPI==1 || XbeeConst_UseAPI==3))||
+        if ((flag_uart2_send==0 && (XbeeConst_UseAPI==1 || XbeeConst_UseAPI>=3))||
                 (flag_uart3_send==0 && XbeeConst_UseAPI==0))
         {
-
             if(remote_sumweight==1)	XbeeConst_FRemoteTxBuf[0] = 28;
             else 	XbeeConst_FRemoteTxBuf[0] = 23;				
             XbeeConst_FRemoteTxBuf[1] = 0x7E;
@@ -609,7 +608,23 @@ static void sendRemote(void *parameter)
 						    rt_thread_mdelay(XbeeConst_DeviceAddress*30);
 					//			rt_thread_mdelay(200);
             }
-            else
+            else  if (XbeeConst_UseAPI>3) {
+							  rt_sem_take(uart3_lock, RT_WAITING_FOREVER);	
+								AT_on();	
+								for(int xcount=0;xcount<2;xcount++){
+									XbeeConst_PRemoteTxBuf0 = BleApp2MakeFrame(0xFFFF, 0x00, xcount, XbeeConst_FRemoteTxBuf);
+
+									for (int SendWifi_i = 1; SendWifi_i <= XbeeConst_PRemoteTxBuf0[0]; SendWifi_i++)  //将缓冲区发出
+											usart3_send_data[SendWifi_i-1] = XbeeConst_PRemoteTxBuf0[SendWifi_i];								
+
+									HAL_UART_Transmit_DMA(&huart3, usart3_send_data, XbeeConst_PRemoteTxBuf0[0]);//xbeeSerial			
+									rt_thread_mdelay(100);			
+								}							
+							 					
+								AT_off();
+								rt_sem_release(uart3_lock);								
+						}
+						else
             {
 							if (iscowweight<1 )
 							{
@@ -624,7 +639,9 @@ static void sendRemote(void *parameter)
             }
         }
     }
+		 if (XbeeConst_UseAPI<4)
 		rt_thread_mdelay(500);
+		 else rt_thread_mdelay(250);
 	}
 }
 
@@ -705,7 +722,7 @@ static void Display_entry(void *parameter) {
 						rt_sem_take(uart4_lock, RT_WAITING_FOREVER);
 		        HAL_UART_Transmit_DMA(&huart4, uart4_send_data, 19);
 						rt_sem_release(uart4_lock);
-						HAL_IWDG_Refresh(&hiwdg);
+			//			HAL_IWDG_Refresh(&hiwdg);
 						rt_thread_mdelay(500);
         }
 				else if (WeightConst_SBType==4)
@@ -778,7 +795,7 @@ static void Display_entry(void *parameter) {
 										}
 								}						
 						}
-						if(WeightConst_Run || inMenu==1)
+					//	if(WeightConst_Run || inMenu==1)
 						{
 							if (isn>=1)
 							{
@@ -818,7 +835,7 @@ static void Display_entry(void *parameter) {
 						else{
 				        rt_thread_mdelay(300);
 						}
-					  HAL_IWDG_Refresh(&hiwdg);
+			//		  HAL_IWDG_Refresh(&hiwdg);
 				}
 				else if (WeightConst_SBType==3){// || WeightConst_SBType==7) {            
 						// if (WeightConst_Weight_display_old[SendDisplay_i] != WeightConst_Weight_display[SendDisplay_i])
@@ -1121,7 +1138,7 @@ static void Display_entry(void *parameter) {
 						
 						rt_thread_mdelay(300);
 
-						HAL_IWDG_Refresh(&hiwdg);
+			//			HAL_IWDG_Refresh(&hiwdg);
         }
 
 //        if (WeightConst_SBType==3 || WeightConst_SBType==7) {            
@@ -1164,7 +1181,7 @@ static void Display_entry(void *parameter) {
 //            SendRemote_timer = 0;
           
 //        }
-						 
+ 
 			}
 }
 
@@ -1172,11 +1189,13 @@ static void Display_clear_entry(void *parameter) {
 	  uint8_t i=0;
 
     while (i<10) {
+	  // while (WeightConst_Run<1) {
        if (WeightConst_Run<1){
 				 if (isn>=1) display_KPT_TMRWatch_();  
+				// if (isn>=1) display_KPT_TMRWatch_weight_(); 
 				 else display_KPT_TMRWatch(); 
 			 }   			
-			 rt_thread_mdelay(1*1000);
+			 rt_thread_mdelay(1000);
 			 i++;
 		}
 }
@@ -1217,7 +1236,7 @@ void threadRemoteDisplay_init(void)
 	  //thread_EmptyBuffer_sem = rt_sem_create("thread_EmptyBuffer_sem", 0, RT_IPC_FLAG_FIFO);
     remotedisplay_tid = rt_thread_create("RemoteD",
                             sendRemote, RT_NULL,
-                            0x100,
+                            0x300,
                             5, 5);
 
     /* 如果获得线程控制块,启动这个线程 */

+ 56 - 13
tmr/flash.c

@@ -1,14 +1,18 @@
 #include <flashdb.h>
 #include <rtthread.h>
 #include "plan.h"
+#include "rtc.h"
 #include "buffer.h"
 #include "button.h"
 #include "display.h"
 #include <string.h>
 
 uint8_t  isCC = 0 ;
+uint8_t  isBLE =0;  //用蓝牙传输
+uint8_t  isNsmall =0;  //新小屏
+uint8_t  isnewBan =0;  //隔离主板
 const uint8_t  isTag = 0 ; //是否含识读标签
-unsigned char  isn = 1;  //是否新大屏
+unsigned char  isn = 0;  //是否新大屏
 unsigned char  remote_sumweight = 0;  //远程是否包含重量
 unsigned char  iscowweight = 0;  //是否奶牛秤
 unsigned char eid[10];    //电子耳标,0为长度
@@ -16,10 +20,10 @@ unsigned char eid[10];    //
 uint8_t XbeeConst_DeviceAddress = 0x01;         
 uint8_t XbeeConst_NetAddress = 0x00;
 uint8_t XbeeConst_UseAPI = 0x01;
-uint8_t WeightConst_TQ = 0x07;//0x05;
+uint8_t WeightConst_TQ = 0x01;//0x05;
 uint8_t WeightConst_BLE = 0;
 uint8_t WeightConst_ChanCheShu = 0x02;
-uint8_t WeightConst_SBType = 0x03;
+uint8_t WeightConst_SBType = 0x01;
 
 
 int16_t WeightConst_WeightBegin = 0;    //按键开始重量
@@ -37,6 +41,8 @@ static uint32_t read_key = 1;
 static uint32_t read_plan = 1;
 static uint32_t read_weight = 1;
 
+//static uint16_t plan_lastframe = 0;
+
 static struct fdb_default_kv_node default_kv_table[] = {       
     {"CH",                &XbeeConst_DeviceAddress, sizeof(XbeeConst_DeviceAddress)},     //  1,    车号,    1字节
     {"TQ",                &WeightConst_TQ,          sizeof(WeightConst_TQ)},              //  2,    提取方式,1字节
@@ -162,12 +168,13 @@ uint32_t tsdb_recordcount(const char key)
 
 	
 static  uint8_t foundF8 = 0;
+
 static bool query_f8_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
 	  unsigned char buf[tsl->log_len];
     fdb_tsdb_t db = arg;
-	
 	  rt_memset(buf, 0, tsl->log_len);
     fdb_blob_read((fdb_db_t) db, fdb_tsl_to_blob(tsl, fdb_blob_make(&blob, &buf, tsl->log_len)));
     if ((buf[3]==0xf8 || buf[3]==0xE8) && tsl->status==FDB_TSL_WRITE)
@@ -175,6 +182,7 @@ static bool query_f8_cb(fdb_tsl_t tsl, void *arg)
 			foundF8 = 1;
 			return true;
 		}
+	}
 		return false;
 		//write_Flash("read_key", &ts_keyTime, sizeof(ts_keyTime)); 
 }
@@ -187,10 +195,12 @@ void findF8(void)
 static  uint8_t foundF4 = 0;
 static bool query_f4_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
+	
 	  unsigned char buf[tsl->log_len];
     fdb_tsdb_t db = arg;
-	
+	  
 	  rt_memset(buf, 0, tsl->log_len);
     fdb_blob_read((fdb_db_t) db, fdb_tsl_to_blob(tsl, fdb_blob_make(&blob, &buf, tsl->log_len)));
     if ((buf[3]==0xf4 || buf[3]==0xE4) && tsl->status==FDB_TSL_WRITE)
@@ -198,6 +208,7 @@ static bool query_f4_cb(fdb_tsl_t tsl, void *arg)
 			foundF4 = 1;
 			return true;
 		}
+	}
 		return false;
 		//write_Flash("read_key", &ts_keyTime, sizeof(ts_keyTime)); 
 }
@@ -209,6 +220,7 @@ void findF4(void)
 
 static bool query_f12_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
 	  unsigned char buf[tsl->log_len];
 	  unsigned char len = 0;
@@ -233,6 +245,7 @@ static bool query_f12_cb(fdb_tsl_t tsl, void *arg)
 				for (int i = 2; i < 6; i++) 
 						plan_comp.Buffer[i] = buf[buf[1]-5+i];   //产品名称		       			
 		}
+	}
 		return false;
 }
 
@@ -247,6 +260,7 @@ void findF12(void)
 static  uint32_t foundkey = 0;
 static bool query_key_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
 	  //unsigned char buf[tsl->log_len];
     fdb_tsdb_t db = arg;
@@ -260,16 +274,18 @@ static bool query_key_cb(fdb_tsl_t tsl, void *arg)
     if (tsl->status==FDB_TSL_WRITE)
 		{
 			foundkey = tsl->time;
-			read_key = foundkey;
+		//	
 			return true;
 		}
+	}
 		return false;
 }
 
-uint32_t findkey(void)
+uint32_t findkey(uint8_t i)
 {	 
 	 foundkey = 0xFFFFFFFF;
    fdb_tsl_iter_by_time(&ts_keydb, read_key, 0xFFFFFFFF, query_key_cb, &ts_keydb);
+	 if (i>0) read_key = foundkey;
 	 return foundkey;
 	//return 0xFFFFFFFF;
 }
@@ -280,11 +296,11 @@ void save_read_ts(const char key)
 	{
 		
 		if (key == 'k'){ 	
-        if (findkey()<0xFFFFFFFF){	
+        if (findkey(0)<0xFFFFFFFF){	
 					if(XbeeConst_FrameNumLast == XbeeConst_FTxBuf0[XbeeConst_FTxBuf0[0]-1]){
 						read_key++;			
 						write_Flash("read_key", &read_key, sizeof(read_key));			
-					}
+			   	}
 				}
 		}else if (key == 'p'){ 
 					read_plan++;
@@ -297,9 +313,21 @@ void save_read_ts(const char key)
 	}
 }
 
+
+
+void back_read_plan(void)
+{
+  if (read_plan>1)
+	{
+      read_plan = read_plan-2;
+		  save_read_ts('p');
+	}
+}
+
 static  uint32_t foundplan = 0;
 static bool query_plan_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
 	  //unsigned char buf[tsl->log_len];
     fdb_tsdb_t db = arg;
@@ -312,6 +340,7 @@ static bool query_plan_cb(fdb_tsl_t tsl, void *arg)
 			read_plan = tsl->time;
 			return true;
 		}
+	}
 		return false;
 }
 
@@ -320,25 +349,28 @@ uint32_t findplan(void)
 	 foundplan = 0;
 //	 rt_kprintf("read_plan findplan:%02X \n",read_plan);			
    fdb_tsl_iter_by_time(&ts_plandb, read_plan, 0xFFFFFFFF, query_plan_cb, &ts_plandb);
+
 	 return foundplan;
 }
 
 static  uint8_t foundlastplan = 0;
 static bool query_lastplan_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
 	  //unsigned char buf[tsl->log_len];
     fdb_tsdb_t db = arg;
-	  rt_memset(WeightConst_PlantempList, 0, tsl->log_len);
-    fdb_blob_read((fdb_db_t) db, fdb_tsl_to_blob(tsl, fdb_blob_make(&blob, &WeightConst_PlantempList, tsl->log_len)));
+	  rt_memset(WeightConst_PlanLastList, 0, tsl->log_len);
+    fdb_blob_read((fdb_db_t) db, fdb_tsl_to_blob(tsl, fdb_blob_make(&blob, &WeightConst_PlanLastList, tsl->log_len)));
 	
     if (tsl->status==FDB_TSL_WRITE)
 		{
-			if (WeightConst_PlantempList[3]==0x15)
-			  foundlastplan = WeightConst_PlantempList[WeightConst_PlantempList[1]-1];
+			if (WeightConst_PlanLastList[3]==0x15)
+			  foundlastplan = WeightConst_PlanLastList[WeightConst_PlanLastList[1]-1];
 			
 			return true;
 		}
+	}
 		return false;
 }
 
@@ -352,6 +384,7 @@ uint32_t findlastplan(void)
 static  uint32_t foundNextplan = 0;
 static bool query_Nextplan_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
     fdb_tsdb_t db = arg;
 	  uint8_t Nextfeedlength = 0;
@@ -373,6 +406,7 @@ static bool query_Nextplan_cb(fdb_tsl_t tsl, void *arg)
 			}
 			return true;
 		}
+	}
 		return false;
 }
 
@@ -388,6 +422,7 @@ static  uint32_t foundweight = 0;
 static  uint32_t read_weight_temp = 0;
 static bool query_weight_cb(fdb_tsl_t tsl, void *arg)
 {
+	if (tsl->status<10 && tsl->log_len<100) {
     struct fdb_blob blob;
 	  unsigned char buf[7];
     fdb_tsdb_t db = arg;
@@ -399,6 +434,8 @@ static bool query_weight_cb(fdb_tsl_t tsl, void *arg)
 		foundweight++;
 
 		return foundweight>3;
+	}
+	else return false;
 }
 
 uint32_t findweight(void)
@@ -416,6 +453,7 @@ uint32_t findweight(void)
 			 XbeeConst_FTxBuf0[3] = XbeeConst_DeviceAddress;
 			 XbeeConst_FTxBuf0[4] = 0xF0;
 			 XbeeConst_FTxBuf0[33] = XbeeConst_FrameNum ++;
+		   HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, XbeeConst_FTxBuf0[33]);
 			 for (int i=1; i< 34; i++)  CRCNum+=XbeeConst_FTxBuf0[i];
 			 XbeeConst_FTxBuf0[34] = 0xFF - CRCNum;
 		   read_weight = read_weight_temp;
@@ -447,6 +485,7 @@ uint8_t ts_pushArrary(fdb_tsdb_t db, uint8_t *buf, uint8_t length)
 		return 1;
 }
 
+extern uint8_t  isNsmall;
 void read_Flash(void)
 {
 		struct fdb_blob blob;
@@ -478,6 +517,10 @@ void read_Flash(void)
 	  fdb_kv_get_blob(&kvdb, "completeorder", fdb_blob_make(&blob, &CompleteTarget_order, sizeof(CompleteTarget_order)));
 		
 	  fdb_kv_get_blob(&kvdb, "TimeConst", fdb_blob_make(&blob, &TimeConst, sizeof(TimeConst)));
+		
+    if (isNsmall){
+			WeightConst_SBType = 3;
+		}
 }
 
 

+ 2 - 1
tmr/flash.h

@@ -32,7 +32,7 @@ extern uint32_t tsdb_recordcount(const char key);
 extern void write_Flash(const char *key, const void *value_buf, size_t buf_len);
 extern uint8_t ts_pushArrary(fdb_tsdb_t db, uint8_t *buf, uint8_t length);
 extern void findF8(void);
-extern uint32_t findkey(void);
+extern uint32_t findkey(uint8_t i);
 extern uint32_t findweight(void);
 extern uint32_t findplan(void);
 extern uint32_t findNextplan(void);
@@ -43,4 +43,5 @@ extern void onbordflash_init(void);
 extern void setNetAddress(void);		
 extern void setAPI(void);		
 extern void init_allflash(void);
+extern void back_read_plan(void);
 #endif

+ 56 - 22
tmr/plan.c

@@ -1,4 +1,5 @@
 #include <rtthread.h>
+#include "rtc.h"
 #include "main.h"
 #include "flash.h"
 #include "buffer.h"
@@ -25,6 +26,7 @@ unsigned char WeightConst_Run=0; //
 unsigned char WeightConst_Stop = 0;
 
 unsigned char WeightConst_PlantempList[40]; //计划临时表
+unsigned char WeightConst_PlanLastList[40]; //计划临时表
 unsigned char WeightConst_Nextfeed[40]; //临时表
 signed short WeightConst_NextWeightTarget;      //目标重量
 unsigned char WeightConst_feed[40]; //原料名称					
@@ -45,6 +47,7 @@ unsigned char XbeeConst_lastsort;        //
 unsigned char XbeeConst_lastinorout;        //保存刚刚收到的发料或加料
 unsigned char XbeeConst_FrameNum = 0;  //帧编号
 
+//__attribute__((zero_init))  uint8_t XbeeConst_FrameNum;//帧编号
 unsigned char XbeeConst_CanSend=1;
 unsigned char getPlaning=0;
 static unsigned char XbeeConst_needRetry=0;         //等待秒数
@@ -117,7 +120,7 @@ void setSendFrame_t(unsigned char Broadcast,unsigned char Radius,unsigned char T
 }
 
 rt_sem_t setTIME_lock = RT_NULL;
-
+uint16_t timex;
 static void setTIME_entry(void *parameter) {
     while (1) {  
 			//定义时间
@@ -159,8 +162,13 @@ static void setTIME_entry(void *parameter) {
            TimeConst.data.date ++;
         }
 		//		if (TimeConst.data.year==1)  sendgetTime();
+				
+				timex = (TimeConst.Buffer[1]<<8)|TimeConst.Buffer[0];
+        HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1, timex);	 
+				timex = (TimeConst.Buffer[3]<<8)|TimeConst.Buffer[2];
+				HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR2, timex);	
 				rt_sem_release(setTIME_lock);
-        rt_thread_mdelay(998);				
+        rt_thread_mdelay(1000);				
     }
 }
 
@@ -176,6 +184,7 @@ void setTIME_thread(void)
 
 extern unsigned char  iscowweight;
 void setWeightConst_initProduct(void) {
+	
 	  rt_memset(WeightConst_product,0x20,40);		
     rt_memset(WeightConst_feed,0x20,40);			
 		rt_memset(WeightConst_Nextfeed,0x20,40);	
@@ -246,6 +255,7 @@ void setWeightConst_initProduct(void) {
     pf_comp.data.autozone = 0; ;  //目标重量的允许跳转范围
     pf_comp.data.needBegin = 0;
     pf_comp.data.pfsort = 0xFE; //顺序
+		
     pf_comp.data.delaytime = 0;		
     pf_comp.data.JMP = 0;
 		
@@ -258,7 +268,13 @@ void setWeightConst_initProduct(void) {
 		}
 }
 
-
+void Planback(void) {  //回闪一条计划
+  if (pf_comp.data.pfsort>=1 && tsdb_recordcount('p')>0)
+	{
+     back_read_plan();
+		 rt_sem_release(pop_product_sem);//需要弹出最新内容
+	}
+}
 void pop_product_entry(void *parameter) {
 		while(1)
 		{
@@ -271,6 +287,7 @@ void pop_product_entry(void *parameter) {
 				}
 				
 				while(1){
+					if (WeightConst_DELAYON==0) {
 						WeightConst_WeightHaveBegin=0;
 						if (tsdb_recordcount('p')>0) {
 								findplan();
@@ -300,7 +317,8 @@ void pop_product_entry(void *parameter) {
 										for (int i = 2; i < 6; i++) {
 												plan_comp.Buffer[i] = WeightConst_PlantempList[setWeightConst_length-5+i];   //产品名称
 										}	
-										WeightConst_Product_Run_time = (plan_comp.data.incount<<8) || plan_comp.data.outcount;
+										WeightConst_Product_Run_time = (plan_comp.data.outcount<<8) | plan_comp.data.incount;
+										HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, WeightConst_Product_Run_time);
 										pf_comp.data.pfsort = 0xFD;
 										WeightConst_Stop = 0;
 										if (WeightConst_SBType>2 && WeightConst_SBType<7) {
@@ -331,6 +349,7 @@ void pop_product_entry(void *parameter) {
 
 										WeightConst_DELAYTIME = 0;
 										WeightConst_DELAYON = 0;
+										HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, WeightConst_DELAYON);	
 										CanButton = 0x01;
 										WeightConst_oksum=0;
 					          WeightConst_WeightOK = 0;
@@ -359,8 +378,9 @@ void pop_product_entry(void *parameter) {
 											reset_read_ts('p');
 										  //	setWeightConst_initProduct();
 										}
-//										if (pf_comp.data.needBegin == 1 && isTag==1 && WeightConst_WeightTarget_addorout==1)
-//											 ReadTag(1);                     
+										
+										if (pf_comp.data.needBegin == 1 && isTag==1 && pf_comp.data.addorout==1)
+											 ReadTag(1);                     
 										
 										if (WeightConst_SBType>2 && WeightConst_SBType<7) {
 				//                if (WeightConst_WeightTarget_order==0xFF && WeightConst_SBType==4)
@@ -384,7 +404,8 @@ void pop_product_entry(void *parameter) {
 								}	
 						}
 				
-					  rt_thread_mdelay(10);			
+					}
+					rt_thread_mdelay(10);			
 				}
 		}
 }
@@ -394,18 +415,22 @@ void sendgetTime(void) {  //
     // 1位起始位 + 1位长度 + 1位源地址 + 1位命令 + 1帧编号 + 1校验
     unsigned char buf[6] ;
     unsigned char CRCNum=0;
+	
+	  
     buf[0]= 0x7E;
     buf[1]= 0x04;
     buf[2]= XbeeConst_DeviceAddress;
 	
     buf[3]= 0xF8;
-    buf[4] = XbeeConst_FrameNum++;
+    buf[4] = ++XbeeConst_FrameNum;
+		HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, buf[4]);
+
     for (int i=0; i< 5; i++) CRCNum+=buf[i];
     buf[5] = 0xff - CRCNum;
 	  
 	  if(READ_BIT(RCC->CSR, RCC_CSR_IWDGRSTF) == RESET)  //看门狗重启不需要获取时间
     {	     
-       ts_pushArrary(&ts_keydb, buf, buf[1]+2); 
+      ts_pushArrary(&ts_keydb, buf, buf[1]+2); 
     }
     if (tsdb_recordcount('p') > 0)	{
 				findF12();
@@ -447,6 +472,7 @@ void sendkey2(int BtnType) {
     }
 
     buf[15] = XbeeConst_FrameNum ++;
+		HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, buf[15]);
 
     for (int i=0; i< 16; i++) CRCNum+=buf[i];
 
@@ -455,6 +481,8 @@ void sendkey2(int BtnType) {
 
     if (BtnType==0xF4) {
       //  WeightConst_Product_JS = 0;
+			  WeightConst_Product_Run_time = 0;
+				HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, WeightConst_Product_Run_time);	
 			  getPlaning = 1;
 				rt_sem_take(weight_lock, RT_WAITING_FOREVER);
         WeightConst_WeightBegin = WeightConst_WeightCur;
@@ -480,9 +508,9 @@ void sendkey1(int BtnType, int remote) {
     buf[0]= 0x7E;
     buf[1]= 0x0F;
     if (isCC)
-        buf[2]= ((remote<< 4) & 0x0f) | (XbeeConst_DeviceAddress& 0x0f);
+        buf[2]= ((remote<< 5) & 0x1f) | (XbeeConst_DeviceAddress& 0x1f);
     else
-        buf[2]= XbeeConst_DeviceAddress & 0x0f;
+        buf[2]= XbeeConst_DeviceAddress & 0x1f;
 
     buf[3]= BtnType;
     for (int i=9; i >0; i--) buf[i+3]= xBytes.Buffer[9-i];
@@ -490,6 +518,7 @@ void sendkey1(int BtnType, int remote) {
     buf[13]= pf_comp.data.pfsort;  //应该附上当前计划的当前料的顺序号
     buf[14]= 0x00;  //应该附上当前计划的当前料的顺序号
     buf[15] = XbeeConst_FrameNum ++;
+		HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, buf[15]);
     for (int i=0; i< 16; i++)
         CRCNum+=buf[i];
 
@@ -508,7 +537,7 @@ void sendkey1(int BtnType, int remote) {
     if (pf_comp.data.pfsort == 0xFE) {
 				rt_sem_take(display_lock, RT_WAITING_FOREVER);
         setWeightConst_initProduct();
-			  WeightConst_Product_Run_time=0;
+			  WeightConst_Product_Run_time=0;			  
 				rt_sem_release(display_lock);
     }
     else
@@ -529,7 +558,11 @@ void sendkey1(int BtnType, int remote) {
 					  rt_sem_release(pop_product_sem); //弹出最新内容
             WeightConst_DELAYON = 0;
         }
+				HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, WeightConst_DELAYON);	
+				HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR6, pf_comp.data.delaytime);	
+				
     }
+		HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, WeightConst_Product_Run_time);
 }
 
 
@@ -577,13 +610,13 @@ void getTargetWeight(void)
     WeightConst_oksum = 0;
     WeightConst_allsum = 0;
 
-//		if (isTag==1)
-//    {
-//              Rec_watchTag_point=0;  //接收标签
-//              ReadTag_state=0;   //读标签状态  0  没读或已读成功,1  开始读 ,2  正在读
-//              WriteTag_state=0;  //写标签状态  0  没写或已写成功,1  开始写 ,2  正在写  
-//    }
-//		
+		if (isTag==1)
+    {
+              Rec_watchTag_point=0;  //接收标签
+              ReadTag_state=0;   //读标签状态  0  没读或已读成功,1  开始读 ,2  正在读
+              WriteTag_state=0;  //写标签状态  0  没写或已写成功,1  开始写 ,2  正在写  
+    }
+		
 		if (WeightConst_SBType>2 && WeightConst_SBType<7) {
 			 rt_event_send(&display_event, EVENT_Stop);
 		}
@@ -641,9 +674,10 @@ void SendWifi_entry(void *parameter) {
 					XbeeConst_needRetry = 0;  //重置重发定时计数
 					XbeeConst_FrameNumLast = XbeeConst_FTxBuf0[XbeeConst_FTxBuf0[0]-1];
 			}
-			else	if (XbeeConst_CanSend==1 && tsdb_recordcount('k')>0) { //可以重发/队列大于0/开头是7e						
-				 if (findkey()<0xFFFFFFFF)
-						{
+			else	if (XbeeConst_CanSend==1 && tsdb_recordcount('k')>0) { //可以重发/队列大于0/开头是7e		
+
+				 if (findkey(1)<0xFFFFFFFF)
+						{					
 							XbeeConst_CanSend = 0; //锁定无线不可发送直至解锁
 							XbeeConst_needRetry = 0;  //重置重发定时计数
 							XbeeConst_FrameNumLast = XbeeConst_FTxBuf0[XbeeConst_FTxBuf0[0]-1];

+ 4 - 4
tmr/plan.h

@@ -143,8 +143,8 @@ union pf_comp_t
 				uint8_t pfsort:8;         // 操作ID  操作ID就是一个计划中的每一步的唯一标识,不同计划的操作ID可以相同,同一计划中的ID不可以相同
                                   // 有效范围是0-200,如果=0xFE,则本计划结束,如果=0xFF,则当天计划结束
 			
-				uint8_t frameid_l:4;      // 对应0x16帧编号
-				uint8_t frameid:4;			  // 本协议帧编号
+				uint8_t frameid:4;      // 本协议帧编号
+				uint8_t frameid_l:4;			  // 对应0x16帧编号
 			
 		}__attribute__((packed)) data;
 		uint8_t Buffer[5];
@@ -175,7 +175,7 @@ extern signed short WeightConst_WeightTargetAllowMin;  //目
 extern short WeightConst_WeightTargetAllowMax;  //目标重量的允许跳转范围
 
 extern unsigned char WeightConst_PlantempList[40]; //计划临时表
-
+extern unsigned char WeightConst_PlanLastList[40]; //计划临时表
 extern unsigned char XbeeConst_FrameNum;
 
 
@@ -213,6 +213,6 @@ extern void getTargetWeight(void);
 extern void pop_product_thread(void);
 extern void delay_key_thread(void);
 extern void setSendFrame_t(unsigned char Broadcast,unsigned char Radius,unsigned char TO);
-
+extern void Planback(void);
 extern union TimeConst_t TimeConst;
 #endif 

+ 54 - 12
tmr/weight.c

@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include "usart.h"
 #include "plan.h"
+#include "rtc.h"
 #include "weight.h"
 #include "ad.h"
 #include "display.h"
@@ -75,7 +76,8 @@ void weight_usart_Init(UART_HandleTypeDef* uartHandle)
 	{
 			if (WeightConst_TQ==1)
 			{
-				 uartHandle->Init.BaudRate = 115200;
+				 uartHandle->Init.BaudRate = 9600;
+			//	uartHandle->Init.StopBits    = UART_STOPBITS_2;	 //停止位1位		
 			}
 			else if (WeightConst_TQ==7)
 			{
@@ -195,6 +197,7 @@ void sendWeight() {
         for (int i=0; i <28; i++) buf[i+4]= rb_remove(RecWeightQueue);
 
         buf[32] = XbeeConst_FrameNum ++;
+			  HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, buf[32]);	
         for (int i=0; i< 33; i++)  CRCNum+=buf[i];
 
         buf[33]= 0xff - CRCNum;
@@ -219,6 +222,7 @@ void sendEIDWeight(unsigned char * eidbuf, signed short WeightCur) {
         buf[11]= (WeightCur>>8) &0xFF;
 			  buf[12]= WeightCur &0xFF;
         buf[13] = XbeeConst_FrameNum ++;
+			  HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, buf[13]);
         for (int i=0; i< 14; i++)  CRCNum+=buf[i];
 
         buf[14]= 0xff - CRCNum;
@@ -230,16 +234,21 @@ void sendEIDWeight(unsigned char * eidbuf, signed short WeightCur) {
 void CheckWeightthread(void) {
 
     while (1) {			
-			if (pf_comp.data.delaytime>0 && WeightConst_DELAYON>0)        //搅拌延时
+			if (WeightConst_DELAYON>0)        //搅拌延时
 			{
 					WeightConst_DELAYTIME ++;
+				  HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR5, WeightConst_DELAYTIME);	
 					if (WeightConst_DELAYTIME >  (pf_comp.data.delaytime * 60))  //10 &&pf_comp.data.delaytime>0 )
 					{
 							write_Flash("begintime", &TimeConst, sizeof(TimeConst));											
 //							WeightConst_WeightBegin = WeightConst_WeightCur;					
 //              write_Flash("beginweight", &WeightConst_WeightBegin, sizeof(WeightConst_WeightBegin)); 
-						//	pf_comp.data.delaytime = 0;
-						//	WeightConst_DELAYON = 0;
+							pf_comp.data.delaytime = 0;
+						  WeightConst_DELAYTIME = 0;
+						  WeightConst_DELAYON = 0;
+					  	HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, 0);	
+						  HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR5, 0);	
+						  HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR6, 0);	
 						  rt_sem_release(pop_product_sem);//弹出最新内容
 					}
 			}
@@ -351,11 +360,12 @@ void CheckWeightthread(void) {
 						rt_event_send(&display_event, EVENT_Next);
 				}
 						
-			  if (WeightConst_Product_Run_time < 65535 && WeightConst_Product_Run_time>0 && pf_comp.data.addorout==0)
-          WeightConst_Product_Run_time++;
-		  }
-			else WeightConst_Product_Run_time = 0;
-
+				if (WeightConst_Product_Run_time < 65535 && WeightConst_Product_Run_time>0 && pf_comp.data.addorout==0)
+						WeightConst_Product_Run_time++;		  
+			//	else 
+			//		WeightConst_Product_Run_time = 0;
+				HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, WeightConst_Product_Run_time);	
+			}
 			rt_thread_mdelay(998);
     }
 }
@@ -1450,7 +1460,7 @@ static void XK3190_A27E() {
                             WeightConst_WeightCurTem = WeightConst_WeightCurTem / 10;
                         }
                     }
-                    if (WeightConst_WeightWS == 0) WeightConst_WeightCurTem = WeightConst_WeightCurTem / 10;
+                    //if (WeightConst_WeightWS == 0) WeightConst_WeightCurTem = WeightConst_WeightCurTem / 10;
                 }
                 if (WeightConst_RecWeightData1[2] == 0x2D)
                     WeightConst_WeightCurTemZF = 1;
@@ -1632,7 +1642,40 @@ static void P_XDNZ_BC02() {
                 WeightConst_RecFlag1 = 0x00;
                 WeightConst_Drop = 1; //开始抛弃数据
                 WeightConst_RecWeightPoint1 = 0; //指针还原
-            } else
+								
+            }else if (WeightConst_RecWeightPoint1 >= 7  
+   
+                    && WeightConst_RecWeightData1[WeightConst_RecWeightPoint1-7]==0x02
+                    && WeightConst_RecWeightData1[WeightConst_RecWeightPoint1]==0x04){
+								WeightConst_WeightCurTem = 0;
+                WeightConst_WeightWS = 0;
+                WeightConst_Weight_ZWS = 0;
+								WeightConst_WeightCurTemZF=0;
+//1B 4F 6D 30 32 02 2D 31 33 32 30 36 04 1B 4F 61 40 40 41 40 40 45 04 1B 4F 75 30 36 04 1A 04
+                for (int ReadWeight_i = 0; ReadWeight_i < 6; ReadWeight_i++) {
+                    if (WeightConst_RecWeightData1[ReadWeight_i + 1] >= 0x30
+                            && WeightConst_RecWeightData1[ReadWeight_i + 1] <= 0x39)
+                    {
+                        WeightConst_WeightCurTem = WeightConst_WeightCurTem
+                                                   + (WeightConst_RecWeightData1[ReadWeight_i +1] -0x30) * mypow(10, 5 - ReadWeight_i); //计算重量,无小数位的
+                        WeightConst_Weight_ZWS++;
+                    }else if (WeightConst_RecWeightData1[ReadWeight_i + 1] == 0x2D)
+										{
+											WeightConst_WeightCurTemZF=1;                        
+										};
+                }
+
+                if (WeightConst_WeightCurTemZF>0) WeightConst_WeightCurTem = WeightConst_WeightCurTem * -1;
+
+                WeightConst_WeightWS = 0; //设置小数位数
+
+                setWeightSM();
+                WeightConst_RecFlag1 = 0x00;
+                WeightConst_Drop = 1; //开始抛弃数据
+                WeightConst_RecWeightPoint1 = 0; //指针还原	
+							
+						}
+						else
                 WeightConst_RecWeightPoint1++;
         }
         else WeightConst_RecWeightPoint1 = 0; //指针还原
@@ -1909,7 +1952,6 @@ void ReadWeightthread(void) {
 						WeightConst_WeightWS = ad_Point;
 						setWeightSM();	
 						rt_sem_release(display_lock);
-           						
 				}
 			  
 				rt_thread_mdelay(125);