#include "modbus.h"
#include "PLSR.h"

uint8_t Coil[1250];				///<存放线圈的数组
uint8_t Register_H[16384];        ///<寄存器的高字节
uint8_t Register_L[16384];        ///<寄存器的低字节
uint8_t EXRegister_H[10000];      ///<0x10000开始寄存器的高字节
uint8_t EXRegister_L[10000];      ///<0x10000开始寄存器的低字节

uint8_t History[3][512];    /*存放历史的地方*/
uint8_t HistoryLongth[3];  /*历史数据大小的计数*/
uint8_t HistoryLocation;  /*当前历史存放到了第几条*/
uint8_t SaveFlag = 0;

uint8_t SentPocket[512];
uint8_t Writr_dat[1024];
/**
* @brief 写单个线圈
* @param[in] addr 写入线圈的地址（第几个线圈）
* @param[in] dat 给线圈写入的值
* @return 无
*/
void WriteBit(uint16_t addr,uint8_t dat)
{
    uint16_t temp;
    temp=addr%8;
    if(dat)
	{
        Coil[addr/8]|= (0x01 << temp);
    }
	else
	{
        Coil[addr/8]&=~(0x01 << temp);
    }
}

/**
* @brief 读单个线圈
* @param[in] addr 读取线圈的地址（第几个线圈）
* @param[in] *dat 线圈的值放在哪里
* @return 无
*/
void ReadBit(uint16_t addr,uint8_t * dat)
{
    uint16_t temp;
    temp=addr%8;
    if((Coil[addr/8])&(0x01 << temp))
	{
        *dat=0x01;
    }
	else
	{
        *dat=0x00;
    }
}

/**
* @brief Modbus数据的初始处理
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void ProcessModbusFrame(uint8_t buffer[], uint16_t longth)
{
	uint8_t crc_8[2],  cmdCode;
	uint16_t modbusCrc;
	modbusCrc = modbus_crc16(buffer, longth - 2);
	memcpy(crc_8, &modbusCrc, 2);
	cmdCode = buffer[1]; 
	
	/* 如果通过了CRC校验 */
	if (crc_8[0] == buffer[longth - 2] && 
	   crc_8[1] == buffer[longth - 1])     
	{
		switch (cmdCode)
		{
			case READ_COIL_CODE: ReadCoilProcess(buffer, longth)   /* 读线圈 01 */
				;break;
			case WRUTE_MUL_COIL_CODE: WriteMulCoilProcess(buffer, longth) /* 写多线圈 0f */
				;break;
			case READ_REGUSTER_CODE: ReadRegisterProcess(buffer, longth) /* 读寄存器 03 */
				;break;
			case WRITE_COIL_CODE: WriteCoilProcess(buffer, longth) /* 写线圈 05 */
				;break;
			case WRITE_MUL_REGISTER_CODE: WriteMulRegisterProcess(buffer, longth)	/* 写多寄存器 10 */
				;break;
			case GET_HISTORY_CODE: GetHistory(buffer, longth) /* 获取历史 55 */
				;break;
			case READ_ODD_REGUSTER_CODE: ReadOddRegisterProcess(buffer, longth) /* 获取奇数的寄存器 33 */
				;break;
			case READ_EXREGUSTER_CODE: ReadEXRegisterProcess(buffer, longth) /* 读0x10000处的寄存器 30*/
				;break;	
			case WRITE_MUL_EXREGISTER_CODE: WriteEXRegisterProcess(buffer, longth) /* 写0x10000处的寄存器 31*/
				;break;		
			case WRITE_ONLY_REGISTER: WriteOnlyRegister(buffer, longth)
				;break;
//			case PLSR_COUNT_CLEAR: PLSRCountClear()
//				;break;
			default :ErrorBack(buffer, longth); /* 无效指令码 */
				;break;
				
		}
	}
}

