Browse Source

add iap function

terry 2 years ago
parent
commit
6b744df145

+ 64 - 0
Core/Inc/Data_deal.h

@@ -0,0 +1,64 @@
+#ifndef __data_deal_H__
+#define __data_deal_H__
+
+
+#include "stdio.h"
+#include "string.h"
+#include "stdint.h"
+#include <ctype.h>  
+
+
+void StrToHex(uint8_t *pbDest, uint8_t *pbSrc, int nLen);														//字符串转成16进制数
+void HexToStr(uint8_t *pbDest, uint8_t *pbSrc, int nLen);														//16进制转换成字符串
+
+void Switch_U32_To_BYTE4(unsigned long temp_U32_data, unsigned char*data);		//将32位无符号整数转成4字节数组存储
+unsigned long Switch_BYTE4_To_U32(unsigned char*data);												//将U32的4字节数组转成32位无符号整数
+
+void Switch_S32_to_ASCII(signed long data, unsigned char*str);								//将32位有符号整数转成ASCII字符串显示
+void Switch_Float_To_ASCII(float temp_float_data, unsigned char*str);					//将浮点数转成ASCII字符串
+
+void Switch_S16_To_Byte2(signed short temp_S16_data, unsigned char*data);			//将有符号整数转成2字节数组存储
+signed short Switch_Byte2_To_S16(unsigned char*data);													//2字节数组转成有符号整数
+
+float Switch_Byte4_To_Float(unsigned char*data);															//四字节数组转成浮点数
+void Switch_Float_To_Byte4(float temp_float_data, unsigned char*data);				//将浮点数转成四字节数组存储
+
+void Data32ToBuf(uint16_t *buf, uint32_t data32);															//4字节数存放到数组中	数组起始地址存放高字节
+int32_t BufToData32(uint16_t *buf);																						//2字节数组组成一个32位数	数组起始地址存放高字节
+
+void S32_to_u8(signed long data,unsigned char*str);
+
+uint16_t LRC_Check(uint8_t *data);
+uint16_t Calc_LRC(uint8_t* data, int data_len);
+uint8_t MODBUS_ASCII_GetLrc(uint8_t *pCyAsciiBuf, uint8_t cyLen);
+
+uint8_t MODBUS_ASCII_AsciiToHex(uint8_t *pbDest);
+uint8_t MODBUS_ASCII_GetLrc(uint8_t *pCyAsciiBuf, uint8_t cyLen);						//MODBUS  LDR校验
+void MODBUS_S32_to_ASCII(int32_t data32 ,uint8_t *pAsciiBuf );
+void MODBUS_S16_to_ASCII(int16_t data16 ,uint8_t *pAsciiBuf );
+void MODBUS_S8_to_ASCII(int8_t data8 ,uint8_t *pAsciiBuf );
+
+uint16_t CRC16(unsigned char *pBuf,int nLength) ;
+
+
+unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen);
+
+float MODBUS_ASCII_AsciiToFlaot(uint8_t *pbDest);
+
+void MODBUS_Float_to_ASCII(float data32 ,uint8_t *pAsciiBuf );
+
+//单字节BCD转为HEX子程序
+unsigned char BCDtoHEX(unsigned char bcd_data); 
+
+//单字节HEX转为BCD子程序
+unsigned char HEXtoBCD(unsigned char hex_data); 
+
+/********** BCD to HEX **********/
+//双字节数值范围:0~9999
+uint16_t BCD2HEX(uint16_t bcd);
+
+/********** BCD to HEX **********/
+//双字节数值范围:0~9999
+uint16_t HEX2BCD(uint16_t hex);
+
+#endif

+ 34 - 0
Core/Inc/iap.h

@@ -0,0 +1,34 @@
+#ifndef __IAP_H__
+#define __IAP_H__
+
+#include "main.h"
+#include "string.h"
+#include "stdio.h"
+#include "usart.h"
+
+typedef  void (*iapfun)(void);				//定义一个函数类型的参数.
+
+#define FLASH_APP1_ADDR		0x08010000  	//第一个应用程序起始地址(存放在FLASH)
+											//保留0X08000000~0X0800FFFF的空间为IAP使用
+/* 启动选项 */
+#define Startup_Normal 	0xFFFFFFFF	///< 正常启动   跳转到APP1
+#define Startup_Update 	0xAAAAAAAA	///< 升级再启动 
+#define Startup_Reset  	0x5555AAAA	///< ***恢复出厂 目前没使用***
+#define Startup_APP2  	0x5555BBBB	///< ***跳转到APP2***
+#define StartBytes_IAP   ((uint32_t)0xA55A55AA) //远程升级的起始字节
+#define EndBytes_IAP     ((uint32_t)0x5AA5AA55) //远程升级的结束字节
+
+
+
+
+
+void Process_CMD_IAP_Update(void);
+void Set_Update_Down(void);
+void Res_Update_Down(void);
+void Start_BootLoader(void);
+void Set_App2_Flag(void);
+void iap_load_app(uint32_t appxaddr);			//执行flash里面的app程序
+
+void iap_write_appbin(uint32_t appxaddr,uint8_t *appbuf,uint32_t applen);	//在指定地址开始,写入bin
+
+#endif

+ 25 - 1
Core/Inc/main.h

@@ -33,11 +33,22 @@ extern "C" {
 /* USER CODE BEGIN Includes */
 #include "stdio.h"
 #include "string.h"
+
+#include "Data_deal.h"
+#include "iap.h"
+#include "md5c.h"
+#include "stmflash.h"
 /* USER CODE END Includes */
 
 /* Exported types ------------------------------------------------------------*/
 /* USER CODE BEGIN ET */
 
+#define iap_ 1
+#if 1
+#define IR_ROM1   0x08000000
+#else
+#define IR_ROM1   0x08020000
+#endif
 /* USER CODE END ET */
 
 /* Exported constants --------------------------------------------------------*/
@@ -48,7 +59,7 @@ extern "C" {
 /* Exported macro ------------------------------------------------------------*/
 /* USER CODE BEGIN EM */
 #define Rx_Max 1024  	
-#define Version_sys 0x23060500  	
+#define Version_sys 0x23060700  	
 
 extern uint16_t Adc2_CalibrationValue ;
 extern uint16_t Adc3_CalibrationValue ;
@@ -57,6 +68,9 @@ extern uint8_t  gpiobStatus ;
 extern uint8_t	Rx_Flag;
 extern uint16_t	Rx_Len;
 extern uint8_t	Rx_Buf[Rx_Max];
+
+extern int data_lengthU2;
+extern int flagU2Rx;
 /* USER CODE END EM */
 
 /* Exported functions prototypes ---------------------------------------------*/
@@ -66,6 +80,8 @@ void Error_Handler(void);
 uint16_t read_flash_16(uint32_t addr);
 void read_new_address(uint32_t addr);
 void Write_Information(uint32_t addr, uint8_t* rx_buffer, uint8_t buffer_index);
+void delay_sys_us(uint32_t Delay);
+void ModBus(void);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
@@ -82,6 +98,14 @@ void Write_Information(uint32_t addr, uint8_t* rx_buffer, uint8_t buffer_index);
 #define ADDR_FLASH_PAGE_134   ((uint32_t)0x8043000)  // Flash扇区134页的起始地址     Adc3_Calibration    4-20mA
 #define ADDR_FLASH_PAGE_144   ((uint32_t)0x8048000)  // Flash扇区144页的起始地址      
   
+#define ADDR_UPDATE_FLAG               0x0807F078                          //2??    ???
+#define StartMode_Addr                 0x0807F07A                          //4??
+
+
+#define Application_Buffer_Addr       0x08040000
+#define ADD_UPDATE_PROG               0x08020000                          //APP2???    ???
+#define ADD_UPDATE_PROG1              0x08000000
+
 
 /* USER CODE END Private defines */
 

+ 27 - 0
Core/Inc/md5c.h

@@ -0,0 +1,27 @@
+#ifndef __MD5C_H__
+#define __MD5C_H__
+/* POINTER defines a generic pointer type */ 
+typedef unsigned char * POINTER; 
+ 
+/* UINT2 defines a two byte word */ 
+//typedef unsigned short int UINT2; 
+ 
+/* UINT4 defines a four byte word */ 
+typedef unsigned long int UINT4; 
+ 
+ 
+/* MD5 context. */ 
+typedef struct { 
+ UINT4 state[4];         /* state (ABCD) */ 
+ UINT4 count[2];  /* number of bits, modulo 2^64 (lsb first) */ 
+ unsigned char buffer[64];       /* input buffer */ 
+} MD5_CTX; 
+ 
+void MD5Init (MD5_CTX *context); 
+void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen); 
+void MD5UpdaterString(MD5_CTX *context,const char *string); 
+int MD5FileUpdateFile (MD5_CTX *context,char *filename); 
+void MD5Final (unsigned char digest[16], MD5_CTX *context); 
+void MDString (char *string,unsigned char digest[16]); 
+int MD5File (char *filename,unsigned char digest[16]); 
+#endif

+ 1 - 0
Core/Inc/stm32f1xx_it.h

@@ -55,6 +55,7 @@ void SVC_Handler(void);
 void DebugMon_Handler(void);
 void PendSV_Handler(void);
 void SysTick_Handler(void);
+void DMA1_Channel3_IRQHandler(void);
 void DMA1_Channel5_IRQHandler(void);
 void TIM2_IRQHandler(void);
 void USART1_IRQHandler(void);

+ 46 - 0
Core/Inc/stmflash.h

@@ -0,0 +1,46 @@
+#ifndef __STMFLASH_H__
+#define __STMFLASH_H__
+#include "main.h"
+#include "string.h"
+#include "stdio.h"
+#include "usart.h"
+
+extern void  FLASH_PageErase(uint32_t PageAddress);
+
+#define STM32_FLASH_SIZE 	512 	 		//所选STM32的FLASH容量大小(单位为K)
+#define STM32_FLASH_WREN 	1              	//使能FLASH写入(0,不是能;1,使能)
+#define FLASH_WAITETIME  	50000          	//FLASH等待超时时间
+
+//FLASH起始地址
+#define STM32_FLASH_BASE 0x08000000 		//STM32 FLASH的起始地址
+
+uint8_t STMFLASH_GetStatus(void);				  //获得状态
+uint8_t STMFLASH_WaitDone(uint16_t time);				  //等待操作结束
+uint8_t STMFLASH_ErasePage(uint32_t paddr);			  //擦除页
+uint8_t STMFLASH_WriteHalfWord(uint32_t faddr, uint16_t dat);//写入半字
+uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);		  //读出半字  
+void STMFLASH_WriteLenByte(uint32_t WriteAddr,uint32_t DataToWrite,uint16_t Len);	//指定地址开始写入指定长度的数据
+uint32_t STMFLASH_ReadLenByte(uint32_t ReadAddr,uint16_t Len);						//指定地址开始读取指定长度数据
+void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite);		//从指定地址开始写入指定长度的数据
+void STMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead);   		//从指定地址开始读出指定长度的数据
+
+//测试写入
+void Test_Write(uint32_t WriteAddr,uint16_t WriteData);								   
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 13 - 0
Core/Inc/usart.h

@@ -37,7 +37,20 @@ extern UART_HandleTypeDef huart1;
 extern UART_HandleTypeDef huart3;
 
 /* USER CODE BEGIN Private defines */
+#define BUF_SIZE 500
+#define Uart1_BUF_SIZE  256
+#define Uart2_BUF_SIZE  1024      /*为UART2、3专门开一个DMA接收存储区 2021-4-12 by Daiyf*/
+#define Uart3_BUF_SIZE  256
+	 
+extern uint8_t usart1_rx_flag;
+extern uint8_t usart3_rx_flag;
+extern uint16_t rx1_len;
+extern uint16_t rx3_len;
 
+extern uint8_t USART_RX_BUF[Uart1_BUF_SIZE];
+extern uint16_t LIB_CRC_MODBUS(uint8_t* Buf, uint16_t srLen);
+extern uint8_t USART2_RX_BUF[Uart2_BUF_SIZE];
+extern uint8_t USART2_RX_BUF002[Uart2_BUF_SIZE];
 /* USER CODE END Private defines */
 
 void MX_USART1_UART_Init(void);

+ 802 - 0
Core/Src/Data_deal.c

