diff --git a/modbus/modbus_parse.c b/modbus/modbus_parse.c new file mode 100644 index 0000000..37b8226 --- /dev/null +++ b/modbus/modbus_parse.c @@ -0,0 +1,568 @@ +#include "stm32f4xx.h" +#include "ucos_ii.h" +#include "os.h" +#include "string.h" +#include "modbus_parse.h" +#include "modbus_rec_send.h" + +extern OS_EVENT* ModbusWriteFlash; /*接收到modbus写入coil请求报文*/ +extern OS_EVENT* ModbusConnect; /*已接收到modbus正确报文*/ + +uint8_t ModbusErr; +/*0x270F + 1 = K10000 */ +uint8_t ModbusCoil[1250]; /*10000/8=1250*/ +uint16_t ModbusReg[10000]; + +/*附加功能:页寄存器*/ +uint16_t ModbusExtPage[1] = {0}; /*设置地址为0xFFFE*/ +uint16_t ModbusExtReg[1]; /*地址映射为0x10000*/ +/*附加功能:读取所有单数个寄存器*/ +uint16_t ModbusExtOdd[1] = {0}; /*设置地址为0xFFFF*/ + +uint8_t ModbusRxBuf[MODBUS_RX_BUF_SIZE]; /*接收数组*/ +uint16_t ModbusRxLen = 0; /*接收数据长度*/ +uint8_t ModbusTxBuf[MODBUS_TX_BUF_SIZE]; /*发送数组*/ +uint16_t ModbusTxLen = 0; /*发送数据长度*/ + + +/*modbus协议帧解析任务*/ +void AppTaskModbusParse (void *p_arg) +{ + OS_ERR err; + MODBUS_FRAME frame; + uint16_t rxLen; + uint8_t rxBuf[256]; + + while(1) + { + /*无限期等待接收到数据帧信号量*/ + OSSemPend(ModbusReceived, 0, &err); + + /*数据接收,防止下一帧覆盖*/ + rxLen = ModbusRxLen; + if(rxLen > MODBUS_RX_BUF_SIZE) + { + rxLen = 0; + } + memcpy(rxBuf, ModbusRxBuf, rxLen); + + /*帧分解*/ + frame.slaveAddres = rxBuf[0]; + frame.func = rxBuf[1]; + frame.crc = ((uint16_t)(rxBuf[rxLen - 2])) | ((uint16_t)rxBuf[rxLen - 1] << 8); + frame.opeAddres = ((uint16_t)rxBuf[2] << 8) | ((uint16_t)rxBuf[3]); + frame.opeNum = ((uint16_t)rxBuf[4] << 8) | ((uint16_t)rxBuf[5]); + + /*crc校验判断*/ + if(ChcekCrc16(frame.crc, rxBuf, rxLen) != 0) + { + /*crc校验错误,直接丢弃*/ + ModbusErr = ERR_CRC; + continue; + } + /*从机地址判断*/ + if(frame.slaveAddres != SLAVE_ADDRES) + { + /*从机地址错误,直接丢弃*/ + ModbusErr = ERR_SLAVE_ADDRES; + continue; + } + /*释放正确接收信号量*/ + OSSemPost(ModbusConnect); + + /*功能码分类*/ + switch(frame.func) + { + case 0x01:/*读线圈*/ + ModbusErr = ModbusReadCoils(frame.opeAddres, frame.opeNum); + break; + + case 0x03:/*读寄存器*/ + ModbusErr = ModbusReadRegs(frame.opeAddres, frame.opeNum); + break; + + case 0x0F:/*写多个线圈*/ + frame.wNum = rxBuf[6]; + memcpy(frame.wData, &rxBuf[7], frame.wNum); + ModbusErr = ModbusWriteCoils(frame.opeAddres, frame.opeNum, frame.wData); + break; + + case 0x10:/*写多个寄存器*/ + frame.wNum = rxBuf[6]; + memcpy(frame.wData, &rxBuf[7], frame.wNum); + ModbusErr = ModbusWriteRegs(frame.opeAddres, frame.opeNum, frame.wData); + break; + + case 0x05:/*写单个线圈*/ + memcpy(frame.wData, &rxBuf[4], 2); + ModbusErr = ModbusWriteCoil(frame.opeAddres, frame.wData); + break; + + case 0x06:/*写单个寄存器*/ + memcpy(frame.wData, &rxBuf[4], 2); + ModbusErr = ModbusWriteReg(frame.opeAddres, frame.wData); + break; + + default:/*功能码错误*/ + ModbusErr = ERR_FUNC; + ModbusErr = ModbusErrReply(frame.func, ERR_FUNC); + break; + } + /*实现附加功能时不在这里启动发送*/ + if(frame.func == 0x03 && frame.opeAddres == 0XFFFF); + else + { + ModbusSend(ModbusTxBuf, ModbusTxLen); + } + + if(ModbusErr == 0 && (frame.func == 0x0F || frame.func == 0x10 + || frame.func == 0x05 || frame.func == 0x06)) + { + /*释放写FLASH信号量*/ + OSSemPost(ModbusWriteFlash); + } + } +} + +uint8_t ModbusReadCoils(uint16_t addres, uint16_t num) +{ + uint16_t byteIndI; /*字节索引*/ + uint8_t bitIndI; /*位索引*/ + uint16_t byteIndO; + uint8_t bitIndO; + + uint8_t dataLen; /*响应帧返回字节数*/ + + uint8_t index; /*发送数组索引*/ + uint8_t readVal; /*读取到的形式值*/ + uint8_t writeVal; /*写入的形式值*/ + + if(ModbusRxLen < 8) + { + return ModbusErrReply(0x01, ERR_DATA); + } + /*操作地址超限*/ + if(addres > 0x270F || (addres + (num - 1)) > 0x270F) + { + return ModbusErrReply(0x01, ERR_OPE_ADDRES); + } + /*操作数量超限*/ + if(num == 0 || num > 2000) + { + return ModbusErrReply(0x01, ERR_DATA); + } + + /*不能num/8+1,当为8的整数时会多一个*/ + dataLen = (num + 7) / 8; + + /*清零发送数组*/ + memset(&ModbusTxBuf[3], 0, 253); + + for(uint16_t i = 0; i < num; i++) + { + byteIndO = i / 8; + bitIndO = i % 8; + + byteIndI = (addres + i) / 8; + bitIndI = (addres + i) % 8; + + /*位掩码读取线圈值*/ + readVal = ModbusCoil[byteIndI] & ((uint8_t)1 << bitIndI); + + /*读取到的值为0则不进行操作*/ + if(readVal != 0) + { + index = 3 + byteIndO; + /*将读取到的值移位到要写入的位*/ + writeVal = (uint8_t)1u << bitIndO; + + ModbusTxBuf[index] |= writeVal; + } + } + + ModbusTxBuf[0] = SLAVE_ADDRES; /*从机地址*/ + ModbusTxBuf[1] = 0x01; /*功能码*/ + ModbusTxBuf[2] = dataLen; /*响应帧返回数据字节数*/ + AddCrc16(ModbusTxBuf, 3 + dataLen); + ModbusTxLen = 5 + dataLen; + + return 0; +} + +uint8_t ModbusWriteCoils(uint16_t addres, uint16_t num, uint8_t *data) +{ + uint16_t byteIndI; + uint8_t bitIndI; + uint16_t byteIndO; + uint8_t bitIndO; + + uint8_t readVal; + uint8_t writeVal; + + if(ModbusRxLen < 10) + { + return ModbusErrReply(0x0F, ERR_DATA); + } + /*操作地址超限*/ + if(addres > 0x270F || (addres + (num - 1)) > 0x270F) + { + return ModbusErrReply(0x0F, ERR_OPE_ADDRES); + } + /*操作数量超限*/ + if(num == 0 || num > 1968) + { + return ModbusErrReply(0x0F, ERR_DATA); + } + + for(uint16_t i = 0; i < num; i++) + { + byteIndI = (addres + i) / 8; + bitIndI = (addres + i) % 8; + + byteIndO = i / 8; + bitIndO = i % 8; + + /*位掩码读取要写入的值*/ + readVal = data[byteIndO] & ((uint8_t)1 << bitIndO); + /*将写入值移位到要写入的位*/ + writeVal = (uint8_t)1 << bitIndI; + + /*对应位写入1*/ + if(readVal != 0) + { + ModbusCoil[byteIndI] |= writeVal; + } + /*对应位写入0*/ + else + { + ModbusCoil[byteIndI] &= (~writeVal); + } + } + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x0F; + /*操作地址*/ + ModbusTxBuf[2] = (uint8_t)(addres >> 8); + ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF); + /*成功写入的数量*/ + ModbusTxBuf[4] = (uint8_t)(num >> 8); + ModbusTxBuf[5] = (uint8_t)(num & 0x00FF); + AddCrc16(ModbusTxBuf, 6); + ModbusTxLen = 8; + + return 0; +} + +uint8_t ModbusReadRegs(uint16_t addres, uint16_t num) +{ + uint8_t index; + uint8_t readValH; + uint8_t readValL; + uint8_t dataLen; + + if(ModbusRxLen < 8) + { + return ModbusErrReply(0x03, ERR_DATA); + } + /*操作地址超限*/ + if(addres > 0x270F || (addres + (num - 1)) > 0x270F) + { + if(addres == 0xFFFF && num == 1) + { + ; + } + else + { + return ModbusErrReply(0x03, ERR_OPE_ADDRES); + } + } + /*操作数量超限*/ + if(num == 0 || num > 125) + { + return ModbusErrReply(0x03, ERR_DATA); + } + + dataLen = num * 2; + /*附加功能:读取0x10000寄存器*/ + if(ModbusExtPage[0] == 1 && addres == 0x0000) + { + /*将16位寄存器值拆分为两个8位*/ + readValH = (uint8_t)(ModbusExtReg[0] >> 8); + readValL = (uint8_t)(ModbusExtReg[0] & 0x00FF); + + ModbusTxBuf[3] = readValH; + ModbusTxBuf[4] = readValL; + } + /*附加功能:读取大量奇数寄存器*/ + else if(addres == 0xFFFF && num == 1) + { + return ModbusExtReadOdd(ModbusExtOdd[0]); + } + else + { + for(uint16_t i = 0; i < num; i++) + { + index = 3 + (i * 2); + /*将16位寄存器值拆分为两个8位*/ + readValH = (uint8_t)(ModbusReg[addres + i] >> 8); + readValL = (uint8_t)(ModbusReg[addres + i] & 0x00FF); + + ModbusTxBuf[index] = readValH; + ModbusTxBuf[index + 1] = readValL; + } + } + + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x03; + ModbusTxBuf[2] = dataLen; + AddCrc16(ModbusTxBuf, 3 + dataLen); + ModbusTxLen = 5 + dataLen; + + return 0; +} + +uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data) +{ + uint8_t index; + + uint8_t writeValH; + uint8_t writeValL; + uint16_t writeVal; + + if(ModbusRxLen < 11) + { + return ModbusErrReply(0x10, ERR_DATA); + } + /*操作地址超限*/ + if(addres > 0x270F || (addres + (num - 1)) > 0x270F) + { + if((addres == 0xFFFE || addres == 0xFFFF) && num == 1) + { + ; + } + else + { + return ModbusErrReply(0x10, ERR_OPE_ADDRES); + } + } + /*操作数量超限*/ + if(num == 0 || num > 123) + { + return ModbusErrReply(0x10, ERR_DATA); + } + + /*附加功能:读取0x10000寄存器*/ + if(addres == 0xFFFE && num == 1) + { + writeValH = data[0]; + writeValL = data[1]; + + /*将要写入两个8位值拼接为16位*/ + writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); + ModbusExtPage[0] = writeVal; + } + /*附加功能:读取大量奇数寄存器*/ + else if(addres == 0xFFFF && num == 1) + { + writeValH = data[0]; + writeValL = data[1]; + + /*将要写入两个8位值拼接为16位*/ + writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); + ModbusExtOdd[0] = writeVal; + } + /*正常功能*/ + else + { + for(uint16_t i = 0; i < num; i++) + { + index = i * 2; + + writeValH = data[index]; + writeValL = data[index + 1]; + + /*将要写入两个8位值拼接为16位*/ + writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); + ModbusReg[addres + i] = writeVal; + } + } + + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x10; + /*操作地址*/ + ModbusTxBuf[2] = (uint8_t)(addres >> 8); + ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF); + /*成功写入数量*/ + ModbusTxBuf[4] = (uint8_t)(num >> 8); + ModbusTxBuf[5] = (uint8_t)(num & 0x00FF); + AddCrc16(ModbusTxBuf, 6); + ModbusTxLen = 8; + + return 0; +} + +uint8_t ModbusWriteCoil(uint16_t addres, uint8_t *data) +{ + uint16_t byteIndI; + uint8_t bitIndI; + + uint16_t readVal; + uint8_t writeVal; + + if(ModbusRxLen < 8) + { + return ModbusErrReply(0x05, ERR_DATA); + } + /*操作地址超限*/ + if(addres > 0x270F) + { + return ModbusErrReply(0x05, ERR_OPE_ADDRES); + } + + byteIndI = addres / 8; + bitIndI = addres % 8; + + /*位掩码读取要写入的值*/ + readVal = ((uint16_t)data[0] << 8) | ((uint16_t)data[1] & 0x00FF); + /*将写入值移位到要写入的位*/ + writeVal = (uint8_t)1 << bitIndI; + + /*置on*/ + if(readVal == 0xFF00) + { + ModbusCoil[byteIndI] |= writeVal; + } + /*置off*/ + else if(readVal == 0x0000) + { + ModbusCoil[byteIndI] &= (~writeVal); + } + else + { + return ModbusErrReply(0x05, ERR_DATA); + } + + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x05; + /*操作地址*/ + ModbusTxBuf[2] = (uint8_t)(addres >> 8); + ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF); + /*成功写入*/ + ModbusTxBuf[4] = data[0]; + ModbusTxBuf[5] = data[1]; + AddCrc16(ModbusTxBuf, 6); + ModbusTxLen = 8; + + return 0; +} + +uint8_t ModbusWriteReg(uint16_t addres, uint8_t *data) +{ + uint8_t writeValH; + uint8_t writeValL; + uint16_t writeVal; + + if(ModbusRxLen < 8) + { + return ModbusErrReply(0x06, ERR_DATA); + } + /*操作地址超限*/ + if(addres > 0x270F) + { + return ModbusErrReply(0x06, ERR_OPE_ADDRES); + } + + writeValH = data[0]; + writeValL = data[1]; + /*将要写入两个8位值拼接为16位*/ + writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); + ModbusReg[addres] = writeVal; + + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x06; + /*操作地址*/ + ModbusTxBuf[2] = (uint8_t)(addres >> 8); + ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF); + /*成功写入*/ + ModbusTxBuf[4] = writeValH; + ModbusTxBuf[5] = writeValL; + AddCrc16(ModbusTxBuf, 6); + ModbusTxLen = 8; + + return 0; +} + + +uint8_t ModbusExtReadOdd(uint16_t num) +{ + uint8_t i = 0; + uint8_t numJ = (num + 124) / 125; + uint8_t numI = num % 125; + + uint8_t index; + uint16_t indexR; + uint8_t readValH; + uint8_t readValL; + uint8_t dataLen; + + for(uint16_t j = 0; j < numJ; j++) + { + if(j == numJ - 1) + { + for(i = 0; i < numI; i++) + { + index = 3 + (i * 2); + indexR = j * 250 + 2 * i + 1; + /*将16位寄存器值拆分为两个8位*/ + readValH = (uint8_t)(ModbusReg[indexR] >> 8); + readValL = (uint8_t)(ModbusReg[indexR] & 0x00FF); + + ModbusTxBuf[index] = readValH; + ModbusTxBuf[index + 1] = readValL; + } + dataLen = 2 * numI; + + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x03; + ModbusTxBuf[2] = dataLen; + AddCrc16(ModbusTxBuf, 3 + dataLen); + ModbusTxLen = 5 + dataLen; + } + else + { + for(i = 0; i < 125; i++) + { + index = 3 + (i * 2); + indexR = j * 250 + 2 * i + 1; + /*将16位寄存器值拆分为两个8位*/ + readValH = (uint8_t)(ModbusReg[indexR] >> 8); + readValL = (uint8_t)(ModbusReg[indexR] & 0x00FF); + + ModbusTxBuf[index] = readValH; + ModbusTxBuf[index + 1] = readValL; + } + dataLen = 250; + + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = 0x03; + ModbusTxBuf[2] = dataLen; + AddCrc16(ModbusTxBuf, 3 + dataLen); + ModbusTxLen = 5 + dataLen; + } + /*演示2ms*/ + OSTimeDly(OS_TICKS_PER_SEC / 500); + ModbusSend(ModbusTxBuf, ModbusTxLen); + } + return 0; +} + + +uint8_t ModbusErrReply(uint8_t func, uint8_t err) +{ + ModbusTxBuf[0] = SLAVE_ADDRES; + ModbusTxBuf[1] = func | 0x80; + ModbusTxBuf[2] = err; + AddCrc16(ModbusTxBuf, 3); + ModbusTxLen = 5; + + return err; +} diff --git a/modbus/modbus_parse.h b/modbus/modbus_parse.h new file mode 100644 index 0000000..1e92aa5 --- /dev/null +++ b/modbus/modbus_parse.h @@ -0,0 +1,58 @@ +#ifndef __MODBUS_PARSE_H +#define __MODBUS_PARSE_H + +#include "ucos_ii.h" + + +/*接收数组大小*/ +#define MODBUS_RX_BUF_SIZE 256 +/*发送数组大小*/ +#define MODBUS_TX_BUF_SIZE 256 + +/*modbus通信波特率*/ +#define MODBUS_USART_BAUDRATE 115200 + +/*从机地址*/ +#define SLAVE_ADDRES 0x01 + +/*错误码*/ +#define ERR_FUNC 0x01 +#define ERR_OPE_ADDRES 0x02 +#define ERR_DATA 0x03 +#define ERR_SLAVE 0x04 + +#define ERR_CRC 0x1F +#define ERR_SLAVE_ADDRES 0x2F + +/*modbus帧结构*/ +typedef struct Modbus_Frame +{ + uint8_t slaveAddres; /*从机地址*/ + uint8_t func; /*功能码*/ + uint16_t opeAddres; /*操作地址*/ + uint16_t opeNum; /*操作数量*/ + uint8_t wNum; /*写入字节数*/ + uint8_t wData[256]; /*写入数据*/ + uint16_t crc; /*CRC校验码*/ +}MODBUS_FRAME; + + +/*接收到数据帧信号量*/ +extern OS_EVENT *ModbusReceived; +extern uint8_t ModbusRxBuf[MODBUS_RX_BUF_SIZE]; /*接收数组*/ +extern uint16_t ModbusRxLen; /*接收数据长度*/ +extern uint8_t ModbusTxBuf[MODBUS_TX_BUF_SIZE]; /*发送数组*/ +extern uint16_t ModbusTxLen; /*发送数据长度*/ + + +uint8_t ModbusReadCoils(uint16_t addres, uint16_t num); +uint8_t ModbusWriteCoils(uint16_t addres, uint16_t num, uint8_t *data); +uint8_t ModbusReadRegs(uint16_t addres, uint16_t num); +uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data); +uint8_t ModbusWriteReg(uint16_t addres, uint8_t *data); +uint8_t ModbusWriteCoil(uint16_t addres, uint8_t *data); +uint8_t ModbusExtReadOdd(uint16_t num); +uint8_t ModbusErrReply(uint8_t func, uint8_t err); + + +#endif diff --git a/modbus/modbus_rec_send.c b/modbus/modbus_rec_send.c new file mode 100644 index 0000000..0376dd4 --- /dev/null +++ b/modbus/modbus_rec_send.c @@ -0,0 +1,146 @@ +#include "modbus_rec_send.h" + + +/*USART接收空闲中断*/ +void USART1_IRQHandler(void) +{ + uint32_t temp; + uint16_t rxLenRemain; + + OSIntEnter(); /*进入中断*/ + if(USART_GetITStatus(USART1, USART_IT_IDLE) == SET) + { + /*清除IDLE中断标志位*/ + temp = USART1->SR; + temp = USART1->DR; + (void)temp; + + /*判断是否接收到帧,触发TIM计时*/ + rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2); + if(rxLenRemain != MODBUS_RX_BUF_SIZE) + { + /*启动TIM计时*/ + TIM_Cmd(TIM5, DISABLE); + TIM_SetCounter(TIM5, 0); /*清除计数值*/ + //TIM_ClearITPendingBit(TIM5, TIM_IT_Update); /*清除中断标志位*/ + TIM_Cmd(TIM5, ENABLE); + } + } + OSIntExit(); /*退出中断*/ +} + +/*TIM定时器中断*/ +void TIM5_IRQHandler(void) +{ + uint16_t rxLenRemain; + + OSIntEnter(); + if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) + { + /*清除TIM5更新中断标志*/ + TIM_ClearITPendingBit(TIM5, TIM_IT_Update); + + /*关闭DMA*/ + DMA_Cmd(DMA2_Stream2, DISABLE); + /*清除传输已经完成TCIF2、传输已经完成一半HTIF2标志位*/ + DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2 | DMA_FLAG_HTIF2); + + /*计算数据长度*/ + rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2); + ModbusRxLen = MODBUS_RX_BUF_SIZE - rxLenRemain; + + /*释放接收到数据帧信号量,唤醒帧解析任务*/ + if(ModbusRxLen >= 4) /*4字节(1字节地址、1字节功能、2字节CRC)*/ + { + OSSemPost(ModbusReceived); + } + + /*重新指定接收地址*/ + DMA_MemoryTargetConfig(DMA2_Stream2, (uint32_t)ModbusRxBuf, DMA_Memory_0); + /*重启DMA*/ + DMA_SetCurrDataCounter(DMA2_Stream2, MODBUS_RX_BUF_SIZE); + DMA_Cmd(DMA2_Stream2, ENABLE); + } + OSIntExit(); +} + +/*modbus响应帧发送*/ +void ModbusSend(uint8_t *txBuf, uint16_t len) +{ + if(DMA_GetCmdStatus(DMA2_Stream7) == ENABLE) + { + /*等待DMA发送完成*/ + while(DMA_GetFlagStatus(DMA2_Stream7, DMA_FLAG_TCIF7) == RESET); + } + + /*先关闭DMA发送通道*/ + DMA_Cmd(DMA2_Stream7, DISABLE); + + /*等待DMA关闭*/ + while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE); + + /*清除传输已经完成TCIF7、传输已经完成一半HTIF7、FIFO错误FEIF7标志位*/ + DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_FEIF7 | DMA_FLAG_HTIF7 | DMA_FLAG_TCIF7); + + /*配置发送地址和长度*/ + DMA_MemoryTargetConfig(DMA2_Stream7, (uint32_t)txBuf, DMA_Memory_0); + DMA_SetCurrDataCounter(DMA2_Stream7, len); + + /*等待串口发送完成*/ + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); + + /*启动 DMA 发送*/ + DMA_Cmd(DMA2_Stream7, ENABLE); +} + +/*crc16校验*/ +uint16_t Crc16(const uint8_t *data, uint16_t length) +{ + uint16_t crc; + uint16_t byteInd; + uint8_t bitInd; + + crc = 0xFFFFu; + for (byteInd = 0u; byteInd < length; byteInd++) + { + crc ^= (uint16_t)data[byteInd]; + for (bitInd = 0u; bitInd < 8u; bitInd++) + { + if ((crc & 0x0001u) != 0u) + { + crc >>= 1; + crc ^= 0xA001u; + } + else + { + crc >>= 1; + } + } + } + return crc; +} + +/*crc16检查*/ +int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length) +{ + uint16_t crc16 = Crc16(data, (length - 2)); + + if(recCrc16 == crc16) + { + return 0; + } + else + { + return -1; + } +} + +void AddCrc16(uint8_t *data, uint16_t length) +{ + uint8_t *dataT = data; + uint16_t crc16 = Crc16(data, length); + + /*低前高后*/ + dataT[length] = (uint8_t)(crc16 & 0x00FF); + dataT[length + 1] = (uint8_t)(crc16 >> 8); +}