/**
* @brief 0x01指令码的执行,读取多线圈
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void ReadCoilProcess (uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint, step, modbusCrc;         /* 从哪里开始读取，读取了多少线圈 */
	uint8_t sentCount, crc_8[2], temp_data, errCode = 0x00,  SentData[400];       /* 要发送多少字节的数据。  crc_8是crc的校验值  temp_data用来存放读到的字节 */
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装为16位 */
	step = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装为16位 */
	sentCount = step / 8;                         /* 计算要用多少字节发送 */
	if (step % 8 != 0 ) sentCount++;				  /* 补全发送字节 */
		
	memset(SentData, 0, 400);
	/* 如果是与本设备通信 */
	if (buffer[0] == SLAVES_ADDRES)
	{
		/* 异常分析 */
		if(longth != 8) errCode = 0x04;
		if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
		if(step == 0 || step > 0x07d0) errCode = 0x03;
			
		if(errCode == 0x00)
		{
			for (int i = 0; i < step; i++ )/* 循环到获取完整的字节 */
			{
				ReadBit(startPoint + i, &temp_data);
				SentData[i/8] = SentData[i/8] | (temp_data << (i % 8));
			}
		
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = 0x01;
			SentPocket[2] = sentCount;   
			for (int j = 0; j < sentCount; j++)/* 数据组装 */
			{
				memcpy( &SentPocket[3 + j], &SentData[j], 1);
			}
			modbusCrc = modbus_crc16(SentPocket, 3 + sentCount);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3 + sentCount] = crc_8[0];
			SentPocket[4 + sentCount] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5 + sentCount);
			SaveHistory(buffer, longth);
		}
		
		else
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);
		}
	}
}

/**
* @brief 0x0f指令码的执行,写入多线圈
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void WriteMulCoilProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint,step, modbusCrc;         /* 从哪里开始写入，写入的终点，写入了多少线圈 */
	uint8_t crc_8[2],datCount, errCode = 0x00, sentCount;                /* crc_8是crc的校验值,datCount,数据计数，有多少位的数据，Writr_dat存放要写入的数据 */
	startPoint = (buffer[2] << 8 )| buffer[3];               /* 将8位数据组装位16位 */
	step = (buffer[4] << 8) | buffer[5];                      /* 将8位数据组装位16位 */
	datCount = buffer[6];
	
	memset(Writr_dat, 0, 1024);
	
	sentCount = step / 8;                         /* 计算要用多少字节发送 */
	if (step % 8 != 0 ) sentCount++;				  /* 补全发送字节 */
	
	/*数据转移，将buffer内的数据存如写数组。*/
	for (int i = 0; i < datCount; i++)
	{
		Writr_dat[i] = buffer[i + 7];
	}
	

	/* 如果是与本设备通信 */
	if((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))
	{
		/* 异常分析 */
		if(buffer[6] + 9 != longth) errCode = 0x04;		
		if(startPoint > 0x270f || startPoint + step > 0x270f) errCode = 0x02;
		if(step == 0 || step > 0x07b0 || sentCount != datCount) errCode = 0x03;
		
		if(errCode == 0x00)
		{
			for (int j = 0; j < step; j++)
			{
				if ((Writr_dat[j / 8]) & (0x01)<<(j % 8))
				{
					WriteBit(startPoint + j, 0x01);
				}
				else
				{
					WriteBit(startPoint + j, 0x00);
				}
			}
		
			/* 如果不是广播，发送返回消息 */
			if(buffer[0] == SLAVES_ADDRES)  
			{
				/* 准备发送应答 */
				SentPocket[0] = 0x01;
				SentPocket[1] = 0x0f;
				SentPocket[2] = buffer[2];
				SentPocket[3] = buffer[3];
				SentPocket[4] = buffer[4];
				SentPocket[5] = buffer[5];
				modbusCrc = modbus_crc16(SentPocket, 6);/* 计算CRC */
				memcpy(crc_8, &modbusCrc, 2);
				SentPocket[6] = crc_8[0];
				SentPocket[7] = crc_8[1];
				HAL_UART_Transmit_DMA(&huart1,SentPocket,8);
				SaveHistory(buffer, longth);
			}
		}
		else if(errCode != 0x00 && buffer[0] == SLAVES_ADDRES)
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);			
		}
	}
}