@@ -0,0 +1,802 @@
+#include "Data_deal.h"
+
+//note: 2021-2-23 新加入BCDtoHEX相互转的几个函数  ---- Daiyf。 
+union Tmp
+{
+    float  value;									//浮点运算联合体
+    unsigned char array[4];
+};
+
+union Tmp1
+{
+    signed short  value;							//S16运算联合体   -32768-32767
+    unsigned char array[2];
+};
+
+union Tmp2
+{
+    signed long  value;							    //S32运算联合体   -2147483648--2147483647   存放18位AD值 -131072-131071
+    unsigned char array[4];
+};
+
+union Tmp3
+{
+    unsigned long  value;							//U32运算联合体   存放18位AD值0x00000-0x3FFFF
+    unsigned char array[4];
+};
+
+
+/*
+// C prototype : void StrToHex(BYTE *pbDest, BYTE *pbSrc, int nLen)
+// parameter(s): [OUT] pbDest - 输出缓冲区
+//	[IN] pbSrc - 字符串
+//	[IN] nLen - 16进制数的字节数(字符串的长度/2)
+// return value: 
+// remarks : 字符串转成16进制数
+*/
+void StrToHex(uint8_t *pbDest, uint8_t *pbSrc, int nLen)
+{
+	char h1,h2;
+	uint8_t s1,s2;
+	int i;
+
+	for (i=0; i<nLen; i++)
+	{
+		h1 = pbSrc[2*i];
+		h2 = pbSrc[2*i+1];
+
+		s1 = toupper(h1) - 0x30;
+		if (s1 > 9) 
+		s1 -= 7;
+
+		s2 = toupper(h2) - 0x30;
+		if (s2 > 9) 
+		s2 -= 7;
+
+		pbDest[i] = s1*16 + s2;
+	}
+}
+
+/*
+// C prototype : void HexToStr(BYTE *pbDest, BYTE *pbSrc, int nLen)
+// parameter(s): [OUT] pbDest - 存放在目标字符串中
+//	[IN] pbSrc - 输入16进制的起始地址
+//	[IN] nLen - 16进制的字节数
+// return value: 
+// remarks : 16进制转换成字符串
+*/
+void HexToStr(uint8_t *pbDest, uint8_t *pbSrc, int nLen)
+{
+	char	ddl,ddh;
+	int i;
+
+	for (i=0; i<nLen; i++)
+	{
+		ddh = 48 + pbSrc[i] / 16;
+		ddl = 48 + pbSrc[i] % 16;
+		if (ddh > 57) ddh = ddh + 7;
+		if (ddl > 57) ddl = ddl + 7;
+		pbDest[i*2] = ddh;
+		pbDest[i*2+1] = ddl;
+	}
+
+	pbDest[nLen*2] = '\0';
+}
+
+/*******************************************************************************
+* Function Name  : Switch_U32_To_AD7691BYTE4
+* Description    : 将32位无符号整数转成4字节数组存储
+* Input          : temp_U32_data--要转换的U32变量   data--转换后的4字节存储
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void Switch_U32_To_BYTE4(unsigned long temp_U32_data, unsigned char*data)
+{
+    union Tmp3 U32Tmp;
+    unsigned char i = 0;
+    U32Tmp.value = temp_U32_data;
+    for(i = 0; i < 4; i++)
+    {
+        data[i] = U32Tmp.array[i];		//将U32转换成四字节
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Switch_BYTE4_To_U32
+* Description    : 将U32的4字节数组转成32位无符号整数
+* Input          : data--转换前四字节数组    temp_U32_data--要转换的U32变量
+* Output         : None
+* Return         : None
+*******************************************************************************/
+unsigned long Switch_BYTE4_To_U32(unsigned char*data)
+{
+    union Tmp3 U32Tmp;
+    unsigned char i = 0;
+    unsigned long temp_U32_data = 0;
+    for(i = 0; i < 4; i++)
+    {
+        U32Tmp.array[i] = *(data + i);		//4字节数据暂存
+    }
+    temp_U32_data = U32Tmp.value; 	//4字节转换的U32有符号整数
+    return(temp_U32_data);
+
+}
+
+/*******************************************************************************
+* Function Name  : Switch_S32_to_ASCII
+* Description    : 将32位有符号整数转成ASCII字符串显示
+* Input          : S32
+* Output         : ASCII字符串
+* Return         : None
+*******************************************************************************/
+
+void Switch_S32_to_ASCII(signed long data, unsigned char*str)
+{
+    unsigned short i;       //u16
+    signed long temp, tempoten; //s32
+    unsigned char temp_length, temp_str[12] = {0};
+
+
+    if(data < 0)
+    {
+        str[0] = '-';    //1.确定符号位
+        data = -data;
+    }
+    else str[0] = '+';
+
+    temp = data;
+
+    i = 0;
+    tempoten = temp / 10;
+    while(tempoten != 0)			    //由低到高存储ASCII码
+    {
+        temp_str[i] = temp - 10 * tempoten + 48; //to ascii code
+        temp = tempoten;
+        tempoten = temp / 10;
+        i++;
+    }
+    temp_str[i] = temp + 48;
+    temp_length = i + 1;
+
+    for(i = 0; i < temp_length; i++)
+    {
+        str[i + 1] =	temp_str[temp_length - 1 - i]; //由高到低存储ASCII码
+    }
+
+}
+
+
+/*******************************************************************************
+* Function Name  : S32_to_u8  
+* Description    : 将32位数转换成8位数组
+* Input          : data--要转变量   str--转换后的字节数组
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void S32_to_u8(signed long data,unsigned char*str)
+{
+// int i;
+	 str[0] = data>>24;
+	 str[1] = data>>16;
+	 str[2] = data>>8;
+	 str[3] = data;
+// for(i=3;i>0;i--)
+// {
+//    str[i]=(data>>(i*8))& 0xFF;
+// }
+}
+
+
+/*******************************************************************************
+* Function Name  : Switch_Float_To_ASCII  注:小数点有效数字3位
+* Description    : 将浮点数转成ASCII字符串
+* Input          : temp_float_data--要转换的float变量   str--转换后的字节数组
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void Switch_Float_To_ASCII(float temp_float_data, unsigned char*str)
+{
+    unsigned short  i, j, k;
+    signed long temp, tempoten;
+    unsigned char intpart[20], data[20];
+
+    if(temp_float_data < 0)
+    {
+        str[0] = '-';
+        temp_float_data = -temp_float_data;
+    }
+    else str[0] = '+';
+
+
+    temp = (signed long)temp_float_data;
+
+    i = 0;
+    tempoten = temp / 10;
+    while(tempoten != 0)
+    {
+        intpart[i] = temp - 10 * tempoten + 48; //to ASCII code
+        temp = tempoten;
+        tempoten = temp / 10;
+        i++;
+    }
+    intpart[i] = temp + 48;
+
+    for(k = 1; k <= i + 1; k++) str[k] = intpart[i + 1 - k];
+
+
+    for(j = 0; j < 20; j++)
+    {
+        data[j] = 0;
+    }
+
+    temp = (temp_float_data * 1000) - ((signed long)(temp_float_data)) * 1000; //取小数
+    if(temp)
+    {
+        Switch_S32_to_ASCII(temp, data);
+        str[i + 2] = '.';
+
+        str[i + 3] = data[1]; //第1位肯定不为0
+
+        if(data[2] != '0')
+        {
+            str[i + 4] = data[2]; //取2位
+        }
+        else
+        {
+            str[i + 4] = 0;
+        }
+        if(data[3] != '0')
+        {
+            str[i + 5] = data[3]; //取3位
+        }
+        else
+        {
+            str[i + 5] = 0;
+        }
+        str[i + 6] = 0;
+    }
+    else
+    {
+        str[i + 3] = 0;
+    }
+
+}
+
+/*******************************************************************************
+* Function Name  : Switch_S16_To_Byte2
+* Description    : 将有符号整数转成2字节数组存储
+* Input          : temp_S16_data--要转换的S16变量   data--转换后的2字节数组
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void Switch_S16_To_Byte2(signed short temp_S16_data, unsigned char*data)
+{
+    union Tmp1 S16Tmp;
+    unsigned char i = 0;
+    S16Tmp.value = temp_S16_data;       //将S16转存
+    for(i = 0; i < 2; i++)
+    {
+        data[i] = S16Tmp.array[i];		//将S16转换成2字节
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Switch_Byte2_To_S16
+* Description    : 2字节数组转成有符号整数
+* Input          : data--转换前的2字节数组
+* Output         : None
+* Return         : 转换后的有符号整数
+*******************************************************************************/
+signed short Switch_Byte2_To_S16(unsigned char*data)
+{
+    union Tmp1 S16Tmp;
+    unsigned char i = 0;
+    signed short temp_S16_data = 0;
+    for(i = 0; i < 2; i++)
+    {
+        S16Tmp.array[i] = data[i];		//2字节数据暂存
+    }
+    temp_S16_data = S16Tmp.value; 	    //2字节转换的S16有符号整数
+
+    return(temp_S16_data);
+}
+
+/*******************************************************************************
+* Function Name  : Switch_Byte4_To_Float
+* Description    : 四字节数组转成浮点数
+* Input          : data--转换前的四字节数组
+* Output         : None
+* Return         : 转换后的浮点数
+*******************************************************************************/
+float Switch_Byte4_To_Float(unsigned char*data)
+{
+    union Tmp floatTmp;
+    unsigned char i = 0;
+    float temp_float_data = 0;
+    for(i = 0; i < 4; i++)
+    {
+        floatTmp.array[i] = data[i];		//四字节数据暂存
+    }
+    temp_float_data = floatTmp.value; 	//四字节转换的浮点数
+
+    return(temp_float_data);
+}
+
+
+
+/*******************************************************************************
+* Function Name  : Switch_Float_To_Byte4
+* Description    : 将浮点数转成四字节数组存储
+* Input          : temp_float_data--要转换的float变量   data--转换后的四字节数组
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void Switch_Float_To_Byte4(float temp_float_data, unsigned char*data)
+{
+    union Tmp floatTmp;
+    unsigned char i = 0;
+    floatTmp.value = temp_float_data;   //将浮点数转存
+    for(i = 0; i < 4; i++)
+    {
+        data[i] = floatTmp.array[i];		//将浮点数转换成四字节
+    }
+}
+
+
+/******************************************************************************
+
+//4字节数存放到数组中	数组起始地址存放高字节
+//输入:uint16_t *buf数组起始地址, uint32_t data32存放数 
+//返回:无
+		
+******************************************************************************/
+void Data32ToBuf(uint16_t *buf, uint32_t data32)
+{
+	*buf++ = data32>>16;
+	*buf   = data32;
+}
+/******************************************************************************
+
+//2字节数组组成一个32位数	数组起始地址存放高字节
+//输入:uint16_t *buf数组起始地址, int32_t data32存放数 
+//返回:32位数
+		
+******************************************************************************/
+int32_t BufToData32(uint16_t *buf)
+{
+	uint8_t i;
+	int32_t temp=0;
+	int32_t data32=0 ;
+	for(i=0;i<2;i++)
+	{
+		temp = *buf++;
+		data32 = (data32<<16) + (temp&0xffff);
+	}
+	return 	data32;
+}
+
+
+/*******************************************************************************
+* Function Name  : Calc_LRC
+* Description    : LRC校验
+* Input          : data--要校验的数组  data_len--校验的长度
+* Output         : None
+* Return         : lrc 校验后的值
+*******************************************************************************/
+uint16_t Calc_LRC(uint8_t* data, int data_len)
+{
+	int i;
+	uint16_t lrc = 0;
+	for ( i = 0; i < data_len; i++)
+	{
+		lrc ^=  data[i];
+	}
+	return lrc;
+}
+/*******************************************************************************
+* Function Name  : LRC_Check
+* Description    : LRC校验
+* Input          : data--要校验的数组 
+* Output         : None
+* Return         : result 校验后的值
+*******************************************************************************/
+uint16_t LRC_Check(uint8_t *data)
+{
+	uint8_t i;
+	int k;
+	uint16_t result;
+	uint16_t lrcdata[12];
+
+	for (i = 1;i < 12 + 1;i++)
+	{
+		if (data[i]>0x40)
+			lrcdata[i - 1] = data[i] - 0x41 + 10;
+		else
+			lrcdata[i - 1] = data[i] - 0x30;
+	}
+	k = 0;
+	for (i = 0;i<12 / 2;i++) 
+	{
+		k += (lrcdata[2 * i] * 16 + lrcdata[2 * i + 1]);
+	}
+	k = k % 256;
+	k = 256 - k;
+	result = k % 256;
+	return result;
+}
+
+//单字节BCD转为HEX子程序
+unsigned char BCDtoHEX(unsigned char bcd_data)  
+{
+    unsigned char temp; 
+    temp=(bcd_data/16*10 + bcd_data%16); 
+    return temp; 
+} 
+
+//单字节HEX转为BCD子程序
+unsigned char HEXtoBCD(unsigned char hex_data)  
+{ 
+    unsigned char temp; 
+    temp=(hex_data/10*16 + hex_data%10); 
+    return temp; 
+}
+/********** BCD to HEX **********/
+//双字节数值范围:0~9999
+uint16_t BCD2HEX(uint16_t bcd)
+{
+  uint16_t temp;
+  temp = (((bcd>>12) & 0x000f) * 1000)
+       + (((bcd>>8) & 0x000f) * 100)
+       + (((bcd>>4) & 0x000f) * 10)
+       + (bcd& 0x000f);
+  return temp;
+}
+
+/********** BCD to HEX **********/
+//双字节数值范围:0~9999
+uint16_t HEX2BCD(uint16_t hex)
+{
+      uint16_t bcd;
+    bcd = ((HEXtoBCD((hex/100))) << 8);
+    bcd += HEXtoBCD(hex%100);
+    return bcd;
+}
+
+
+
+
+/*******************************************************************************
+* Function Name  : MODBUS_ASCII_AsciiToFloat
+* Description    : 将目标中的8个字节转化为一个浮点数
+* Input          : pbDest--要转化的数组
+* Output         : None
+* Return         : float 转化后的值
+*******************************************************************************/
+float MODBUS_ASCII_AsciiToFlaot(uint8_t *pbDest)
+{
+
+	  union Tmp floatTmp;
+	  unsigned char  data[8];
+    unsigned char i = 0;
+    float temp_float_data = 0;
+    for(i = 0; i < 4; i++)
+    {   
+			  data[i] =  MODBUS_ASCII_AsciiToHex(pbDest+i*2);   //一个字节一个转
+        floatTmp.array[3-i] = data[i];		//四字节数据暂存
+    }
+    temp_float_data = floatTmp.value; 	//四字节转换的浮点数
+
+    return(temp_float_data);
+}
+
+
+/*******************************************************************************
+* Function Name  : MODBUS_Float_to_ASCII
+* Description    : float数据转换为8个字节的ASCII数据
+* Input          : data32--要转换的数据
+* Output         : pAsciiBuf  转换后的数组
+* Return         : 
+*******************************************************************************/
+void MODBUS_Float_to_ASCII(float data32 ,uint8_t *pAsciiBuf )
+{
+	uint8_t i;
+	union Tmp2 a32Tmp;
+	union Tmp floatTmp;
+	floatTmp.value = data32;
+	
+	for(i=0;i<4;i++)a32Tmp.array[i]=floatTmp.array[i];
+	
+	for(i=0;i<8;i++)
+	{
+	
+		pAsciiBuf[i] = (a32Tmp.value>>(28-i*4))&0x0F;
+		if(pAsciiBuf[i]<=0x09)
+			pAsciiBuf[i] = pAsciiBuf[i]+0x30;
+		else
+		{
+			pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
+		}
+		
+	}
+	
+}
+/*******************************************************************************
+* Function Name  : MODBUS_ASCII_AsciiToHex
+* Description    : 转化为16进制
+* Input          : pbDest--要转化的数组
+* Output         : None
+* Return         : s1*16 + s2 转化后的值
+*******************************************************************************/
+uint8_t MODBUS_ASCII_AsciiToHex(uint8_t *pbDest)
+{
+	
+	char h1,h2;
+	uint8_t s1,s2;
+	
+		h1 = pbDest[0];
+		h2 = pbDest[1];
+
+		s1 = toupper(h1) - 0x30;
+		if (s1 > 9) 
+		s1 -= 7;
+
+		s2 = toupper(h2) - 0x30;
+		if (s2 > 9) 
+		s2 -= 7;
+
+		return (s1*16 + s2);
+}
+
+/*******************************************************************************
+* Function Name  : MODBUS_ASCII_GetLrc
+* Description    : LRC校验
+* Input          : pCyAsciiBuf--要校验的数组 cyLen--长度
+* Output         : None
+* Return         : cyLrcVal 校验后的值
+*******************************************************************************/
+uint8_t MODBUS_ASCII_GetLrc(uint8_t *pCyAsciiBuf, uint8_t cyLen)
+{
+	uint8_t i;
+	uint8_t cyLrcVal;
+	
+	if (1 == (cyLen % 2) )
+	{
+		return 0;
+	}
+	
+	cyLen /= 2;
+	cyLrcVal = 0;
+	for (i = 0; i < cyLen; i++)
+	{
+		cyLrcVal +=  MODBUS_ASCII_AsciiToHex(pCyAsciiBuf + i * 2);
+	}
+	
+	cyLrcVal = ~cyLrcVal;
+	cyLrcVal += 1;
+	
+	return (cyLrcVal);
+}
+
+/*******************************************************************************
+* Function Name  : MODBUS_S32_to_ASCII
+* Description    : 32位数据转换为单个8位数据
+* Input          : data32--要转换的数据
+* Output         : pAsciiBuf  转换后的数组
+* Return         : 
+*******************************************************************************/
+void MODBUS_S32_to_ASCII(int32_t data32 ,uint8_t *pAsciiBuf )
+{
+	uint8_t i;
+	for(i=0;i<8;i++)
+	{
+		pAsciiBuf[i] = (data32>>(28-i*4))&0x0F;
+		if(pAsciiBuf[i]<=0x09)
+			pAsciiBuf[i] = pAsciiBuf[i]+0x30;
+		else
+		{
+			pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
+		}
+		
+	}
+	
+}
+
+/*******************************************************************************
+* Function Name  : MODBUS_S16_to_ASCII
+* Description    : 16为数据转换为ASCII数据
+* Input          : data16--要转换的数据
+* Output         : pAsciiBuf  转换后的数组
+* Return         : 
+*******************************************************************************/
+void MODBUS_S16_to_ASCII(int16_t data16 ,uint8_t *pAsciiBuf )
+{
+	uint8_t i;
+	for(i=0;i<4;i++)
+	{
+		pAsciiBuf[i] = (data16>>(12-i*4))&0x0F;
+		if(pAsciiBuf[i]<=0x09)//if((pAsciiBuf[i]>=0x00)&&(pAsciiBuf[i]<=0x09))
+			pAsciiBuf[i] = pAsciiBuf[i]+0x30;
+		else
+		{
+			pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
+		}
+		
+	}
+}
+
+/*******************************************************************************
+* Function Name  : MODBUS_S8_to_ASCII
+* Description    : 8为数据转换为ASCII数据
+* Input          : data8--要转换的数据
+* Output         : pAsciiBuf  转换后的数组
+* Return         : 
+*******************************************************************************/
+void MODBUS_S8_to_ASCII(int8_t data8 ,uint8_t *pAsciiBuf )
+{
+	uint8_t i;
+	for(i=0;i<2;i++)
+	{
+		pAsciiBuf[i] = (data8>>(4-i*4))&0x0F;
+		if(pAsciiBuf[i]<=0x09)//if((pAsciiBuf[i]>=0x00)&&(pAsciiBuf[i]<=0x09))
+			pAsciiBuf[i] = pAsciiBuf[i]+0x30;
+		else
+		{
+			pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
+		}
+	}
+}
+
+////将一个8位数高低4位交换 
+//static inline unsigned char bswap_8(unsigned char v)
+//{	
+//	return ((v & 0xff) << 4) | (v >> 4) ;   //将参数(v & 0xff) << 4 相当于放到高位, v >> 4 位相当于放在低位
+//}                                               //以下两个代码分析雷同
+////将一个16位数高低8位交换 
+//static inline unsigned short bswap_16(unsigned short v)
+//{
+//	return ((v & 0xff) << 8) | (v >> 8);
+//}
+////将一个32位数高低16位交换 
+//static inline unsigned int bswap_32(unsigned int v)
+//{
+//	return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
+//		((v & 0xff0000) >> 8) | (v >> 24);
+//}
+
+/*******************************************************************************
+* Function Name  : CRC16
+* Description    : CRC16校验
+* Input          : pBuf--要校验的数据  nLength--校验的长度
+* Output         : ((wReturn & 0xff) << 8) | (wReturn >> 8)  校验后的数组
+* Return         : 
+*******************************************************************************/ 
+uint16_t CRC16(unsigned char *pBuf,int nLength)  
+{  
+	uint16_t wReturn = 0xFFFF;
+	int nDataLen=0;
+	int nIndex=0;
+	for(nDataLen=0;nDataLen<nLength;nDataLen++)
+	{
+		wReturn^=(unsigned short)(pBuf[nDataLen]);//(BYTE(pBuf[nDataLen]));
+		for(nIndex=0;nIndex<8;nIndex++)
+		{
+			if(wReturn&0x0001)
+			{
+				wReturn>>=1;
+				wReturn^=0xA001;
+			}
+			else
+			{
+				wReturn>>=1;
+			}
+		}
+	}
+		return	((wReturn & 0xff) << 8) | (wReturn >> 8);//高低互换
+//	 return wReturn;
+}
+
+
+
+static uint16_t const wCRC16Table[256] = {      
+    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,     
+    0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,     
+    0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,      
+    0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,     
+    0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,       
+    0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,     
+    0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,     
+    0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,     
+    0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,     
+    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,        
+    0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,     
+    0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,     
+    0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,     
+    0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,     
+    0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,        
+    0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,     
+    0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,     
+    0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,     
+    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,     
+    0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,        
+    0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,     
+    0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,     
+    0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,     
+    0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,     
+    0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,       
+    0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,     
+    0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,     
+    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,     
+    0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,     
+    0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,       
+    0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,     
+    0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040};
+
+
+uint16_t Key_CRC16(const unsigned char* pDataIn, const unsigned char iLenIn)     
+{     
+     uint16_t wResult = 0xFFFF;     
+     uint16_t wTableNo = 0;     
+     int i = 0;
+    for( i = 0; i < iLenIn; i++)     
+    {     
+        wTableNo = ((wResult & 0xff) ^ (pDataIn[i] & 0xff));     
+        wResult = ((wResult >> 8) & 0xff) ^ wCRC16Table[wTableNo];     
+    }     
+    return wResult;     
+} 
+// crcValue=CRC16(SendBuf,4);
+//    SendBuf[4]=(unsigned char)crcValue;
+//    SendBuf[5]=(unsigned char)(crcValue>>8);
+
+
+void InvertUint8(unsigned char *dBuf, unsigned char *srcBuf)
+{
+    int i;
+    unsigned char tmp[4];
+    tmp[0] = 0;
+    for(i = 0; i < 8; i++)
+    {
+        if(srcBuf[0] & (1 << i))
+            tmp[0] |= 1 << (7 - i);
+    }
+    dBuf[0] = tmp[0];
+}
+
+void InvertUint16(unsigned short *dBuf, unsigned short *srcBuf)
+{
+    int i;
+    unsigned short tmp[4];
+    tmp[0] = 0;
+    for (i = 0; i < 16; i++)
+    {
+        if(srcBuf[0] & (1 << i))
+            tmp[0] |= 1 << (15 - i);
+    }
+    dBuf[0] = tmp[0];
+}
+unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)
+{
+    int i;
+	  unsigned short temp;
+	  unsigned short temp1;
+    unsigned short wCRCin = 0xFFFF;
+    unsigned short wCPoly = 0x8005;
+    unsigned char wChar = 0;
+    while(usDataLen--)
+    {
+        wChar = *(puchMsg++);
+        InvertUint8(&wChar, &wChar);
+        wCRCin ^= (wChar << 8);
+        for(i = 0; i < 8; i++)
+        {
+            if(wCRCin & 0x8000)
+                wCRCin = (wCRCin << 1)^wCPoly;
+            else
+                wCRCin = wCRCin << 1;
+        }
+    }
+    InvertUint16(&wCRCin, &wCRCin);
+		temp1=wCRCin>>8&0x00ff;
+		temp=(temp1)+(wCRCin<<8);
+    return(temp);
+}

