You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

147 line
3.8 KiB

  1. #include "modbus_rec_send.h"
  2. /*USART接收空闲中断*/
  3. void USART1_IRQHandler(void)
  4. {
  5. uint32_t temp;
  6. uint16_t rxLenRemain;
  7. OSIntEnter(); /*进入中断*/
  8. if(USART_GetITStatus(USART1, USART_IT_IDLE) == SET)
  9. {
  10. /*清除IDLE中断标志位*/
  11. temp = USART1->SR;
  12. temp = USART1->DR;
  13. (void)temp;
  14. /*判断是否接收到帧,触发TIM计时*/
  15. rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2);
  16. if(rxLenRemain != MODBUS_RX_BUF_SIZE)
  17. {
  18. /*启动TIM计时*/
  19. TIM_Cmd(TIM5, DISABLE);
  20. TIM_SetCounter(TIM5, 0); /*清除计数值*/
  21. //TIM_ClearITPendingBit(TIM5, TIM_IT_Update); /*清除中断标志位*/
  22. TIM_Cmd(TIM5, ENABLE);
  23. }
  24. }
  25. OSIntExit(); /*退出中断*/
  26. }
  27. /*TIM定时器中断*/
  28. void TIM5_IRQHandler(void)
  29. {
  30. uint16_t rxLenRemain;
  31. OSIntEnter();
  32. if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
  33. {
  34. /*清除TIM5更新中断标志*/
  35. TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
  36. /*关闭DMA*/
  37. DMA_Cmd(DMA2_Stream2, DISABLE);
  38. /*清除传输已经完成TCIF2、传输已经完成一半HTIF2标志位*/
  39. DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2 | DMA_FLAG_HTIF2);
  40. /*计算数据长度*/
  41. rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2);
  42. ModbusRxLen = MODBUS_RX_BUF_SIZE - rxLenRemain;
  43. /*释放接收到数据帧信号量,唤醒帧解析任务*/
  44. if(ModbusRxLen >= 4) /*4字节(1字节地址、1字节功能、2字节CRC)*/
  45. {
  46. OSSemPost(ModbusReceived);
  47. }
  48. /*重新指定接收地址*/
  49. DMA_MemoryTargetConfig(DMA2_Stream2, (uint32_t)ModbusRxBuf, DMA_Memory_0);
  50. /*重启DMA*/
  51. DMA_SetCurrDataCounter(DMA2_Stream2, MODBUS_RX_BUF_SIZE);
  52. DMA_Cmd(DMA2_Stream2, ENABLE);
  53. }
  54. OSIntExit();
  55. }
  56. /*modbus响应帧发送*/
  57. void ModbusSend(uint8_t *txBuf, uint16_t len)
  58. {
  59. if(DMA_GetCmdStatus(DMA2_Stream7) == ENABLE)
  60. {
  61. /*等待DMA发送完成*/
  62. while(DMA_GetFlagStatus(DMA2_Stream7, DMA_FLAG_TCIF7) == RESET);
  63. }
  64. /*先关闭DMA发送通道*/
  65. DMA_Cmd(DMA2_Stream7, DISABLE);
  66. /*等待DMA关闭*/
  67. while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);
  68. /*清除传输已经完成TCIF7、传输已经完成一半HTIF7、FIFO错误FEIF7标志位*/
  69. DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_FEIF7 | DMA_FLAG_HTIF7 | DMA_FLAG_TCIF7);
  70. /*配置发送地址和长度*/
  71. DMA_MemoryTargetConfig(DMA2_Stream7, (uint32_t)txBuf, DMA_Memory_0);
  72. DMA_SetCurrDataCounter(DMA2_Stream7, len);
  73. /*等待串口发送完成*/
  74. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  75. /*启动 DMA 发送*/
  76. DMA_Cmd(DMA2_Stream7, ENABLE);
  77. }
  78. /*crc16校验*/
  79. uint16_t Crc16(const uint8_t *data, uint16_t length)
  80. {
  81. uint16_t crc;
  82. uint16_t byteInd;
  83. uint8_t bitInd;
  84. crc = 0xFFFFu;
  85. for (byteInd = 0u; byteInd < length; byteInd++)
  86. {
  87. crc ^= (uint16_t)data[byteInd];
  88. for (bitInd = 0u; bitInd < 8u; bitInd++)
  89. {
  90. if ((crc & 0x0001u) != 0u)
  91. {
  92. crc >>= 1;
  93. crc ^= 0xA001u;
  94. }
  95. else
  96. {
  97. crc >>= 1;
  98. }
  99. }
  100. }
  101. return crc;
  102. }
  103. /*crc16检查*/
  104. int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length)
  105. {
  106. uint16_t crc16 = Crc16(data, (length - 2));
  107. if(recCrc16 == crc16)
  108. {
  109. return 0;
  110. }
  111. else
  112. {
  113. return -1;
  114. }
  115. }
  116. void AddCrc16(uint8_t *data, uint16_t length)
  117. {
  118. uint8_t *dataT = data;
  119. uint16_t crc16 = Crc16(data, length);
  120. /*低前高后*/
  121. dataT[length] = (uint8_t)(crc16 & 0x00FF);
  122. dataT[length + 1] = (uint8_t)(crc16 >> 8);
  123. }