/**
* @brief 0x03指令码的执行,读出输出寄存器
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void ReadRegisterProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint,step, modbusCrc;         /* 从哪里开始读取，读取多少寄存器 */
	uint8_t crc_8[2], SentData[256], errCode = 0x00;               
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */
	step = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装位16位 */
	

	/* 如果是与本设备通信 */
	if (buffer[0] == SLAVES_ADDRES)
	{
		if(longth != 8) errCode = 0x04;
		if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
		if(step == 0 || step > 0x007d) errCode = 0x03;
		
		if(errCode == 0x00)
		{
			for (int i = 0; i < step; i++)                         /* 将数据存取发出数据缓存 */
			{                                                     
				SentData[i * 2]     = Register_H[startPoint + i];
				SentData[i * 2 +1 ] = Register_L[startPoint + i];
			}
		
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = 0x03;
			SentPocket[2] = buffer[5] * 2;
			for (int j = 0; j < buffer[5] * 2; j++)/* 数据组装 */
			{
				SentPocket[3+j] = SentData[j];
			}
			modbusCrc = modbus_crc16(SentPocket, (buffer[5] * 2)+ 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[(buffer[5] * 2)+ 3] = crc_8[0];
			SentPocket[(buffer[5] * 2)+ 4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,(buffer[5] * 2)+ 5 );
			SaveHistory(buffer, longth);
		}
		else
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);			
		}
	}
}

/**
* @brief 0x30指令码的执行,读出额外输出寄存器
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void ReadEXRegisterProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint,step, modbusCrc;         /* 从哪里开始读取，读取多少寄存器 */
	uint8_t crc_8[2], SentData[256], errCode = 0x00;               
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */
	step = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装位16位 */
	

	/* 如果是与本设备通信 */
	if (buffer[0] == SLAVES_ADDRES)
	{
		if(longth != 8) errCode = 0x04;
		if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;	
		if(step == 0 || step > 0x007d) errCode = 0x03;
		
		if(errCode == 0x00)
		{
			for (int i = 0; i < step; i++)                         /* 将数据存取发出数据缓存 */
			{                                                     
				SentData[i * 2]     = EXRegister_H[startPoint + i];
				SentData[i * 2 +1 ] = EXRegister_L[startPoint + i];
			}
		
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = 0x30;
			SentPocket[2] = buffer[5] * 2;
			for (int j = 0; j < buffer[5] * 2; j++)/* 数据组装 */
			{
				SentPocket[3+j] = SentData[j];
			}
			modbusCrc = modbus_crc16(SentPocket, (buffer[5] * 2)+ 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[(buffer[5] * 2)+ 3] = crc_8[0];
			SentPocket[(buffer[5] * 2)+ 4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,(buffer[5] * 2)+ 5 );
			SaveHistory(buffer, longth);
		}
		else
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);			
		}
	}
}

/**
* @brief 0x33指令码的执行,读取奇数位寄存器
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void ReadOddRegisterProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint,step, modbusCrc;         /* 从哪里开始读取，读取多少寄存器 */
	uint8_t crc_8[2], SentData[256], errCode = 0x00;               
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */
	step = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装位16位 */
	

	/* 如果是与本设备通信 */
	if (buffer[0] == SLAVES_ADDRES)
	{
		if(longth != 8) errCode = 0x04;
		if(startPoint > 0x270f || startPoint + step > 0x270f + 1 || startPoint % 2 == 0) errCode = 0x02;
		if(step == 0 || step > 0x007d) errCode = 0x03;
		
		if(errCode == 0x00)
		{
			for (int i = 0; i < step * 2; i+= 2)                         /* 将数据存取发出数据缓存 */
			{                                                     
				SentData[i] = Register_H[startPoint + i];
				SentData[i + 1] = Register_L[startPoint + i];
			}
		
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = 0x33;
			SentPocket[2] = step * 2;
			for (int j = 0; j < step * 2; j++)/* 数据组装 */
			{
				SentPocket[3+j] = SentData[j];
			}
			modbusCrc = modbus_crc16(SentPocket, step * 2 + 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[(buffer[5] * 2)+ 3] = crc_8[0];
			SentPocket[(buffer[5] * 2)+ 4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,(step * 2)+ 5 );
			SaveHistory(buffer, longth);
		}
		else
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);			
		}
	}
	
}