+ 3 - 0
Core/Src/dma.c

@@ -43,6 +43,9 @@ void MX_DMA_Init(void)
   __HAL_RCC_DMA1_CLK_ENABLE();
 
   /* DMA interrupt init */
+  /* DMA1_Channel3_IRQn interrupt configuration */
+  HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
   /* DMA1_Channel5_IRQn interrupt configuration */
   HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);

+ 480 - 0
Core/Src/iap.c

@@ -0,0 +1,480 @@
+#include "main.h"
+#include "string.h"
+#include "stdio.h"
+#include "usart.h"
+#include "iap.h"
+#include "stmflash.h"
+#include "md5c.h"
+
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+iapfun jump2app;
+uint16_t iapbuf[1024];
+
+__asm void MSR_MSP(uint32_t addr) 
+{
+    MSR MSP, r0 			//set Main Stack value
+    BX r14
+}
+
+void Flash_ReadBytes(uint16_t* sorBuf,uint32_t FlashAddr,uint16_t len)
+{
+	uint16_t* p = sorBuf;
+	uint8_t i = 0,j = 0;
+	uint32_t addr = FlashAddr;
+	while(len--)
+	{
+		i = *(uint32_t*)addr++;
+		j = *(uint32_t*)addr++;
+		*p++ = j<<8|i;
+	}
+}
+
+uint16_t Flashbuf[2048]__attribute__ ((at(0X20001000)));
+
+void Flash_WriteBytes(uint16_t* sorBuf,uint32_t FlashAddr,uint16_t len)
+{
+
+	uint32_t Offset_ADDR = 0,Page_StartAddr = 0,i = 0;
+	Offset_ADDR = FlashAddr%0x800;
+	Page_StartAddr = FlashAddr - Offset_ADDR;
+	//设置PageError
+	uint32_t PageError = 0;
+	FLASH_EraseInitTypeDef f;
+
+	f.TypeErase = FLASH_TYPEERASE_PAGES;
+	__nop();
+	f.PageAddress =Page_StartAddr;
+	f.NbPages = 1;
+
+	Flash_ReadBytes(Flashbuf,Page_StartAddr,0x400);
+	
+	for(i = 0;i<len;i++)
+		Flashbuf[Offset_ADDR/2+i] = sorBuf[i];
+	
+	//1、解锁FLASH
+  HAL_FLASH_Unlock();
+	__nop();
+
+  //2、擦除FLASH
+  //初始化FLASH_EraseInitTypeDef
+
+  //调用擦除函数
+  HAL_FLASHEx_Erase(&f, &PageError);
+	
+	__nop();
+  //3、对FLASH烧写
+  for(uint16_t i = 0;i< 0x400 ;i++)
+  {
+      HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD , Page_StartAddr + (i * 2), Flashbuf[i]);
+  }
+
+    //4、锁住FLASH
+    HAL_FLASH_Lock();
+	
+}
+
+
+int App2_MD5_Check(uint32_t addr,unsigned int all_len)
+{
+	unsigned char digest[16];
+	
+	unsigned int i,update_len;
+	MD5_CTX md5c;
+	all_len -= 16;
+	MD5Init(&md5c);
+	for(i=0;i<all_len;)
+	{
+		if(all_len>(i+512))
+			update_len = 512;
+		else
+			update_len = all_len-i;
+		memcpy(iapbuf,(const void *)(addr+i),update_len);
+		MD5Update (&md5c, (unsigned char *)iapbuf, update_len);
+		i += update_len;
+		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+	}
+	MD5Final(digest,&md5c);
+	for(i=0;i<16;++i)
+	{
+		if(digest[i]!=*(unsigned char *)(addr+all_len+i))
+			break;
+	}
+	if(i>=16)
+		return 1;
+	else
+		return 0;
+}
+// appxaddr:应用程序的起始地址
+// appbuf:应用程序CODE.
+// appsize:应用程序大小(字节).
+void iap_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
+{
+	uint32_t t;
+	uint16_t i = 0;
+	uint16_t temp;
+	uint32_t fwaddr = appxaddr; //当前写入的地址
+	uint8_t *dfu = appbuf;
+	for (t = 0; t < appsize; t += 2)
+	{
+		temp = (uint16_t)dfu[1] << 8;
+		temp += (uint16_t)dfu[0];
+		dfu += 2; //偏移2个字节
+		iapbuf[i++] = temp;
+		if (i == 1024)
+		{
+			i = 0;
+			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+			STMFLASH_Write(fwaddr, iapbuf, 1024);
+			fwaddr += 2048; //偏移2048  16=2*8.所以要乘以2.
+		}
+		
+	}
+	if (i)
+		STMFLASH_Write(fwaddr, iapbuf, i); //将最后的一些内容字节写进去.
+}
+
+//跳转到应用程序段
+// appxaddr:用户代码起始地址.
+void iap_load_app(uint32_t appxaddr)
+{
+	if (((*(uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法.
+	{
+		jump2app = (iapfun) * (uint32_t *)(appxaddr + 4); //用户代码区第二个字为程序开始地址(复位地址)
+		MSR_MSP(*(uint32_t *)appxaddr);					  //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
+		jump2app();										  //跳转到APP.
+	}
+}
+	unsigned int update_flag = 0xAAAAAAAA; ///< 对应bootloader的启动步骤
+	unsigned int ModeStart;
+	unsigned int i,all_len;
+/**
+ * @bieaf 进行BootLoader的启动
+ *
+ * @param none
+ * @return none
+ */
+void Start_BootLoader(void)
+{
+	uint16_t ModeStart1[2];
+	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+	Flash_ReadBytes(ModeStart1, StartMode_Addr, 2);
+	ModeStart = ModeStart1[0];
+	ModeStart <<= 16;
+	ModeStart |= ModeStart1[1];
+	switch (ModeStart) ///< 读取是否启动应用程序 */
+	{
+	case Startup_Normal: ///< 正常启动 */   //在APP2中可以设定此标志位   使得下次重启之后进入APP1
+	{
+		;
+		break;
+	}
+	case Startup_Update: /*启动最新的程序 */
+		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+		for (i = 0, all_len = 0; i < 4; ++i)
+		{
+				all_len = all_len << 8;
+				all_len |= *(unsigned char *)(StartMode_Addr + 68 + i);
+		}
+		if (App2_MD5_Check(Application_Buffer_Addr,all_len))
+			{
+				iap_write_appbin(ADD_UPDATE_PROG,(uint8_t *)Application_Buffer_Addr,all_len);
+				HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+				Flash_WriteBytes((uint16_t*)(StartMode_Addr + 68), StartMode_Addr+132, 2);
+			}
+			Set_App2_Flag();
+	case Startup_APP2: /*启动最新的程序 */
+		for (i = 0, all_len = 0; i < 4; ++i)
+			{
+				all_len = all_len << 8;
+				all_len |= *(unsigned char *)(StartMode_Addr + 132 + i);
+			}
+			if ((all_len<0x20000) && App2_MD5_Check(ADD_UPDATE_PROG,all_len))
+			{
+				__set_FAULTMASK(0);			   //先关闭全局中断
+				iap_load_app(ADD_UPDATE_PROG); //执行FLASH APP2代码
+			}
+		break;
+	default: ///< 启动失败
+	{
+		return;
+	}
+	}
+}
+
+
+uint8_t YmodemID;
+uint16_t packIndex, packTotalNum, packIndexbak; //当前包号,总包数
+uint16_t crcIAP, crcTerminal, crcIAP1;
+uint32_t FileLength_IAP = 0;  //文件长度
+uint16_t FileBuffArray[512];  // MD5校验
+uint16_t FileBuffArray1[512]; // MD5校验
+uint32_t AddrToWrite = Application_Buffer_Addr;
+uint32_t DataReadFlash, DataReadFlash1, update_flag;
+void Set_Update_Down(void)
+{
+	uint16_t update_flag1[2];
+	update_flag = Startup_Update; ///< 对应bootloader的启动步骤
+	update_flag1[0] = (uint16_t)update_flag;
+	update_flag1[1] = (uint16_t)(update_flag >> 16);
+	Flash_WriteBytes(update_flag1, StartMode_Addr, 2);
+	__set_FAULTMASK(1);
+	NVIC_SystemReset();
+}
+
+void Res_Update_Down(void)
+{
+	uint16_t update_flag1[2];
+	update_flag = Startup_Normal; ///< 对应bootloader的启动步骤
+	update_flag1[0] = (uint16_t)update_flag;
+	update_flag1[1] = (uint16_t)(update_flag >> 16);
+	Flash_WriteBytes(update_flag1, StartMode_Addr, 2);
+	__set_FAULTMASK(1);
+	NVIC_SystemReset();
+}
+
+
+void Set_App2_Flag(void)
+{
+	uint16_t update_flag1[2];
+	update_flag = Startup_APP2; ///< 对应bootloader的启动步骤
+	update_flag1[1] = (uint16_t)update_flag;
+	update_flag1[0] = (uint16_t)(update_flag >> 16);
+	Flash_WriteBytes(update_flag1, StartMode_Addr, 2);
+}
+
+void Process_CMD_IAP_Update(void)
+{
+
+	int lenRx1, lenRx2;
+	int i;
+	
+	for (i = 0; i < 512; i++)
+	{
+		FileBuffArray[i] = 0;
+		FileBuffArray1[i] = 0;
+	}
+	packIndex = (USART2_RX_BUF002[5] << 8) + USART2_RX_BUF002[6];
+	packTotalNum = (USART2_RX_BUF002[7] << 8) + USART2_RX_BUF002[8];
+	lenRx1 = data_lengthU2;
+	YmodemID = USART2_RX_BUF002[4]; //只能是01,02
+	data_lengthU2 = 0;
+	uint8_t ERR_Arr[8] = "error\r\n";
+	uint8_t ACK_Arr[16] = "acknowlege";
+
+	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+	switch (YmodemID)
+	{
+	case 0x01: //起始帧与结束帧解析  根据包序号判别该帧为起始帧还是结束帧
+		if (packIndex == 1)
+		{ //起始帧处理
+			FileLength_IAP = (USART2_RX_BUF002[73] << 24) + (USART2_RX_BUF002[74] << 16) + (USART2_RX_BUF002[75] << 8) + (USART2_RX_BUF002[76]);
+			crcIAP = LIB_CRC_MODBUS(&USART2_RX_BUF002[4], 133); //
+			crcTerminal = (USART2_RX_BUF002[lenRx1 - 5] << 8) + USART2_RX_BUF002[lenRx1 - 6];
+			if (crcIAP == crcTerminal)
+			{
+				for (i = 0; i < 88; ++i)
+				{
+					if (*(unsigned char *)(StartMode_Addr + i + 4) != USART2_RX_BUF002[9 + i])
+						break;
+				}
+				if (i < 88)
+				{
+					for (i = 0; i < 44; i++)
+					{
+						FileBuffArray[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]);
+					}
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+					Flash_WriteBytes(FileBuffArray, StartMode_Addr + 4, 44);
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+					delay_sys_us(80);
+					packIndexbak = 0;
+					AddrToWrite = Application_Buffer_Addr;
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+				}
+				else
+				{
+					if(packIndexbak>1)
+						packIndexbak-=1;
+				}
+
+				{
+					static uint16_t txLen;
+					for (i = 0; i < 1024; i++)
+					{
+						USART2_RX_BUF002[i] = 0;
+					}
+					txLen = sprintf((char *)FileBuffArray, "file=%d\r\n", packIndexbak);
+//					HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+					delay_sys_us(80);
+					HAL_UART_Transmit_IT(&huart1,(unsigned char *)FileBuffArray,txLen);		
+					while (huart1.gState == HAL_UART_STATE_BUSY_TX)
+					{
+						HAL_Delay(1);
+					}
+					delay_sys_us(80);
+					delay_sys_us(80);
+//					HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+				}
+			}
+			else
+			{
+				for (i = 0; i < 1024; i++)
+				{
+					USART2_RX_BUF002[i] = 0;
+				}
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+				delay_sys_us(80);
+				HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100);
+				delay_sys_us(80);
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+				__NOP();
+			}
+			__NOP();
+		}
+		else
+		{
+			__NOP();
+		}
+		break;
+	case 0x02:														//有效载荷帧数据处理
+		crcIAP = LIB_CRC_MODBUS(&USART2_RX_BUF002[4], lenRx1 - 10); //
+		crcTerminal = (USART2_RX_BUF002[lenRx1 - 5] << 8) + USART2_RX_BUF002[lenRx1 - 6];
+		if ((crcIAP == crcTerminal) && (((packIndexbak + 1) == packIndex) || ((packIndexbak) == packIndex)))
+		{
+			if ((packIndexbak + 1) == packIndex)
+			{
+				lenRx2 = (lenRx1 - 15) % 2;
+				if (!lenRx2)
+				{
+					for (i = 0; i < ((lenRx1 - 15) / 2); i++)
+					{
+						FileBuffArray[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]);
+						FileBuffArray1[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]);
+					}
+					Flash_WriteBytes(FileBuffArray, AddrToWrite, ((lenRx1 - 15) / 2));
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+					Flash_ReadBytes(FileBuffArray1, AddrToWrite, ((lenRx1 - 15) / 2));
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+				}
+				else
+				{
+					for (i = 0; i < ((lenRx1 - 16) / 2); i++)
+					{
+						FileBuffArray[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]);
+						FileBuffArray1[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]);
+					}
+					FileBuffArray[(lenRx1 - 16) / 2] = USART2_RX_BUF002[(lenRx1 - 16 + 10)] << 8;
+					FileBuffArray1[(lenRx1 - 16) / 2] = USART2_RX_BUF002[(lenRx1 - 16 + 10)] << 8;
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+					Flash_WriteBytes(FileBuffArray, AddrToWrite, ((lenRx1 - 15 + 1) / 2));
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+					Flash_ReadBytes(FileBuffArray1, AddrToWrite, ((lenRx1 - 15 + 1) / 2));
+					HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+				}
+				AddrToWrite += lenRx1 - 15;
+				DataReadFlash = *((uint32_t *)(AddrToWrite));
+				DataReadFlash1 = (*(__IO uint32_t *)AddrToWrite);
+				HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+			}
+			if (DataReadFlash == DataReadFlash1)
+			{
+				__NOP();
+				HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
+				packIndexbak = packIndex;
+			}
+
+			{
+				int txLen;
+				for (i = 0; i < 1024; i++)
+				{
+					USART2_RX_BUF002[i] = 0;
+				}
+				txLen = sprintf((char *)USART2_RX_BUF002, "%s=%d\r\n", ACK_Arr, packIndex);
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+				delay_sys_us(80);
+				HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen);		
+				while (huart1.gState == HAL_UART_STATE_BUSY_TX)
+				{
+					delay_sys_us(1);
+				}
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+			}
+			__NOP();
+		}
+		else
+		{
+//			HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+			delay_sys_us(80);
+			HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100);
+			delay_sys_us(80);
+//			HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+			__NOP();
+		}
+		break;
+	case 3:
+		//	if(packIndex>2)
+		{														 //结束帧处理
+			int i,all_len;
+			crcIAP1 = LIB_CRC_MODBUS(&USART2_RX_BUF002[4], 133); //
+			crcTerminal = (USART2_RX_BUF002[lenRx1 - 5] << 8) + USART2_RX_BUF002[lenRx1 - 6];
+			if (crcIAP1 == crcTerminal)
+			{
+				int txLen;
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+				delay_sys_us(80);
+				txLen = sprintf((char *)USART2_RX_BUF002, "%s\r\n", ACK_Arr);
+				HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen);		
+				while (huart1.gState == HAL_UART_STATE_BUSY_TX)
+				{
+					delay_sys_us(1);
+				}
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+				for (i = 0, all_len = 0; i < 4; ++i)
+				{
+					all_len = all_len << 8;
+					all_len |= *(unsigned char *)(StartMode_Addr + 68 + i);
+				}
+			if (1)//App2_MD5_Check(Application_Buffer_Addr,all_len))
+			{
+				txLen = sprintf((char *)USART2_RX_BUF002, "md5 check=ok\r\n");
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+				delay_sys_us(80);
+				HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen);		
+				while (huart1.gState == HAL_UART_STATE_BUSY_TX)
+				{
+					delay_sys_us(1);
+				}
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+				Set_Update_Down(); //设定标志位  下次启动时进行程序拷贝
+			}
+			else
+			{
+				txLen = sprintf((char *)USART2_RX_BUF002,"md5 check=error\r\n");
+			}
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+				delay_sys_us(80);
+				HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen);		
+				while (huart1.gState == HAL_UART_STATE_BUSY_TX)
+				{
+					delay_sys_us(1);
+				}
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+			}
+			else
+			{
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); //
+				delay_sys_us(80);
+				HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100);
+				delay_sys_us(80);
+//				HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); //
+				__NOP();
+			}
+			__NOP();
+		}
+		break;
+	default:
+		break;
+	}
+}
+

