#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); }