/**
* @brief 0x10指令码的执行,写入多寄存器
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void WriteMulRegisterProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint, step, modbusCrc;         /* 从哪里开始写入，写入多少寄存器 */
	uint8_t crc_8[2], datCount, errCode = 0x00;                   /* crc校验；数据计数 */
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */	
	step = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装位16位 */
	datCount = buffer[6] / 2;
	
	
	/* 如果是与本设备通信 */
	if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))
	{
		if(buffer[6] + 9 != longth) errCode = 0x04;
		if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;
		if(step == 0x00 || step > 0x07b || step * 2 != buffer[6] ) errCode = 0x03;
		
		if(errCode == 0x00)
		{
			for (int i = 0; i < datCount; i++)              /* 数据写入 */
			{											
				Register_H[startPoint + i] = buffer[(i * 2)+ 7];     
				Register_L[startPoint + i] = buffer[(i * 2)+ 8];     
			}
		
			/* 如果不是广播，发送返回消息 */
			if(buffer[0] == SLAVES_ADDRES)
			{
				/* 准备发送应答 */
				SentPocket[0] = 0x01;
				SentPocket[1] = 0x10;	
				SentPocket[2] = buffer[2];
				SentPocket[3] = buffer[3];
				SentPocket[4] = buffer[4];
				SentPocket[5] = buffer[5];		
				modbusCrc = modbus_crc16(SentPocket, 6);/* 计算CRC */
				memcpy(crc_8, &modbusCrc, 2);
				SentPocket[6] = crc_8[0];
				SentPocket[7] = crc_8[1];
				HAL_UART_Transmit_DMA(&huart1,SentPocket,8);	
				SaveHistory(buffer, longth);
			}
		}
		else if(errCode != 0x00 && buffer[0] == SLAVES_ADDRES)
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);			
		}
	}
	
}

/**
* @brief 0x31指令码的执行,写入额外多寄存器
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void WriteEXRegisterProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint, step, modbusCrc;         /* 从哪里开始写入，写入多少寄存器 */
	uint8_t crc_8[2], datCount, errCode = 0x00;                   /* crc校验；数据计数 */
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */	
	step = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装位16位 */
	datCount = buffer[6] / 2;
	
	
	/* 如果是与本设备通信 */
	if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))
	{
		if(buffer[6] + 9 != longth) errCode = 0x04;
		if(startPoint > 0x270f || startPoint + step > 0x270f + 1) errCode = 0x02;	
		if(step == 0x00 || step > 0x07b || step * 2 != buffer[6] ) errCode = 0x03;
		
		if(errCode == 0x00)
		{
			for (int i = 0; i < datCount; i++)              /* 数据写入 */
			{											
				EXRegister_H[startPoint + i] = buffer[(i * 2)+ 7];     
				EXRegister_L[startPoint + i] = buffer[(i * 2)+ 8];     
			}
		
			/* 如果不是广播，发送返回消息 */
			if(buffer[0] == SLAVES_ADDRES)
			{
				/* 准备发送应答 */
				SentPocket[0] = 0x01;
				SentPocket[1] = 0x31;	
				SentPocket[2] = buffer[2];
				SentPocket[3] = buffer[3];
				SentPocket[4] = buffer[4];
				SentPocket[5] = buffer[5];		
				modbusCrc = modbus_crc16(SentPocket, 6);/* 计算CRC */
				memcpy(crc_8, &modbusCrc, 2);
				SentPocket[6] = crc_8[0];
				SentPocket[7] = crc_8[1];
				HAL_UART_Transmit_DMA(&huart1,SentPocket,8);	
				SaveHistory(buffer, longth);
			}
		}
		else if(errCode != 0x00 && buffer[0] == SLAVES_ADDRES)
		{
			/* 准备发送应答 */
			SentPocket[0] = 0x01;
			SentPocket[1] = buffer[1] + 0x80;	
			SentPocket[2] = errCode;
			modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
			memcpy(crc_8, &modbusCrc, 2);
			SentPocket[3] = crc_8[0];
			SentPocket[4] = crc_8[1];
			HAL_UART_Transmit_DMA(&huart1,SentPocket,5);			
		}
	}
	
}

/**
* @brief 0x05指令码的执行,写入单线圈
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void WriteCoilProcess(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint, State;         /* 从哪里开始写入，写入多少寄存器 */
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */	
	State = (buffer[4] << 8) | buffer[5];           /* 将8位数据组装位16位 */
	
	
	if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))/* 如果是与本设备通信 */
	{
		if(State == 0xff00)
		{
        	Coil[startPoint/8]|= (0x01 << (startPoint % 8) );
		}
		if(State == 0x0000)
		{
			Coil[startPoint/8]&=~(0x01 << (startPoint % 8) );
		}
		
		/* 如果不是广播，发送返回消息 */
		if(buffer[0] == SLAVES_ADDRES)
		{
			memcpy(SentPocket, buffer, longth);
			HAL_UART_Transmit_DMA(&huart1, SentPocket, longth);
		}
		
	}

}