+ 374 - 197
Core/Src/main.c

@@ -36,13 +36,6 @@
 
 /* Private define ------------------------------------------------------------*/
 /* USER CODE BEGIN PD */
-int fputc(int ch, FILE *f)
-{
-    uint8_t temp[10] = {ch};
-    HAL_UART_Transmit(&huart1, temp,1, 2);
-    HAL_UART_Transmit(&huart3, temp,1, 2);
-    return ch;
-}
 /* USER CODE END PD */
 
 /* Private macro -------------------------------------------------------------*/
@@ -64,12 +57,105 @@ uint16_t Adc3_CalibrationValue ;
 uint8_t		Rx_Flag = 0;
 uint16_t	Rx_Len = 0;
 uint8_t		Rx_Buf[Rx_Max] = {0};	
+uint8_t gpioaStatus = 0;
+uint8_t gpiobStatus = 0;
+
+uint8_t bufMain[128];
+int spr000;
 /* USER CODE END PV */
 
 /* Private function prototypes -----------------------------------------------*/
 void SystemClock_Config(void);
 /* USER CODE BEGIN PFP */
+#ifdef iap_
+
+typedef struct _T2C_RemoteCaliData
+{
+	uint16_t   FrameHead;   		//帧头 0-1
+	uint32_t   AddrExtModule; 	//4字节扩展地址   2--5
+	uint16_t   FunctionCode;		//功能码2字节   只能是0x0003、0x0006或者0x0010    6--7
+	uint16_t   AddrRegStart;		//寄存器起始地址2字节:合法范围为0x0000~0xffff    8--9
+	uint16_t   NumberOfRegs;		//数据个数2字节:最多读取0xffff字节;实际取决于终端限制,目前为256字节  10--11
+	uint32_t   ReserveData001;	//保留字4字节 12--15
+	uint8_t    PayLoadData[44+32+32];	//有效载荷具体有三种:44,或者76字节,或者108字节;字节 16--59
+	uint16_t   ReserveData002;	//保留字2字节    60--61
+	uint16_t   CheckSum;				//校验2字节      62--63
+}sT2C_RemoteCaliDat;
+
+typedef struct{
+	uint16_t USE_RKG;								//控制器占用人孔盖总线
+	uint16_t USE_XYF;								//控制器占用卸油阀总线
+	uint16_t KZQ_ErrorCnt;					//校验错误计数
+	uint16_t KZQ_Error;							//控制器通信错误
+	uint8_t sensor_addr;						//操作的传感器地址
+	uint8_t sensor_RW;							//操作的传感器读写属性
+	uint16_t sensor_reg;							//操作的传感器寄存器地址,即功能码
+	uint8_t sensor_datelen;					//操作数据长度
+	uint8_t data_buf[70];          //下发数据缓存 
+}KZQ_Inf;
+#define 	ADDR_Is_In_ElecFence	0x05D0	//	1488		车是否在电子围栏内
+
+
+
+ sT2C_RemoteCaliDat T2C_RemoteCaliDat001  =
+{
+ 
+	0x3901,
+	0x9551000,
+	0x0003,
+	ADDR_Is_In_ElecFence,//0x0000,
+	0x0001,        //操作的数据个数
+	0x55aa55aa,    //保留字4字节
+	{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,\
+	25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44},
+	0x7788,//保留字2字节
+	0x99aa   //校验2字节
+};
+sT2C_RemoteCaliDat *pT2C_RemoteCaliData = &T2C_RemoteCaliDat001; 
+
+	uint8_t CMD_KZQ[256] =
+	{0x39,0x01,0x95,0x50,0x00,0x01,0x00,0x03,
+	0x00,0x00,0x00,0x00,0x95,0x05,0xaa,0xaa,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	};
+	int flagU2Rx=0;
+	int data_lengthU2;
+	uint8_t* ptx = CMD_KZQ;   
+	uint16_t ModbusCRC = 0,SetSuccess = 0,ModbusCRC1 = 0,SetSuccess1 = 0,SetSuccess2=0,SetSuccess3=0;                 
+
+	int i000;
+	uint8_t* send_ptr;
+	uint16_t send_len;
+	uint32_t tmpU32;
+	KZQ_Inf kzq_inf;
+	KZQ_Inf* pkzq = &kzq_inf;
+	uint8_t USART2_RX_BUF003[128];
+	uint8_t F_STATE[70] = {0};
+	uint8_t ptxCang01Temp[150];
+	uint32_t KZQ_RTerror = 0;
+	
+void RstCPU(void)
+{
+  uint16_t j;
+  __disable_irq();
+	
+	while(1)
+	{
+		__disable_irq();	
+		NVIC_SystemReset();  
+		while(j --)
+		{
+	    __nop(); __nop(); __nop(); __nop(); 
+		}
+	}
+}
 