/**
* @brief 0x06指令码的执行,写入单寄存器
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void WriteOnlyRegister(uint8_t buffer[], uint16_t longth)
{
	uint16_t startPoint;
	startPoint = (buffer[2] << 8 )| buffer[3];    /* 将8位数据组装位16位 */	
	
	if ((buffer[0] == SLAVES_ADDRES || buffer[0] == 0x00))/* 如果是与本设备通信 */
	{
		
		Register_H[startPoint] = buffer[4];     
		Register_L[startPoint] = buffer[5];   
		
		/* 如果不是广播，发送返回消息 */
		if(buffer[0] == SLAVES_ADDRES)
		{
			memcpy(SentPocket, buffer, longth);
			HAL_UART_Transmit_DMA(&huart1, SentPocket, longth);
		}
		
	}
}

/**
* @brief 指令码错误的返回报文
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void ErrorBack(uint8_t buffer[], uint16_t longth)
{
	uint16_t modbusCrc;
	uint8_t crc_8[2];
	
	/* 如果是与本设备通信 */
	if (buffer[0] == SLAVES_ADDRES)
	{
		/* 准备发送应答 */
		SentPocket[0] = 0x01;
		SentPocket[1] = buffer[1] + 0x80;	
		SentPocket[2] = 0x01;	
		modbusCrc = modbus_crc16(SentPocket, 3);/* 计算CRC */
		memcpy(crc_8, &modbusCrc, 2);
		SentPocket[3] = crc_8[0];
		SentPocket[4] = crc_8[1];
		HAL_UART_Transmit_DMA(&huart1,SentPocket,5);		
	}
}

/**
* @brief 历史保存
* @param[in] buffer[] 保存的数据
* @param[in] longth   数据的长度
* @return 无
*/
void SaveHistory(uint8_t buffer[], uint16_t longth)
{
	memcpy(History[HistoryLocation], buffer, longth);
	HistoryLongth[HistoryLocation] = longth;
	HistoryLocation++;
	if(HistoryLocation == 3)
	{
		HistoryLocation = 0;
	}
}

/**
* @brief 历史读取
* @return 无
*/
void LoadHistory(void)
{
	uint8_t temp;
	temp = HistoryLocation;
	for(int i = 0; i < 3; i++)
	{
		
		if(temp == 3)
		{
			temp = 0;
		}
		HAL_UART_Transmit(&huart1, History[temp], HistoryLongth[temp], 0xffff);
		temp++;
	}
}

/**
* @brief 0x55指令码的执行,输出历史
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void GetHistory(uint8_t buffer[], uint16_t longth)
{
	/* 如果是与本设备通信 */
	if (buffer[0] == SLAVES_ADDRES)
	{
		LoadHistory();
		
	}
}

/**
* @brief 0x39指令码的执行,输出历史
* @param[in] buffer[] 预处理的数据
* @param[in] longth   数据的长度
* @return 无
*/
void PLSRCountClear(void)
{
	for(int i = 0; i < 10; i ++)
	{
		CNT_Only[i] = 0; 
	}
}

/**
* @brief  读取并还原sram数据。
* @return 无
*/
void ModbusLoadSRAM(void)
{
	uint32_t temp[256] = {0};
	Read_Backup_SRAM(temp,256);
	memcpy(SramData, temp, 1024);
	for(int i = 0; i < 512; i++)
	{                                      
		Register_H[i + 4096] = SramData[i * 2];    
		Register_L[i + 4096] = SramData[i * 2 + 1];
	}
}

/**
* @brief  存入sram数据。
* @return 无
*/
void ModbusSaveSRAM(void)
{
	uint32_t temp[256] = {0};
	for (int i = 0; i < 512; i++)                         
	{
		SramData[i * 2]     = Register_H[i + 4096];
		SramData[i * 2 + 1] = Register_L[i + 4096];
	}
	memcpy(temp, SramData, 1024);
	Write_Backup_SRAM(temp, 256);
}