+#endif
 /* USER CODE END PFP */
 
 /* Private user code ---------------------------------------------------------*/
@@ -84,7 +170,13 @@ void SystemClock_Config(void);
 int main(void)
 {
   /* USER CODE BEGIN 1 */
+#if	IR_ROM1 == 0x08000000	
+	Start_BootLoader();
+#else	
+	SCB->VTOR = FLASH_BASE | ADD_UPDATE_PROG; 
+	__set_PRIMASK(0);
 
+#endif	
   /* USER CODE END 1 */
 
   /* MCU Configuration--------------------------------------------------------*/
@@ -117,7 +209,11 @@ int main(void)
   update_baudrate(read_flash_16(ADDR_FLASH_PAGE_114));
   AdcCalibration_init();
   
-  HAL_UART_Receive_DMA(&huart1, Rx_Buf, Rx_Max);  
+  
+  spr000=sprintf((char*)bufMain,"system reset...%5d",5);
+  HAL_UART_Transmit(&huart1,bufMain,spr000,300);
+  
+  HAL_UART_Receive_DMA(&huart1,USART2_RX_BUF,Uart2_BUF_SIZE); 
   __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 
   /* USER CODE END 2 */
 
@@ -125,7 +221,228 @@ int main(void)
   /* USER CODE BEGIN WHILE */
   while (1)
   { 
-	if (Rx_Flag == 1 && (calculate_crc(Rx_Buf,6) == (Rx_Buf[7] << 8 | Rx_Buf[6]))) {		
+	ModBus();
+	#ifdef iap_
+	 if (flagU2Rx == 1 && (USART2_RX_BUF002[0] == 0xa5) && (USART2_RX_BUF002[1] == 0x5a))
+	{
+		flagU2Rx = 0;
+		if ((data_lengthU2 > 300) || ((USART2_RX_BUF002[0] == 0xa5) && (USART2_RX_BUF002[1] == 0x5a)))
+		{
+			tmpU32 = (USART2_RX_BUF002[0] << 24) | (USART2_RX_BUF002[1] << 16) | (USART2_RX_BUF002[2] << 8) | (USART2_RX_BUF002[3]);
+			if (StartBytes_IAP == tmpU32)
+			{
+				Process_CMD_IAP_Update();
+				continue;
+			}
+		}
+		// KZQ_RTerror = 0;
+		// ASC转换为16进制,收到数据为:3901开头的数据总长度131字节
+		if ((USART2_RX_BUF002[0] == 0x3A) && (USART2_RX_BUF002[1] == 0x33) && (USART2_RX_BUF002[2] == 0x39) && (USART2_RX_BUF002[3] == 0x30)) //判断帧头
+		{
+			if (data_lengthU2 != 131)
+			{
+				++KZQ_RTerror;
+				continue;
+			}
+			for (i000 = 0; i000 < (data_lengthU2 - 3) / 2; i000++)
+			{
+				T2C_RemoteCaliDat001.PayLoadData[i000] = MODBUS_ASCII_AsciiToHex(USART2_RX_BUF002 + 1 + 0 + i000 * 2);
+
+				USART2_RX_BUF003[i000] = MODBUS_ASCII_AsciiToHex(USART2_RX_BUF002 + 1 + 0 + i000 * 2);
+			}
+			//解析后的数据拷贝过来
+			memcpy(USART2_RX_BUF002, USART2_RX_BUF003, (data_lengthU2 - 3) / 2);
+			data_lengthU2 = (data_lengthU2 - 3) / 2;
+		}
+		if (data_lengthU2 < 5)
+			continue;
+		ModbusCRC = USART2_RX_BUF002[data_lengthU2 - 1] << 8;
+		ModbusCRC |= USART2_RX_BUF002[data_lengthU2 - 2];
+		ModbusCRC1 = LIB_CRC_MODBUS(USART2_RX_BUF002, data_lengthU2 - 2);
+
+		if ((USART2_RX_BUF002[0] != 0x39) && (USART2_RX_BUF002[1] <= 0x01) && (USART2_RX_BUF002[2] <= 0x95) && (USART2_RX_BUF002[3] <= 0x50)) //判断帧头
+		{
+			RstCPU();
+		}
+
+		
+	}
+#endif
+	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
+	HAL_Delay(1);  
+	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
+	
+	gpioaStatus = GetPaInputStatus();
+	gpiobStatus = GetPbOutputStatus();
+	GetADCResults(&hadc1); 
+	
+    /* USER CODE END WHILE */
+
+    /* USER CODE BEGIN 3 */
+  }
+  /* USER CODE END 3 */
+}
+
+/**
+  * @brief System Clock Configuration
+  * @retval None
+  */
+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.
+  */
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
+  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
+  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+  /** Initializes the CPU, AHB and APB buses clocks
+  */
+  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
+  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
+  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
+  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+  {
+    Error_Handler();
+  }
+}
+
+/* USER CODE BEGIN 4 */
+uint16_t read_flash_16(uint32_t addr){
+    uint16_t data = *(volatile uint16_t*)addr;     // 从Flash中读取2个字节
+    return data;
+}
+
+void read_new_address(uint32_t addr){
+		uint16_t init_address = read_flash_16(addr);
+	  if(init_address == 0xFFFF) {
+			initial_address = initial_address;
+		} else {
+			initial_address = init_address;  // 读取新地址并赋值给initial_address
+		}
+}
+
+void erase_flash(uint32_t ADDR_FLASH){                //进行擦除
+    FLASH_EraseInitTypeDef erase_init;
+    erase_init.TypeErase = FLASH_TYPEERASE_PAGES;  // 擦除类型为页擦除
+    erase_init.PageAddress = ADDR_FLASH;  
+    erase_init.NbPages = 1;  // 擦除的页数
+    uint32_t page_error = 0;
+    HAL_FLASH_Unlock();  // 解锁Flash
+    HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_init, &page_error);  // 执行擦除操作
+    HAL_FLASH_Lock();  // 上锁Flash
+    if(status == HAL_OK){
+        if(ADDR_FLASH == ADDR_FLASH_PAGE_94) {
+            initial_address = 0;         // 将initial_address清零
+        }
+        else if(ADDR_FLASH == ADDR_FLASH_PAGE_104) {
+            gpiobStatus = 0;             // 将pb_status清零
+        }
+        else if(ADDR_FLASH == ADDR_FLASH_PAGE_114) {
+            BaudrateValue = 0xFFFF;  
+        }
+        else if(ADDR_FLASH == ADDR_FLASH_PAGE_124) {
+            Adc2_CalibrationValue = 0x0000;  // 清零
+        }
+        else if(ADDR_FLASH == ADDR_FLASH_PAGE_134) {
+            Adc3_CalibrationValue = 0x0000;  // 清零
+        }
+        
+    }
+}
+
+void Write_Information(uint32_t addr, uint8_t* rx_buffer, uint8_t buffer_index) {
+    uint16_t newValue = 0;
+	  erase_flash(addr);
+    HAL_FLASH_Unlock();  // 解锁Flash
+	
+    if (addr == ADDR_FLASH_PAGE_94) {  // 写入地址到Flash
+        newValue = rx_buffer[buffer_index];
+        HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_94, newValue);
+        if (status == HAL_OK) {
+            initial_address = newValue;  // 将新地址赋值给initial_address
+        }
+    } 
+		else if (addr == ADDR_FLASH_PAGE_104) {  // 写入PB状态到Flash
+        newValue = rx_buffer[buffer_index];
+        HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_104, newValue);
+        if (status == HAL_OK) {
+            gpiobStatus = newValue;  // 将新状态赋值给gpiobStatus
+        }
+    } 
+		else if (addr == ADDR_FLASH_PAGE_114) {  // 写入波特率到Flash
+        newValue = rx_buffer[buffer_index];
+        HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_114, newValue);
+        if (status == HAL_OK) {
+            BaudrateValue = newValue;  // 将新状态赋值给BaudrateValue
+        }
+    } 
+		else if (addr == ADDR_FLASH_PAGE_124 || addr == ADDR_FLASH_PAGE_134) {  // 写入ADC校准值到Flash
+        uint16_t Standard_value = (0.6 / (3.3 / 4096));
+        if (addr == ADDR_FLASH_PAGE_124) {
+            if (adc2_rawValue >= Standard_value) {
+                newValue = adc2_rawValue - Standard_value;
+            } else {
+                newValue = Standard_value - adc2_rawValue;
+                newValue |= 0x8000;
+            }
+            HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_124, newValue);
+            if (status == HAL_OK) {
+                Adc2_CalibrationValue = newValue & 0x7FFF;
+							  Value_old_addr2 = newValue;
+            }
+        } else if (addr == ADDR_FLASH_PAGE_134) {
+            if (adc3_rawValue >= Standard_value) {
+                newValue = adc3_rawValue - Standard_value;
+            } else {
+                newValue = Standard_value - adc3_rawValue;
+                newValue |= 0x8000;
+            }
+            HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_134, newValue);
+            if (status == HAL_OK) {
+                Adc3_CalibrationValue = newValue & 0x7FFF;
+							  Value_old_addr3 = newValue;
+            }
+        }
+    }
+    
+		HAL_FLASH_Lock();  // 上锁Flash
+}
+
+
+void delay_sys_us(uint32_t Delay)//1个delay,大概1.5us
+{
+	uint32_t cnt = Delay * 8;  
+    uint32_t i = 0;
+    for(i = 0; i < cnt; i++)__NOP();
+}
+
+
+void ModBus(void) {
+	
+	if (Rx_Flag == 1 && (calculate_crc(Rx_Buf,6) == (Rx_Buf[7] << 8 | Rx_Buf[6])) && data_lengthU2 < 10) {		
 		if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x01 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
 			
 			uint8_t data_to_send[] = {(uint8_t)initial_address, 0x03, 0x02, 0x00, gpioaStatus, 0x00, 0x00};
@@ -134,9 +451,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_UART_Transmit(&huart1, data_to_send, 7, 6);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x02 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
@@ -147,9 +465,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_UART_Transmit(&huart1, data_to_send, 7, 6);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 				
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x03 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){	
@@ -160,9 +479,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_UART_Transmit(&huart1, data_to_send, 7, 6);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 				
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x04 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
@@ -173,9 +493,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_UART_Transmit(&huart1, data_to_send, 7, 6);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 				
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x05 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
@@ -186,9 +507,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 7, 6);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x01 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x02){
@@ -199,9 +521,10 @@ int main(void)
 			data_to_send[8] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 9, 8);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x01 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x03){
@@ -212,9 +535,10 @@ int main(void)
 			data_to_send[10] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 11, 10);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x01 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x04){
@@ -225,9 +549,10 @@ int main(void)
 			data_to_send[12] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 13, 12);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 				
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x01 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x05){
@@ -238,9 +563,10 @@ int main(void)
 			data_to_send[14] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 15, 14);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}  
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x02 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x02){
@@ -251,9 +577,10 @@ int main(void)
 			data_to_send[8] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 9, 8);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}  
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x02 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x03){
@@ -264,9 +591,10 @@ int main(void)
 			data_to_send[10] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 11, 10);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}  
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x02 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x04){
@@ -277,9 +605,10 @@ int main(void)
 			data_to_send[12] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 13, 12);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}       
 				
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x03 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x02){
@@ -290,9 +619,10 @@ int main(void)
 			data_to_send[8] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 9, 8);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}  
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x03 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x03){
@@ -303,9 +633,10 @@ int main(void)
 			data_to_send[10] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 11, 10);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		} 
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x04 && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x02){
@@ -316,12 +647,13 @@ int main(void)
 			data_to_send[8] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 9, 8);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}   
 		
-		else if((Rx_Buf[0] == (uint8_t)initial_address || Rx_Buf[0] == 0xFA) && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0xAA && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
+		else if(Rx_Buf[0] == 0xFA && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0xAA && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
 
 			uint8_t data_to_send[] = {0xFA, 0x03, 0x02, 0x00, (uint8_t)initial_address, 0x00, 0x00};
 			uint16_t CRC_value = calculate_crc(data_to_send, 5);
@@ -329,9 +661,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 7, 6);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		} 
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x03 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0xBB && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x02){
@@ -342,9 +675,10 @@ int main(void)
 			data_to_send[8] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 9, 8);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x06 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x02 && Rx_Buf[4] == 0x00){
@@ -357,9 +691,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 7, 7);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		} 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x06 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x0A && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
 
@@ -371,9 +706,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 7, 7);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}    
 				
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x06 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x0B && Rx_Buf[4] == 0x00 && Rx_Buf[5] == 0x01){
@@ -386,9 +722,10 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 7, 7);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}   
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x06 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0x0C && Rx_Buf[4] == 0x00){
@@ -401,9 +738,10 @@ int main(void)
 			data_to_send[7] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 8, 8);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf)); 
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}  
 		
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x06 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0xAA && Rx_Buf[4] == 0x00){
@@ -415,189 +753,28 @@ int main(void)
 			data_to_send[6] = (uint8_t)(CRC_value >> 8);
 			HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, data_to_send, 7, 7);
 			memset(Rx_Buf, 0, sizeof(Rx_Buf));
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}   
 
 		else if(Rx_Buf[0] == (uint8_t)initial_address && Rx_Buf[1] == 0x06 && Rx_Buf[2] == 0x00 && Rx_Buf[3] == 0xCC && Rx_Buf[4] == 0xA5 && Rx_Buf[5] == 0x5A){
 			Rx_Flag = 0; // 将标志位重新置为0
 			memset(Rx_Buf,0,sizeof(Rx_Buf));
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE); 
 			HAL_NVIC_SystemReset();
 		}	
 		else {
 			memset(Rx_Buf, 0, sizeof(Rx_Buf));
+			memset(USART2_RX_BUF, 0, Uart2_BUF_SIZE);  
 			Rx_Flag = 0;	
 			HAL_UART_AbortReceive(&huart1);
-			HAL_UART_Receive_DMA(&huart1, Rx_Buf, sizeof(Rx_Buf)); 
+			HAL_UART_Receive_DMA(&huart1, USART2_RX_BUF, Uart2_BUF_SIZE); 
 		}
 	}
-		
-	gpioaStatus = GetPaInputStatus();
-	gpiobStatus = GetPbOutputStatus();
-	GetADCResults(&hadc1);
 	
-	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
-	HAL_Delay(1);  
-	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
-	
-	HAL_UART_Receive_DMA(&huart1,Rx_Buf,Rx_Max);
-
-    /* USER CODE END WHILE */
-
-    /* USER CODE BEGIN 3 */
-  }
-  /* USER CODE END 3 */
-}
-
-/**
-  * @brief System Clock Configuration
-  * @retval None
-  */
-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.
-  */
-  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
-  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
-  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
-  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
-  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
-  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
-  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
-  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
-  {
-    Error_Handler();
-  }
-
-  /** Initializes the CPU, AHB and APB buses clocks
-  */
-  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
-                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
-  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
-  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
-  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
-  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
-  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
-  {
-    Error_Handler();
-  }
-  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
-  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
-  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
-  {
-    Error_Handler();
-  }
-}
-
-/* USER CODE BEGIN 4 */
-uint16_t read_flash_16(uint32_t addr){
-    uint16_t data = *(volatile uint16_t*)addr;     // 从Flash中读取2个字节
-    return data;
 }
-
-void read_new_address(uint32_t addr){
-		uint16_t init_address = read_flash_16(addr);
-	  if(init_address == 0xFFFF) {
-			initial_address = initial_address;
-		} else {
-			initial_address = init_address;  // 读取新地址并赋值给initial_address
-		}
-}
-
-void erase_flash(uint32_t ADDR_FLASH){                //进行擦除
-    FLASH_EraseInitTypeDef erase_init;
-    erase_init.TypeErase = FLASH_TYPEERASE_PAGES;  // 擦除类型为页擦除
-    erase_init.PageAddress = ADDR_FLASH;  
-    erase_init.NbPages = 1;  // 擦除的页数
-    uint32_t page_error = 0;
-    HAL_FLASH_Unlock();  // 解锁Flash
-    HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_init, &page_error);  // 执行擦除操作
-    HAL_FLASH_Lock();  // 上锁Flash
-    if(status == HAL_OK){
-        if(ADDR_FLASH == ADDR_FLASH_PAGE_94) {
-            initial_address = 0;         // 将initial_address清零
-        }
-        else if(ADDR_FLASH == ADDR_FLASH_PAGE_104) {
-            gpiobStatus = 0;             // 将pb_status清零
-        }
-        else if(ADDR_FLASH == ADDR_FLASH_PAGE_114) {
-            BaudrateValue = 0xFFFF;  
-        }
-        else if(ADDR_FLASH == ADDR_FLASH_PAGE_124) {
-            Adc2_CalibrationValue = 0x0000;  // 清零
-        }
-        else if(ADDR_FLASH == ADDR_FLASH_PAGE_134) {
-            Adc3_CalibrationValue = 0x0000;  // 清零
-        }
-        
-    }
-}
-
-void Write_Information(uint32_t addr, uint8_t* rx_buffer, uint8_t buffer_index) {
-    uint16_t newValue = 0;
-	  erase_flash(addr);
-    HAL_FLASH_Unlock();  // 解锁Flash
-	
-    if (addr == ADDR_FLASH_PAGE_94) {  // 写入地址到Flash
-        newValue = rx_buffer[buffer_index];
-        HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_94, newValue);
-        if (status == HAL_OK) {
-            initial_address = newValue;  // 将新地址赋值给initial_address
-        }
-    } 
-		else if (addr == ADDR_FLASH_PAGE_104) {  // 写入PB状态到Flash
-        newValue = rx_buffer[buffer_index];
-        HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_104, newValue);
-        if (status == HAL_OK) {
-            gpiobStatus = newValue;  // 将新状态赋值给gpiobStatus
-        }
-    } 
-		else if (addr == ADDR_FLASH_PAGE_114) {  // 写入波特率到Flash
-        newValue = rx_buffer[buffer_index];
-        HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_114, newValue);
-        if (status == HAL_OK) {
-            BaudrateValue = newValue;  // 将新状态赋值给BaudrateValue
-        }
-    } 
-		else if (addr == ADDR_FLASH_PAGE_124 || addr == ADDR_FLASH_PAGE_134) {  // 写入ADC校准值到Flash
-        uint16_t Standard_value = (0.6 / (3.3 / 4096));
-        if (addr == ADDR_FLASH_PAGE_124) {
-            if (adc2_rawValue >= Standard_value) {
-                newValue = adc2_rawValue - Standard_value;
-            } else {
-                newValue = Standard_value - adc2_rawValue;
-                newValue |= 0x8000;
-            }
-            HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_124, newValue);
-            if (status == HAL_OK) {
-                Adc2_CalibrationValue = newValue & 0x7FFF;
-							  Value_old_addr2 = newValue;
-            }
-        } else if (addr == ADDR_FLASH_PAGE_134) {
-            if (adc3_rawValue >= Standard_value) {
-                newValue = adc3_rawValue - Standard_value;
-            } else {
-                newValue = Standard_value - adc3_rawValue;
-                newValue |= 0x8000;
-            }
-            HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ADDR_FLASH_PAGE_134, newValue);
-            if (status == HAL_OK) {
-                Adc3_CalibrationValue = newValue & 0x7FFF;
-							  Value_old_addr3 = newValue;
-            }
-        }
-    }
-    
-		HAL_FLASH_Lock();  // 上锁Flash
-}
-
 /* USER CODE END 4 */
 
 /**

+ 341 - 0
Core/Src/md5c.c

@@ -0,0 +1,341 @@
+
+#include "md5c.h" 
+#include <string.h> 
+#include <stdio.h> 
+ 
+/* Constants for MD5Transform routine. 
+*/ 
+ 
+ 
+#define S11 7 
+#define S12 12 
+#define S13 17 
+#define S14 22 
+#define S21 5 
+#define S22 9 
+#define S23 14 
+#define S24 20 
+#define S31 4 
+#define S32 11 
+#define S33 16 
+#define S34 23 
+#define S41 6 
+#define S42 10 
+#define S43 15 
+#define S44 21 
+ 
+static void MD5_memcpy (POINTER output, POINTER input, unsigned int len); 
+static void MD5Transform (UINT4 state[4], unsigned char block[64]); 
+static void Encode (unsigned char *output, UINT4 *input, unsigned int len); 
+static void MD5_memset (POINTER output, int value, unsigned int len); 
+static void Decode (UINT4 *output, unsigned char *input, unsigned int len); 
+ 
+static unsigned char PADDING[64] = { 
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
+}; 
+ 
+/* F, G, H and I are basic MD5 functions. 
+*/ 
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 
+#define H(x, y, z) ((x) ^ (y) ^ (z)) 
+#define I(x, y, z) ((y) ^ ((x) | (~z))) 
+ 
+/* ROTATE_LEFT rotates x left n bits. 
+*/ 
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 
+ 
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 
+Rotation is separate from addition to prevent recomputation. 
+*/ 
+#define FF(a, b, c, d, x, s, ac) { \
+	(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ } 
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ } 
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ } 
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ } 
+ 
+/* MD5 initialization. Begins an MD5 operation, writing a new context. 
+ */ 
+void MD5Init (MD5_CTX *context)          /* context */ 
+{ 
+ context->count[0] = context->count[1] = 0; 
+ /* Load magic initialization constants. 
+ */ 
+ context->state[0] = 0x67452301; 
+ context->state[1] = 0xefcdab89; 
+ context->state[2] = 0x98badcfe; 
+ context->state[3] = 0x10325476; 
+} 
+ 
+/* MD5 block update operation. Continues an MD5 message-digest 
+ operation, processing another message block, and updating the 
+ context. 
+ */ 
+void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen) 
+ 
+{ 
+ unsigned int i, index, partLen; 
+ 
+ /* Compute number of bytes mod 64 */ 
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F); 
+ 
+ /* Update number of bits */ 
+ if ((context->count[0] += ((UINT4)inputLen << 3)) 
+  < ((UINT4)inputLen << 3)) 
+  context->count[1]++; 
+ context->count[1] += ((UINT4)inputLen >> 29); 
+ 
+ partLen = 64 - index; 
+ 
+ /* Transform as many times as possible. 
+ */ 
+ if (inputLen >= partLen) { 
+  MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); 
+  MD5Transform (context->state, context->buffer); 
+ 
+  for (i = partLen; i + 63 < inputLen; i += 64) 
+   MD5Transform (context->state, &input[i]); 
+ 
+  index = 0; 
+ } 
+ else 
+  i = 0; 
+ 
+ /* Buffer remaining input */ 
+ MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i); 
+} 
+ 
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the 
+ the message digest and zeroizing the context. 
+ */ 
+void MD5Final (unsigned char digest[16], MD5_CTX *context)         
+{ 
+ unsigned char bits[8]; 
+ unsigned int index, padLen; 
+ 
+ /* Save number of bits */ 
+ Encode (bits, context->count, 8); 
+ 
+ /* Pad out to 56 mod 64. 
+ */ 
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f); 
+ padLen = (index < 56) ? (56 - index) : (120 - index); 
+ MD5Update (context, PADDING, padLen); 
+ 
+ /* Append length (before padding) */ 
+ MD5Update (context, bits, 8); 
+ 
+ /* Store state in digest */ 
+ Encode (digest, context->state, 16); 
+ 
+ /* Zeroize sensitive information. 
+ */ 
+ MD5_memset ((POINTER)context, 0, sizeof (*context)); 
+} 
+ 
+/* MD5 basic transformation. Transforms state based on block. 
+ */ 
+static void MD5Transform (UINT4 state[4], unsigned char block[64]) 
+{ 
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 
+ 
+ Decode (x, block, 64); 
+ 
+ /* Round 1 */ 
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 
+ 
+ /* Round 2 */ 
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 
+ 
+ /* Round 3 */ 
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 
+ 
+ /* Round 4 */ 
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 
+ 
+ state[0] += a; 
+ state[1] += b; 
+ state[2] += c; 
+ state[3] += d; 
+ 
+ /* Zeroize sensitive information. 
+ */ 
+ MD5_memset ((POINTER)x, 0, sizeof (x)); 
+} 
+ 
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is 
+ a multiple of 4. 
+ */ 
+static void Encode (unsigned char *output, UINT4 *input, unsigned int len) 
+{ 
+ unsigned int i, j; 
+ 
+ for (i = 0, j = 0; j < len; i++, j += 4) { 
+  output[j] = (unsigned char)(input[i] & 0xff); 
+  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 
+  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 
+  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 
+ } 
+} 
+ 
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is 
+ a multiple of 4. 
+ */ 
+static void Decode (UINT4 *output, unsigned char *input, unsigned int len) 
+{ 
+ unsigned int i, j; 
+ 
+ for (i = 0, j = 0; j < len; i++, j += 4) 
+  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 
+  (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 
+} 
+ 
+/* Note: Replace "for loop" with standard memcpy if possible. 
+ */ 
+ 
+static void MD5_memcpy (POINTER output, POINTER input, unsigned int len) 
+{ 
+ unsigned int i; 
+ 
+ for (i = 0; i < len; i++) 
+  output[i] = input[i]; 
+} 
+ 
+/* Note: Replace "for loop" with standard memset if possible. 
+ */ 
+static void MD5_memset (POINTER output, int value, unsigned int len) 
+{ 
+ unsigned int i; 
+ 
+ for (i = 0; i < len; i++) 
+  ((char *)output)[i] = (char)value; 
+} 
+/* Digests a string and prints the result. 
+ */ 
+void MDString (char *string,unsigned char digest[16]) 
+{ 
+ MD5_CTX context; 
+ unsigned int len = strlen (string); 
+ 
+ MD5Init (&context); 
+ MD5Update (&context, (unsigned char *)string, len); 
+ MD5Final (digest, &context); 
+} 
+/* Digests a file and prints the result. 
+ */ 
+int MD5File (char *filename,unsigned char digest[16]) 
+{ 
+ FILE *file; 
+ MD5_CTX context; 
+ int len; 
+ unsigned char buffer[1024]; 
+ 
+ if ((file = fopen (filename, "rb")) == NULL) 
+  return -1; 
+ else { 
+  MD5Init (&context); 
+  while (len == fread (buffer, 1, 1024, file)) 
+   MD5Update (&context, buffer, len); 
+  MD5Final (digest, &context); 
+ 
+  fclose (file); 
+ } 
+ return 0; 
+} 
+void MD5UpdaterString(MD5_CTX *context,const char *string) 
+{ 
+ unsigned int len = strlen (string); 
+ MD5Update (context, (unsigned char *)string, len); 
+} 
+int MD5FileUpdateFile (MD5_CTX *context,char *filename) 
+{ 
+ FILE *file; 
+ int len; 
+ unsigned char buffer[1024]; 
+ 
+ if ((file = fopen (filename, "rb")) == NULL) 
+  return -1; 
+ else { 
+  while (len == fread (buffer, 1, 1024, file)) 
+   MD5Update (context, buffer, len); 
+  fclose (file); 
+ } 
+ return 0; 
+} 

+ 28 - 22
Core/Src/stm32f1xx_it.c

@@ -44,11 +44,8 @@
 
 /* Private variables ---------------------------------------------------------*/
 /* USER CODE BEGIN PV */
-uint8_t receive_buffer[30];  // 定义接收缓存,这里假设最多可以接收100个字节
-uint8_t flag = 0;
 
-uint8_t gpioaStatus = 0;
-uint8_t gpiobStatus = 0;
+
 /* USER CODE END PV */
 
 /* Private function prototypes -----------------------------------------------*/
@@ -64,9 +61,11 @@ uint8_t gpiobStatus = 0;
 /* External variables --------------------------------------------------------*/
 extern TIM_HandleTypeDef htim2;
 extern DMA_HandleTypeDef hdma_usart1_rx;
+extern DMA_HandleTypeDef hdma_usart3_rx;
 extern UART_HandleTypeDef huart1;
 extern UART_HandleTypeDef huart3;
 /* USER CODE BEGIN EV */
+extern uint8_t USART2_RX_BUF002[Uart2_BUF_SIZE];
 
 /* USER CODE END EV */
 
@@ -208,6 +207,20 @@ void SysTick_Handler(void)
 /* please refer to the startup file (startup_stm32f1xx.s).                    */
 /******************************************************************************/
 
+/**
+  * @brief This function handles DMA1 channel3 global interrupt.
+  */
+void DMA1_Channel3_IRQHandler(void)
+{
+  /* USER CODE BEGIN DMA1_Channel3_IRQn 0 */
+
+  /* USER CODE END DMA1_Channel3_IRQn 0 */
+  HAL_DMA_IRQHandler(&hdma_usart3_rx);
+  /* USER CODE BEGIN DMA1_Channel3_IRQn 1 */
+
+  /* USER CODE END DMA1_Channel3_IRQn 1 */
+}
+
 /**
   * @brief This function handles DMA1 channel5 global interrupt.
   */
@@ -229,7 +242,6 @@ void TIM2_IRQHandler(void)
 {
   /* USER CODE BEGIN TIM2_IRQn 0 */
   HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);
-
   /* USER CODE END TIM2_IRQn 0 */
   HAL_TIM_IRQHandler(&htim2);
   /* USER CODE BEGIN TIM2_IRQn 1 */
@@ -244,24 +256,18 @@ void USART1_IRQHandler(void)
 {
   /* USER CODE BEGIN USART1_IRQn 0 */
 
-	uint32_t temp;
-	if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))  
-	{   
-		/*清除状态寄存器和串口数据寄存器*/
-		__HAL_UART_CLEAR_IDLEFLAG(&huart1); 
-
-		/*失能DMA接收*/
+	if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))   //判断是否是空闲中断
+	{
+		__HAL_UART_CLEAR_IDLEFLAG(&huart1);                     //清楚空闲中断标志(否则会一直不断进入中断)
 		HAL_UART_DMAStop(&huart1);  
-
-		/*读取接收长度,总大小-剩余大小*/
-		temp = huart1.hdmarx->Instance->CNDTR; 
-		Rx_Len = Rx_Max - temp; 
-
-		/*接收标志位置1*/
-		Rx_Flag=1;  
-
-		/*使能接收DMA接收*/
-		HAL_UART_Receive_DMA(&huart1,Rx_Buf,Rx_Max);  
+		data_lengthU2  = Uart2_BUF_SIZE - hdma_usart1_rx.Instance->CNDTR;
+		memcpy(USART2_RX_BUF002,USART2_RX_BUF,data_lengthU2);	
+		
+		memcpy(Rx_Buf,USART2_RX_BUF,data_lengthU2);	
+		
+		HAL_UART_Receive_DMA(&huart1,USART2_RX_BUF,Uart2_BUF_SIZE); 
+		Rx_Flag = 1;
+		flagU2Rx =1;
 	}
   /* USER CODE END USART1_IRQn 0 */
   HAL_UART_IRQHandler(&huart1);

+ 123 - 0
Core/Src/stmflash.c

@@ -0,0 +1,123 @@
+#include "stmflash.h"
+#include "usart.h"
+
+uint16_t STMFLASH_ReadHalfWord(uint32_t faddr)
+{
+	return *(uint16_t*)faddr; 
+}
+#if STM32_FLASH_WREN	//如果使能了写   
+//不检查的写入
+//WriteAddr:起始地址
+//pBuffer:数据指针
+//NumToWrite:半字(16位)数   
+void STMFLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)   
+{ 			 		 
+	uint16_t i;
+	for(i=0;i<NumToWrite;i++)
+	{
+		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);
+	  WriteAddr+=2;//地址增加2.
+	}  
+} 
+//从指定地址开始写入指定长度的数据
+//WriteAddr:起始地址(此地址必须为2的倍数!!)
+//pBuffer:数据指针
+//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
+#if STM32_FLASH_SIZE<256
+#define STM_SECTOR_SIZE 1024 //字节
+#else 
+#define STM_SECTOR_SIZE	2048
+#endif		 
+uint16_t STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节
+void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)	
+{
+	uint32_t secpos;	   //扇区地址
+	uint16_t secoff;	   //扇区内偏移地址(16位字计算)
+	uint16_t secremain; //扇区内剩余地址(16位字计算)	   
+ 	uint16_t i;    
+	uint32_t offaddr;   //去掉0X08000000后的地址
+	
+	if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
+	
+	HAL_FLASH_Unlock();					//解锁
+	offaddr=WriteAddr-STM32_FLASH_BASE;		//实际偏移地址.
+	secpos=offaddr/STM_SECTOR_SIZE;			//扇区地址  0~127 for STM32F103RBT6
+	secoff=(offaddr%STM_SECTOR_SIZE)/2;		//在扇区内的偏移(2个字节为基本单位.)
+	secremain=STM_SECTOR_SIZE/2-secoff;		//扇区剩余空间大小   
+	if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
+	while(1) 
+	{	
+		STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
+		for(i=0;i<secremain;i++)	//校验数据
+		{
+			if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除  	  
+		}
+		if(i<secremain)				//需要擦除
+		{
+			FLASH_PageErase(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);	//擦除这个扇区
+			FLASH_WaitForLastOperation(FLASH_WAITETIME);            	//等待上次操作完成
+			CLEAR_BIT(FLASH->CR, FLASH_CR_PER);							//清除CR寄存器的PER位,此操作应该在FLASH_PageErase()中完成!
+																		//但是HAL库里面并没有做,应该是HAL库bug!
+			for(i=0;i<secremain;i++)//复制
+			{
+				STMFLASH_BUF[i+secoff]=pBuffer[i];	  
+			}
+			STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区  
+		}else 
+		{
+			FLASH_WaitForLastOperation(FLASH_WAITETIME);       	//等待上次操作完成
+			STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间. 
+		}
+		if(NumToWrite==secremain)break;//写入结束了
+		else//写入未结束
+		{
+			secpos++;				//扇区地址增1
+			secoff=0;				//偏移位置为0 	 
+		   	pBuffer+=secremain;  	//指针偏移
+			WriteAddr+=secremain*2;	//写地址偏移(16位数据地址,需要*2)	   
+		   	NumToWrite-=secremain;	//字节(16位)数递减
+			if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
+			else secremain=NumToWrite;//下一个扇区可以写完了
+		}	 
+	};	
+	HAL_FLASH_Lock();		//上锁
+}
+#endif
+
+//从指定地址开始读出指定长度的数据
+//ReadAddr:起始地址
+//pBuffer:数据指针
+//NumToWrite:半字(16位)数
+void STMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead)   	
+{
+	uint16_t i;
+	for(i=0;i<NumToRead;i++)
+	{
+		pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
+		ReadAddr+=2;//偏移2个字节.	
+	}
+}
+
+//////////////////////////////////////////测试用///////////////////////////////////////////
+//WriteAddr:起始地址
+//WriteData:要写入的数据
+void Test_Write(uint32_t WriteAddr,uint16_t WriteData)   	
+{
+	STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字 
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 122 - 1
Core/Src/usart.c

@@ -22,11 +22,73 @@
 
 /* USER CODE BEGIN 0 */
 
+static const char LIB_CRC_MODBUS_HI[] =
+{
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
+    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
+    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
+    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+};
+
+static const char LIB_CRC_MODBUS_LO[] =
+{
+    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
+    0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
+    0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
+    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
+    0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
+    0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
+    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
+    0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
+    0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
+    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
+    0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
+    0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
+    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
+    0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
+    0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
+    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
+    0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
+    0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
+    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
+    0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
+    0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
+    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
+    0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
+    0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
+    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
+    0x43, 0x83, 0x41, 0x81, 0x80, 0x40
+};
+uint8_t USART2_RX_BUF[Uart2_BUF_SIZE];
+uint8_t USART2_RX_BUF002[Uart2_BUF_SIZE];
 /* USER CODE END 0 */
 
 UART_HandleTypeDef huart1;
 UART_HandleTypeDef huart3;
 DMA_HandleTypeDef hdma_usart1_rx;
+DMA_HandleTypeDef hdma_usart3_rx;
 
 /* USART1 init function */
 
@@ -132,7 +194,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
     __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
 
     /* USART1 interrupt Init */
-    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
+    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
     HAL_NVIC_EnableIRQ(USART1_IRQn);
   /* USER CODE BEGIN USART1_MspInit 1 */
 
@@ -161,6 +223,23 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
+    /* USART3 DMA Init */
+    /* USART3_RX Init */
+    hdma_usart3_rx.Instance = DMA1_Channel3;
+    hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+    hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+    hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
+    hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+    hdma_usart3_rx.Init.Mode = DMA_NORMAL;
+    hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
+    if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
+    {
+      Error_Handler();
+    }
+
+    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);
+
     /* USART3 interrupt Init */
     HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(USART3_IRQn);
@@ -210,6 +289,9 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
     */
     HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
 
+    /* USART3 DMA DeInit */
+    HAL_DMA_DeInit(uartHandle->hdmarx);
+
     /* USART3 interrupt Deinit */
     HAL_NVIC_DisableIRQ(USART3_IRQn);
   /* USER CODE BEGIN USART3_MspDeInit 1 */
@@ -248,4 +330,43 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
     __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE); // 清除接收中断标志位
     __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_ORE); // 清除接收溢出标志位
 }
+
+
+
+/*****************************************************************
+* 串口发送数组函数
+******************************************************************/
+void UartWrite(UART_HandleTypeDef *uartHandle, uint8_t *buf , uint8_t len)
+{
+    uint8_t i;
+    for(i = 0; i < len; i++)
+    {
+        HAL_UART_Transmit(uartHandle, &buf[i], 1, 0xFFFF);
+    }
+}
+// 重定向函数1
+int fputc(int ch,FILE *f)
+{
+    uint8_t temp[1]={ch};
+    HAL_UART_Transmit(&huart1,temp,1,2);        //
+    HAL_UART_Transmit(&huart3,temp,1,2);        //
+		return 0;
+}
+
+//16位modbusCRC校验
+uint16_t LIB_CRC_MODBUS(uint8_t* Buf, uint16_t srLen)
+{
+    uint32_t srIndex;
+    char ucHI = 0xFF;
+    char ucLO = 0xFF;
+
+    while(srLen--)
+    {
+        srIndex = ucHI ^ *Buf++;
+        ucHI = ucLO ^ LIB_CRC_MODBUS_HI[srIndex];
+        ucLO = LIB_CRC_MODBUS_LO[srIndex];
+    }
+
+    return ((uint16_t)ucHI<<8) + ucLO;
+}
 /* USER CODE END 1 */

BIN
Doc/新版采集通讯模块的软件设计概要性方案.pdf


File diff suppressed because it is too large
+ 128 - 101
MDK-ARM/iocollect.uvguix.Administrator


+ 83 - 77
MDK-ARM/iocollect.uvoptx

@@ -153,56 +153,7 @@
           <Name>-U-O142 -O2254 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_512 -FS08000000 -FL080000 -FP0($$Device:STM32F103RE$Flash\STM32F10x_512.FLM)</Name>
         </SetRegEntry>
       </TargetDriverDllRegistry>
-      <Breakpoint>
-        <Bp>
-          <Number>0</Number>
-          <Type>0</Type>
-          <LineNumber>135</LineNumber>
-          <EnabledFlag>1</EnabledFlag>
-          <Address>0</Address>
-          <ByteObject>0</ByteObject>
-          <HtxType>0</HtxType>
-          <ManyObjects>0</ManyObjects>
-          <SizeOfObject>0</SizeOfObject>
-          <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>0</BreakIfRCount>
-          <Filename>../Core/Src/main.c</Filename>
-          <ExecCommand></ExecCommand>
-          <Expression></Expression>
-        </Bp>
-        <Bp>
-          <Number>1</Number>
-          <Type>0</Type>
-          <LineNumber>155</LineNumber>
-          <EnabledFlag>1</EnabledFlag>
-          <Address>0</Address>
-          <ByteObject>0</ByteObject>
-          <HtxType>0</HtxType>
-          <ManyObjects>0</ManyObjects>
-          <SizeOfObject>0</SizeOfObject>
-          <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>0</BreakIfRCount>
-          <Filename>../Core/Src/main.c</Filename>
-          <ExecCommand></ExecCommand>
-          <Expression></Expression>
-        </Bp>
-        <Bp>
-          <Number>2</Number>
-          <Type>0</Type>
-          <LineNumber>153</LineNumber>
-          <EnabledFlag>1</EnabledFlag>
-          <Address>0</Address>
-          <ByteObject>0</ByteObject>
-          <HtxType>0</HtxType>
-          <ManyObjects>0</ManyObjects>
-          <SizeOfObject>0</SizeOfObject>
-          <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>0</BreakIfRCount>
-          <Filename>../Core/Src/main.c</Filename>
-          <ExecCommand></ExecCommand>
-          <Expression></Expression>
-        </Bp>
-      </Breakpoint>
+      <Breakpoint/>
       <WatchWindow1>
         <Ww>
           <count>0</count>
@@ -252,14 +203,21 @@
         <Ww>
           <count>9</count>
           <WinNumber>1</WinNumber>
-          <ItemText>temp</ItemText>
+          <ItemText>data_lengthU2</ItemText>
         </Ww>
         <Ww>
           <count>10</count>
           <WinNumber>1</WinNumber>
-          <ItemText>temp</ItemText>
+          <ItemText>USART2_RX_BUF</ItemText>
         </Ww>
       </WatchWindow1>
+      <WatchWindow2>
+        <Ww>
+          <count>0</count>
+          <WinNumber>2</WinNumber>
+          <ItemText>Rx_Buf</ItemText>
+        </Ww>
+      </WatchWindow2>
       <MemoryWindow1>
         <Mm>
           <WinNumber>1</WinNumber>
@@ -298,7 +256,7 @@
       <DebugFlag>
         <trace>0</trace>
         <periodic>1</periodic>
-        <aLwin>1</aLwin>
+        <aLwin>0</aLwin>
         <aCover>0</aCover>
         <aSer1>0</aSer1>
         <aSer2>0</aSer2>
@@ -377,6 +335,54 @@
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
+      <PathWithFileName>..\Core\Src\iap.c</PathWithFileName>
+      <FilenameWithoutPath>iap.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>3</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Core\Src\md5c.c</PathWithFileName>
+      <FilenameWithoutPath>md5c.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>4</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Core\Src\stmflash.c</PathWithFileName>
+      <FilenameWithoutPath>stmflash.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>5</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Core\Src\Data_deal.c</PathWithFileName>
+      <FilenameWithoutPath>Data_deal.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>6</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
       <PathWithFileName>../Core/Src/main.c</PathWithFileName>
       <FilenameWithoutPath>main.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
@@ -384,7 +390,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>3</FileNumber>
+      <FileNumber>7</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -396,7 +402,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>4</FileNumber>
+      <FileNumber>8</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -408,7 +414,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>5</FileNumber>
+      <FileNumber>9</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -420,7 +426,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>6</FileNumber>
+      <FileNumber>10</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -432,7 +438,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>7</FileNumber>
+      <FileNumber>11</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -444,7 +450,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>8</FileNumber>
+      <FileNumber>12</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -456,7 +462,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>9</FileNumber>
+      <FileNumber>13</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -476,7 +482,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>10</FileNumber>
+      <FileNumber>14</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -488,7 +494,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>11</FileNumber>
+      <FileNumber>15</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -500,7 +506,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>12</FileNumber>
+      <FileNumber>16</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -512,7 +518,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>13</FileNumber>
+      <FileNumber>17</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -524,7 +530,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>14</FileNumber>
+      <FileNumber>18</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -536,7 +542,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>15</FileNumber>
+      <FileNumber>19</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -548,7 +554,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>16</FileNumber>
+      <FileNumber>20</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -560,7 +566,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>17</FileNumber>
+      <FileNumber>21</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -572,7 +578,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>18</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -584,7 +590,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>19</FileNumber>
+      <FileNumber>23</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -596,7 +602,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>20</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -608,7 +614,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>21</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -620,7 +626,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>22</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -632,7 +638,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -644,7 +650,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -656,7 +662,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -676,7 +682,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 32 - 3
MDK-ARM/iocollect.uvprojx

@@ -49,7 +49,7 @@
             <InvalidFlash>1</InvalidFlash>
           </TargetStatus>
           <OutputDirectory>..\Output\</OutputDirectory>
-          <OutputName>iocollect</OutputName>
+          <OutputName>A_iocollect_230607</OutputName>
           <CreateExecutable>1</CreateExecutable>
           <CreateLib>0</CreateLib>
           <CreateHexFile>1</CreateHexFile>
@@ -80,9 +80,9 @@
             <nStopB2X>0</nStopB2X>
           </BeforeMake>
           <AfterMake>
-            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg1>1</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
-            <UserProg1Name></UserProg1Name>
+            <UserProg1Name>fromelf.exe --bin --output ..\Output\A_iocollect_230607.bin ..\Output\*.axf</UserProg1Name>
             <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
@@ -394,6 +394,26 @@
         <Group>
           <GroupName>Application/User/Core</GroupName>
           <Files>
+            <File>
+              <FileName>iap.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Core\Src\iap.c</FilePath>
+            </File>
+            <File>
+              <FileName>md5c.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Core\Src\md5c.c</FilePath>
+            </File>
+            <File>
+              <FileName>stmflash.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Core\Src\stmflash.c</FilePath>
+            </File>
+            <File>
+              <FileName>Data_deal.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Core\Src\Data_deal.c</FilePath>
+            </File>
             <File>
               <FileName>main.c</FileName>
               <FileType>1</FileType>
@@ -806,4 +826,13 @@
     <files/>
   </RTE>
 
+  <LayerInfo>
+    <Layers>
+      <Layer>
+        <LayName>iocollect</LayName>
+        <LayPrjMark>1</LayPrjMark>
+      </Layer>
+    </Layers>
+  </LayerInfo>
+
 </Project>

+ 13 - 2
iocollect.ioc

@@ -18,7 +18,8 @@ CAD.formats=
 CAD.pinconfig=
 CAD.provider=
 Dma.Request0=USART1_RX
-Dma.RequestsNb=1
+Dma.Request1=USART3_RX
+Dma.RequestsNb=2
 Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
 Dma.USART1_RX.0.Instance=DMA1_Channel5
 Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
@@ -28,6 +29,15 @@ Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
 Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE
 Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW
 Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
+Dma.USART3_RX.1.Direction=DMA_PERIPH_TO_MEMORY
+Dma.USART3_RX.1.Instance=DMA1_Channel3
+Dma.USART3_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
+Dma.USART3_RX.1.MemInc=DMA_MINC_ENABLE
+Dma.USART3_RX.1.Mode=DMA_NORMAL
+Dma.USART3_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
+Dma.USART3_RX.1.PeriphInc=DMA_PINC_DISABLE
+Dma.USART3_RX.1.Priority=DMA_PRIORITY_LOW
+Dma.USART3_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
 File.Version=6
 GPIO.groupedBy=Group By Peripherals
 KeepUserPlacement=true
@@ -78,6 +88,7 @@ Mcu.UserName=STM32F103RETx
 MxCube.Version=6.8.1
 MxDb.Version=DB.6.0.81
 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.DMA1_Channel3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
 NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
 NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 NVIC.ForceEnableDMAVector=true
@@ -89,7 +100,7 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
 NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
-NVIC.USART1_IRQn=true\:0\:0\:true\:false\:true\:true\:true\:true
+NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true
 NVIC.USART3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
 NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 PA0-WKUP.Locked=true

+ 6 - 0
readme.md

@@ -17,6 +17,12 @@
 > ######<u>Updated on 2023/5/5 </u>
 > #####Add View Device Address; 
 > #####Software modification baud rate; 
+> ######<u>Updated on 6/5/2023 11:18:02 AM  </u>
+> #####Add DMA receive statement; 
+### function_v1.2: 
+**Add Function**
+> ######<u>Updated on 6/7/2023 2:10:31 PM   </u>
+> #####Add IAP(In Application Programming);