野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 29658|回复: 20

学习modbus移植串口无法接收数据。

[复制链接]
发表于 2020-9-9 11:30:30 | 显示全部楼层 |阅读模式
打算移植一个modbus协议https://gitee.com/qq1847123212/ModBus-Master 这个是别人用arduino 上移植过来的https://github.com/4-20ma/ModbusMaster  在AVR上用过发现不错。现在移植出了问题。就是接收函数返回超时。参考hal库写了一个也不可以。调试发现无法接受完整数据。大神赐教思路https://www.firebbs.cn/forum.php?mod=attachment&aid=MjgxNTN8YzU4MjNjNzI1Nzg5ZmI1ZmFmYzM2M2RhMmVmZGU4MmV8MTczMjM4OTYwOA%3D%3D&request=yes&_f=.zipattach://28153.zip STM32F103 modbus.zip (449.24 KB, 下载次数: 29)
回复

使用道具 举报

发表于 2020-9-9 22:07:40 | 显示全部楼层
FreeRTOS和FreeMODBUS移植到STM32F103傻瓜教程(Keil5).pdf

https://download.csdn.net/download/ba_wang_mao/12054217
回复 支持 反对

使用道具 举报

发表于 2020-9-9 22:16:09 | 显示全部楼层
喔!你要的是MODBUS 主站
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-10 11:04:58 | 显示全部楼层
ba_wang_mao 发表于 2020-9-9 22:16
喔!你要的是MODBUS 主站

谢谢,freertos我也会移植,就是modbus master搞来搞去还没有调出来。如果小芯片用上rtos 简直噩梦,所以想搞个无RTOS的modbus master
回复 支持 反对

使用道具 举报

发表于 2020-9-10 11:50:55 | 显示全部楼层
搞MODBUS MASTER我一般使用队列+状态机实现,效果非常不错
回复 支持 反对

使用道具 举报

发表于 2020-9-10 11:51:48 | 显示全部楼层
本帖最后由 ba_wang_mao 于 2020-9-10 11:54 编辑
  1. #ifndef __MODBUS_HOSTS_RTU__H
  2. #define __MODBUS_HOSTS_RTU__H



  3. #include "stm32f4xx.h"



  4. #define MODBUS_HOSTS_FUNC_ReadCoil                                                        (0x01)
  5. #define MODBUS_HOSTS_FUNC_ReadDiscrete                                                (0x02)
  6. #define        MODBUS_HOSTS_FUNC_ReadHoldingRegisters                                (0x03)
  7. #define        MODBUS_HOSTS_FUNC_ReadInputRegisters                                (0x04)
  8. #define MODBUS_HOSTS_FUNC_ForceSingleCoil                                        (0x05)
  9. #define        MODBUS_HOSTS_FUNC_PresetSingleHoldingRegister                (0x06)
  10. #define MODBUS_HOSTS_FUNC_ForceMultipleCoil                                        (0x0F)
  11. #define MODBUS_HOSTS_FUNC_PresetMultipleHoldingRegisters        (0x10)



  12. //MODBUS主站最大传输254字节,当波特率=115200时,1秒钟最大能够传输11520字节,则50毫秒能传输576字节
  13. //30毫秒能传输345字节,25毫秒能传输288字节,20毫秒能传输234字节



  14. #define MODBUS_HOSTS_POLL_TIME                                                                (8)
  15. #define MBHOSTS_MAX_REPEAT_SEND_COUNT                                                (5)



  16. enum MODBUS_HOSTS_STATUS
  17. {        
  18.         enum_MODBUS_STATUS_READY ,        
  19.         enum_MODBUS_STATUS_SEND_BEGIN ,
  20.         enum_MODBUS_STATUS_SEND_BEGINING ,        
  21.         enum_MODBUS_STATUS_SEND_OVER ,
  22.         enum_MODBUS_STATUS_RECV_OVER ,
  23.         enum_MODBUS_STATUS_RECV_ERROR ,
  24.         enum_MODBUS_STATUS_TIME_OUT ,
  25.         enum_MODBUS_STATUS_DELAY_TO_SEND_BEGIN ,        
  26.         enum_MODBUS_STATUS_DELAY_TO_READY ,
  27.         
  28. };

  29. <blockquote>void MBCOM1_MBHosts_Init(void);
复制代码


#endif // MODBUS_HOSTS_RTU_H
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-10 13:50:40 | 显示全部楼层
ba_wang_mao 发表于 2020-9-10 11:51
#endif // MODBUS_HOSTS_RTU_H

我自己写有bug,而且占用空间比较大
回复 支持 反对

使用道具 举报

发表于 2020-9-10 15:53:15 | 显示全部楼层
1.modbus_queue.h
  1. #ifndef MODBUS_QUEUE_H
  2. #define MODBUS_QUEUE_H

  3. #include "stm32f4xx.h"




  4. #define MODBUS_HOSTS_QUEUE_LEN                  (20)
  5. #define MODBUS_HOSTS_QUEUE_ELEMEMT_LEN  (255)





  6. typedef struct TagMODBUS_HOSTS_QUEUE
  7. {
  8.         uint8_t DeviceAddr;
  9.     uint8_t Func;
  10.         uint8_t CodeFunc;
  11.     uint8_t StartAddr;               
  12.     uint8_t RegisterAmount;               
  13.     uint8_t ByteCount;                       
  14.     uint8_t SendByteCount;       
  15.     int8_t  RepeatCount;
  16.     uint8_t Data[MODBUS_HOSTS_QUEUE_ELEMEMT_LEN];       
  17. } MODBUS_HOSTS_QUEUE;




  18. void MBHosts_Queue_Cls(void);
  19. void MBHosts_Queue_Init(void);
  20. uint8_t MBHosts_Queue_Empty(void);
  21. uint8_t MBHosts_Queue_Full(void);
  22. uint8_t MBHosts_In_Queue( MODBUS_HOSTS_QUEUE Queue);
  23. uint8_t MBHosts_Out_Queue(MODBUS_HOSTS_QUEUE *Queue);



  24. #endif // MODBUS_QUEUE_H
复制代码


回复 支持 反对

使用道具 举报

发表于 2020-9-10 15:55:35 | 显示全部楼层

2、modbus_hosts.h
  1. #ifndef MODBUS_HOSTS_RTU_H
  2. #define MODBUS_HOSTS_RTU_H

  3. #include "stm32f4xx.h"
  4. #include "modbus_queue.h"




  5. #define MODBUS_HOSTS_FUNC_ReadCoil                                                        (0x01)
  6. #define MODBUS_HOSTS_FUNC_ReadDiscrete                                                (0x02)
  7. #define        MODBUS_HOSTS_FUNC_ReadHoldingRegisters                                (0x03)
  8. #define        MODBUS_HOSTS_FUNC_ReadInputRegisters                                (0x04)
  9. #define MODBUS_HOSTS_FUNC_ForceSingleCoil                                        (0x05)
  10. #define        MODBUS_HOSTS_FUNC_PresetSingleHoldingRegister                (0x06)
  11. #define MODBUS_HOSTS_FUNC_ForceMultipleCoil                                        (0x0F)
  12. #define MODBUS_HOSTS_FUNC_PresetMultipleHoldingRegisters        (0x10)



  13. #define MODBUS_HOSTS_POLL_TIME                                                (20)



  14. enum MODBUS_HOSTS_STATUS
  15. {       
  16.         enum_MODBUS_STATUS_READY ,       
  17.         enum_MODBUS_STATUS_SEND_BEGIN ,
  18.         enum_MODBUS_STATUS_SEND_BEGINING ,       
  19.         enum_MODBUS_STATUS_SEND_OVER ,
  20.         enum_MODBUS_STATUS_RECV_OVER ,
  21.         enum_MODBUS_STATUS_RECV_ERROR ,
  22.         enum_MODBUS_STATUS_TIME_OUT ,
  23.         enum_MODBUS_STATUS_DELAY_TO_SEND_BEGIN ,       
  24.         enum_MODBUS_STATUS_DELAY_TO_READY ,
  25.        
  26. };



  27. uint16_t CRC16(uint8_t *puchMsg, uint16_t usDataLen);
  28. void MBHosts_Init(void);
  29. void MBHosts_ReadCoilRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint16_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  30. void MBHosts_ReadDiscreteRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint16_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  31. void MBHosts_ReadInputRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint8_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  32. void MBHosts_ReadHoldingRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint8_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  33. void MBHosts_ForceSingleCoil(uint8_t DeviceAddr , uint16_t startAddr , uint16_t On_Off , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  34. void MBHosts_PresetSingleHoldingRegister(uint8_t DeviceAddr , uint16_t startAddr , uint16_t Value , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  35. void MBHosts_ForceMultipleCoil(uint8_t DeviceAddr , uint16_t startAddr , uint16_t registerAmount , uint8_t Data_Buffer[] , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue);
  36. void MBHosts_PresetMultipleHoldingRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint8_t registerAmount , int16_t Data_Buffer[] , uint8_t RepeatCount , uint8_t Func , MODBUS_HOSTS_QUEUE *Queue);




  37. #endif // MODBUS_HOSTS_RTU_H
复制代码



回复 支持 反对

使用道具 举报

发表于 2020-9-10 15:58:13 | 显示全部楼层
本帖最后由 ba_wang_mao 于 2020-9-12 15:13 编辑

3.modbus_hosts.c


  1. #include "modbus_hosts.h"



  2. const uint8_t auchCRCHi[] = {
  3. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  4. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  5. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  6. 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  7. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  8. 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  9. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  10. 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  11. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  12. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  13. 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  14. 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  15. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  16. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  17. 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  18. 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  19. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  20. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  21. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  22. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  23. 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  24. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  25. 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  26. 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  27. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  28. 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  29. };




  30. const uint8_t auchCRCLo[] = {
  31. 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
  32. 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
  33. 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
  34. 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
  35. 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
  36. 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
  37. 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
  38. 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
  39. 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
  40. 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
  41. 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
  42. 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
  43. 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
  44. 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
  45. 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
  46. 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
  47. 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
  48. 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
  49. 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
  50. 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
  51. 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
  52. 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
  53. 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
  54. 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
  55. 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
  56. 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
  57. };




  58. uint16_t CRC16(uint8_t *puchMsg, uint16_t usDataLen)
  59. {
  60.         uint8_t uchCRCHi = 0xFF;
  61.         uint8_t uchCRCLo = 0xFF;
  62.         uint32_t uIndex;

  63.         while (usDataLen--)
  64.         {
  65.                 uIndex = uchCRCHi ^ *puchMsg++;
  66.                 uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
  67.                 uchCRCLo = auchCRCLo[uIndex];
  68.         }
  69.         return (uchCRCHi << 8 | uchCRCLo);
  70. }





  71. //void MBHosts_Init(void)
  72. //{
  73. //    MBHosts_Queue_Init();
  74. //}




  75. void MBHosts_ReadCoilRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint16_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  76. {
  77.         uint8_t i;        
  78.         uint8_t ByteCount;
  79.         uint16_t crcData;
  80.         
  81.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  82.                 Queue->Data[i] = 0x00;
  83.         Queue->Data[0] = DeviceAddr;
  84.         Queue->Data[1] = MODBUS_HOSTS_FUNC_ReadCoil;
  85.         Queue->Data[2] = startAddr >> 0x08;
  86.         Queue->Data[3] = startAddr & 0xFF;
  87.         Queue->Data[4] = registerAmount >> 0x08;
  88.         Queue->Data[5] = registerAmount & 0xFF;
  89.         crcData = CRC16(Queue->Data , 6);
  90.         Queue->Data[6] = crcData >> 0x08;
  91.         Queue->Data[7] = crcData & 0xFF;
  92.         
  93.         ByteCount = registerAmount >> 0x03;
  94.         if (registerAmount & 0x07)
  95.                 ByteCount++;        
  96.         Queue->DeviceAddr = DeviceAddr;
  97.         Queue->Func = MODBUS_HOSTS_FUNC_ReadCoil;
  98.         Queue->StartAddr = startAddr;
  99.         Queue->RegisterAmount = registerAmount;
  100.         Queue->ByteCount = ByteCount;
  101.         Queue->SendByteCount = 0x08;
  102.         Queue->RepeatCount = RepeatCount;
  103. }



  104. void MBHosts_ReadDiscreteRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint16_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  105. {
  106.         uint8_t i;               
  107.         uint8_t ByteCount;
  108.         uint16_t crcData;

  109.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  110.                 Queue->Data[i] = 0x00;
  111.         Queue->Data[0] = DeviceAddr;
  112.         Queue->Data[1] = MODBUS_HOSTS_FUNC_ReadDiscrete;
  113.         Queue->Data[2] = startAddr >> 0x08;
  114.         Queue->Data[3] = startAddr & 0xFF;
  115.         Queue->Data[4] = registerAmount >> 0x08;
  116.         Queue->Data[5] = registerAmount & 0xFF;
  117.         crcData = CRC16(Queue->Data , 6);
  118.         Queue->Data[6] = crcData >> 0x08;
  119.         Queue->Data[7] = crcData & 0xFF;        
  120.         ByteCount = registerAmount >> 0x03;
  121.         if (registerAmount & 0x07)
  122.                 ByteCount++;
  123.         Queue->DeviceAddr = DeviceAddr;
  124.         Queue->Func = MODBUS_HOSTS_FUNC_ReadDiscrete;        
  125.         Queue->StartAddr = startAddr;
  126.         Queue->RegisterAmount = registerAmount;
  127.         Queue->ByteCount = ByteCount;
  128.         Queue->SendByteCount = 0x08;
  129.         Queue->RepeatCount = RepeatCount;
  130. }



  131. void MBHosts_ReadInputRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint8_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  132. {
  133.         uint8_t i;        
  134.         uint16_t crcData;

  135.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  136.                 Queue->Data[i] = 0x00;        
  137.         Queue->Data[0] = DeviceAddr;
  138.         Queue->Data[1] = MODBUS_HOSTS_FUNC_ReadInputRegisters;
  139.         Queue->Data[2] = startAddr >> 0x08;
  140.         Queue->Data[3] = startAddr & 0xFF;
  141.         Queue->Data[4] = registerAmount >> 0x08;
  142.         Queue->Data[5] = registerAmount & 0xFF;
  143.         crcData = CRC16(Queue->Data , 6);
  144.         Queue->Data[6] = crcData >> 0x08;
  145.         Queue->Data[7] = crcData & 0xFF;
  146.         Queue->DeviceAddr = DeviceAddr;
  147.         Queue->Func = MODBUS_HOSTS_FUNC_ReadInputRegisters;
  148.         Queue->StartAddr = startAddr;
  149.         Queue->RegisterAmount = registerAmount;
  150.         Queue->ByteCount = registerAmount << 0x01;
  151.         Queue->SendByteCount = 0x08;
  152.         Queue->RepeatCount = RepeatCount;
  153. }



  154. void MBHosts_ReadHoldingRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint8_t registerAmount , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  155. {
  156.         uint8_t i;        
  157.         uint16_t crcData;

  158.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  159.                 Queue->Data[i] = 0x00;        
  160.         Queue->Data[0] = DeviceAddr;
  161.         Queue->Data[1] = MODBUS_HOSTS_FUNC_ReadHoldingRegisters;
  162.         Queue->Data[2] = startAddr >> 0x08;
  163.         Queue->Data[3] = startAddr & 0xFF;
  164.         Queue->Data[4] = registerAmount >> 0x08;
  165.         Queue->Data[5] = registerAmount & 0xFF;
  166.         crcData = CRC16(Queue->Data , 6);
  167.         Queue->Data[6] = crcData >> 0x08;
  168.         Queue->Data[7] = crcData & 0xFF;
  169.         Queue->DeviceAddr = DeviceAddr;
  170.         Queue->Func = MODBUS_HOSTS_FUNC_ReadHoldingRegisters;
  171.         Queue->StartAddr = startAddr;
  172.         Queue->RegisterAmount = registerAmount;
  173.         Queue->ByteCount = registerAmount << 0x01;
  174.         Queue->SendByteCount = 0x08;
  175.         Queue->RepeatCount = RepeatCount;
  176.         //In_Queue(*Queue);
  177. }



  178. void MBHosts_ForceSingleCoil(uint8_t DeviceAddr , uint16_t startAddr , uint16_t On_Off , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  179. {
  180.         uint8_t i;        
  181.         uint16_t crcData;

  182.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  183.                 Queue->Data[i] = 0x00;        
  184.         Queue->Data[0] = DeviceAddr;
  185.         Queue->Data[1] = MODBUS_HOSTS_FUNC_ForceSingleCoil;
  186.         Queue->Data[2] = startAddr >> 0x08;
  187.         Queue->Data[3] = startAddr & 0xFF;
  188.         if (On_Off)
  189.                 Queue->Data[4] = 0xFF;        // (4,5) = 0x0000/0xFF00
  190.         else
  191.                 Queue->Data[4] = 0x00;        // (4,5) = 0x0000/0xFF00
  192.         Queue->Data[5] = 0x00;
  193.         crcData = CRC16(Queue->Data , 6);
  194.         Queue->Data[6] = crcData >> 0x08;
  195.         Queue->Data[7] = crcData & 0xFF;
  196.         Queue->DeviceAddr = DeviceAddr;
  197.         Queue->Func = MODBUS_HOSTS_FUNC_ForceSingleCoil;
  198.         Queue->StartAddr = startAddr;
  199.         Queue->RegisterAmount = 1;                                                        //        无意义
  200.         Queue->ByteCount = Queue->RegisterAmount << 0x01;        //        无意义
  201.         Queue->SendByteCount = 0x08;
  202.         Queue->RepeatCount = RepeatCount;
  203.         //In_Queue(*Queue);
  204. }



  205. void MBHosts_PresetSingleHoldingRegister(uint8_t DeviceAddr , uint16_t startAddr , uint16_t Value , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  206. {
  207.         uint8_t i;        
  208.         uint16_t crcData;

  209.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  210.                 Queue->Data[i] = 0x00;

  211.         Queue->Data[0] = DeviceAddr;
  212.         Queue->Data[1] = MODBUS_HOSTS_FUNC_PresetSingleHoldingRegister;
  213.         Queue->Data[2] = startAddr >> 0x08;
  214.         Queue->Data[3] = startAddr & 0xFF;
  215.         Queue->Data[4] = Value >> 0x08;
  216.         Queue->Data[5] = Value & 0xFF;
  217.         crcData = CRC16(Queue->Data , 6);
  218.         Queue->Data[6] = crcData >> 0x08;
  219.         Queue->Data[7] = crcData & 0xFF;        
  220.         Queue->DeviceAddr = DeviceAddr;
  221.         Queue->Func = MODBUS_HOSTS_FUNC_PresetSingleHoldingRegister;
  222.         Queue->StartAddr = startAddr;
  223.         Queue->RegisterAmount = 1;
  224.         Queue->ByteCount = Queue->RegisterAmount << 0x01;
  225.         Queue->SendByteCount = 0x08;
  226.         Queue->RepeatCount = RepeatCount;
  227.         //In_Queue(*Queue);        
  228. }



  229. void MBHosts_ForceMultipleCoil(uint8_t DeviceAddr , uint16_t startAddr , uint16_t registerAmount , uint8_t Data_Buffer[] , uint8_t RepeatCount , MODBUS_HOSTS_QUEUE *Queue)
  230. {
  231.         uint8_t i;        
  232.         uint8_t j;
  233.         uint16_t k;
  234.         uint8_t ByteCount;
  235.         uint16_t crcData;

  236.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  237.                 Queue->Data[i] = 0x00;
  238.         Queue->Data[0] = DeviceAddr;
  239.         Queue->Data[1] = MODBUS_HOSTS_FUNC_ForceMultipleCoil;
  240.         Queue->Data[2] = startAddr >> 0x08;
  241.         Queue->Data[3] = startAddr & 0xFF;
  242.         Queue->Data[4] = registerAmount >> 0x08;
  243.         Queue->Data[5] = registerAmount & 0xFF;        
  244.         ByteCount = registerAmount >> 3;
  245.         if (registerAmount & 0x07)
  246.                 ByteCount++;
  247.         Queue->Data[6] = ByteCount;               
  248.         k = 0x00;
  249.         for (i = 0 ; i < ByteCount ; i++)
  250.         {
  251.                 Queue->Data[i + 7] = 0x00;
  252.                 for (j = 0 ; j < 8 ; j++ )
  253.                 {
  254.                         Queue->Data[i + 7] |=  (Data_Buffer[k] << j);
  255.                         k++;
  256.                         if (k >= registerAmount)
  257.                                 break;
  258.                 }
  259.         }                                       
  260.         crcData = CRC16(Queue->Data , (ByteCount + 9) - 2);
  261.         Queue->Data[(ByteCount + 9) - 2] = crcData >> 0x08;
  262.         Queue->Data[(ByteCount + 9) - 1] = crcData & 0xFF;        
  263.         Queue->DeviceAddr = DeviceAddr;
  264.         Queue->Func = MODBUS_HOSTS_FUNC_ForceMultipleCoil;
  265.         Queue->StartAddr = startAddr;
  266.         Queue->RegisterAmount = registerAmount;
  267.         Queue->ByteCount = ByteCount;
  268.         Queue->SendByteCount = ByteCount + 9;
  269.         Queue->RepeatCount = RepeatCount;
  270.         //In_Queue(*Queue);        
  271. }



  272. void MBHosts_PresetMultipleHoldingRegisters(uint8_t DeviceAddr , uint16_t startAddr , uint8_t registerAmount , int16_t Data_Buffer[] , uint8_t RepeatCount , uint8_t Func , MODBUS_HOSTS_QUEUE *Queue)
  273. {
  274.         uint8_t i;        
  275.         uint8_t k;
  276.         uint8_t ByteCount;
  277.         uint16_t crcData;

  278.         for (i = 0; i < MODBUS_HOSTS_QUEUE_ELEMEMT_LEN ; i++)
  279.                 Queue->Data[i] = 0x00;
  280.         Queue->Data[0] = DeviceAddr;
  281.         Queue->Data[1] = MODBUS_HOSTS_FUNC_PresetMultipleHoldingRegisters;
  282.         Queue->Data[2] = startAddr >> 0x08;
  283.         Queue->Data[3] = startAddr & 0xFF;
  284.         Queue->Data[4] = registerAmount >> 0x08;
  285.         Queue->Data[5] = registerAmount & 0xFF;
  286.         ByteCount = registerAmount << 0x01;
  287.         Queue->Data[6] = ByteCount;
  288.         for (k = 0 ; k < ByteCount ; k++)
  289.         {
  290.                 Queue->Data[7+2*k] = Data_Buffer[k] >> 0x08;
  291.                 Queue->Data[7+2*k+1] = Data_Buffer[k] & 0xFF;
  292.         }
  293.         crcData = CRC16(Queue->Data , (ByteCount + 9) - 2);
  294.         Queue->Data[(ByteCount + 9) - 2] = crcData >> 0x08;
  295.         Queue->Data[(ByteCount + 9) - 1] = crcData & 0xFF;
  296.         Queue->DeviceAddr = DeviceAddr;
  297.         Queue->Func = MODBUS_HOSTS_FUNC_PresetMultipleHoldingRegisters;
  298.         Queue->CodeFunc = Func;
  299.         Queue->StartAddr = startAddr;
  300.         Queue->RegisterAmount = registerAmount;
  301.         Queue->ByteCount = ByteCount;
  302.         Queue->SendByteCount = ByteCount + 9;
  303.         Queue->RepeatCount = RepeatCount;
  304.         //In_Queue(*Queue);        
  305. }




复制代码


回复 支持 反对

使用道具 举报

发表于 2020-9-10 16:02:03 | 显示全部楼层
4.modbus_queue.c

  1. #include "modbus_queue.h"


  2. uint16_t MBHosts_front = 0x00;                                       
  3. uint16_t MBHosts_rear = 0x00;        
  4. MODBUS_HOSTS_QUEUE MBHosts_Element[MODBUS_HOSTS_QUEUE_LEN];




  5. void MBHosts_Queue_Cls(void)
  6. {
  7.         MBHosts_front = 0x00;
  8.         MBHosts_rear = 0x00;
  9. }





  10. void MBHosts_Queue_Init(void)
  11. {
  12.         uint16_t i;

  13.         
  14.         MBHosts_Queue_Cls();
  15.         
  16.         for (i = 0; i < MODBUS_HOSTS_QUEUE_LEN; i++)
  17.         {
  18.                 MBHosts_Element[i].DeviceAddr = 0x00;               
  19.                 MBHosts_Element[i].Func = 0x00;
  20.                 MBHosts_Element[i].CodeFunc = 0x00;//自己定义的内部编码
  21.                 MBHosts_Element[i].StartAddr = 0x00;               
  22.                 MBHosts_Element[i].RegisterAmount = 0x00;
  23.                 MBHosts_Element[i].ByteCount = 0x00;
  24.                 MBHosts_Element[i].SendByteCount = 0x00;
  25.                 MBHosts_Element[i].RepeatCount = 0x00;
  26.                 memset(MBHosts_Element[i].Data , 0x00 , MODBUS_HOSTS_QUEUE_ELEMEMT_LEN);
  27.         }
  28. }




  29. BOOL MBHosts_Queue_Empty(void)
  30. {
  31.         return (MBHosts_rear == MBHosts_front);
  32. }




  33. BOOL MBHosts_Queue_Full(void)
  34. {
  35.         return ((MBHosts_rear + 1) % MODBUS_HOSTS_QUEUE_LEN == MBHosts_front);
  36. }




  37. BOOL  MBHosts_In_Queue( MODBUS_HOSTS_QUEUE Queue)
  38. {        
  39.         if (!MBHosts_Queue_Full())
  40.         {
  41.                 MBHosts_rear = (MBHosts_rear + 1) % MODBUS_HOSTS_QUEUE_LEN;
  42.                 MBHosts_Element[MBHosts_rear].DeviceAddr = Queue.DeviceAddr;
  43.                 MBHosts_Element[MBHosts_rear].Func = Queue.Func;        
  44.                 MBHosts_Element[MBHosts_rear].CodeFunc = Queue.CodeFunc;
  45.                 MBHosts_Element[MBHosts_rear].StartAddr = Queue.StartAddr;
  46.                 MBHosts_Element[MBHosts_rear].RegisterAmount = Queue.RegisterAmount;
  47.                 MBHosts_Element[MBHosts_rear].ByteCount = Queue.ByteCount;
  48.                 MBHosts_Element[MBHosts_rear].SendByteCount = Queue.SendByteCount;               
  49.                 MBHosts_Element[MBHosts_rear].RepeatCount = Queue.RepeatCount;
  50.                 memcpy(MBHosts_Element[MBHosts_rear].Data , Queue.Data , MODBUS_HOSTS_QUEUE_ELEMEMT_LEN);
  51.                 return (TRUE);
  52.         }
  53.         return (FALSE);
  54. }





  55. BOOL MBHosts_Out_Queue(MODBUS_HOSTS_QUEUE *Queue)
  56. {        
  57.         if (!MBHosts_Queue_Empty())
  58.         {
  59.                 MBHosts_front = (MBHosts_front + 1) % MODBUS_HOSTS_QUEUE_LEN;
  60.                 Queue->DeviceAddr = MBHosts_Element[MBHosts_front].DeviceAddr;
  61.                 Queue->Func = MBHosts_Element[MBHosts_front].Func;
  62.                 Queue->CodeFunc = MBHosts_Element[MBHosts_front].CodeFunc;
  63.                 Queue->StartAddr = MBHosts_Element[MBHosts_front].StartAddr;
  64.                 Queue->RegisterAmount = MBHosts_Element[MBHosts_front].RegisterAmount;
  65.                 Queue->ByteCount =  MBHosts_Element[MBHosts_front].ByteCount;
  66.                 Queue->SendByteCount = MBHosts_Element[MBHosts_front].SendByteCount;               
  67.                 Queue->RepeatCount = MBHosts_Element[MBHosts_front].RepeatCount;
  68.                 memcpy(Queue->Data , MBHosts_Element[MBHosts_front].Data , MODBUS_HOSTS_QUEUE_ELEMEMT_LEN);
  69.                 return (TRUE);
  70.         }
  71.         return (FALSE);
  72. }


复制代码


回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-10 17:54:44 | 显示全部楼层
向大神学习
回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:39:24 | 显示全部楼层
本帖最后由 ba_wang_mao 于 2020-9-10 20:40 编辑

5、串口缓冲区结构体

  1. typedef struct
  2. {
  3.     BOOL volatile Outtime_mark;        
  4.         uint8_t volatile MBHosts_Query_isr;
  5.         uint16_t volatile MBHosts_Poll_Time;
  6.     uint16_t volatile sendCount;
  7.     uint16_t volatile sendPosi;
  8.     uint16_t volatile receCount;
  9.     uint8_t send_buffer[MSCOMM_BUFFER_LENGTH];
  10.     uint8_t mscomm_buffer[MSCOMM_BUFFER_LENGTH];
  11. } USART_DataType;
复制代码



复制代码
回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:42:14 | 显示全部楼层
6、定时器T1用做主站超时定时器(主站一条报文发送出去后,不能无限制等待,必须在规定的时间内等待人机应答;如果从机没有在规定的时间应答,则认为超时)

  1. USART_DataType MB_USART2;

  2. //1000ms=11520byte , 100ms = 1152byte , 35ms = 403byte
  3. void TIM1_Configuration(void)
  4. {
  5.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;


  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
  7.     TIM_DeInit(TIM1);
  8.         TIM_InternalClockConfig(TIM1);
  9.     TIM_TimeBaseStructure.TIM_Period = 10000 - 1;
  10.         TIM_TimeBaseStructure.TIM_Prescaler = 588;//(168=10ms,84=5ms,504=30ms,588=35ms,839=50ms,1679=100ms)
  11.     TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  12.     TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
  13.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  14.     TIM_ClearFlag(TIM1, TIM_FLAG_Update);
  15.         TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
  16.         TIM_Cmd(TIM1, DISABLE);
  17. }


  18. void TIM1_UP_TIM10_IRQHandler(void)
  19. {
  20.                
  21.         if (TIM_GetITStatus(TIM1,TIM_IT_Update) != RESET)
  22.         {
  23.                 TIM_ClearITPendingBit(TIM1,TIM_IT_Update);               
  24.                 TIM_Cmd(TIM1, DISABLE);
  25.                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  26.                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_TIME_OUT;     //超时
  27.         }
  28. }

复制代码


回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:44:27 | 显示全部楼层
7、串口+DMA接收MODBUS从机报文

  1. void USART2_IRQHandler(void)
  2. {
  3.         int16_t ch;

  4.        
  5.         if (USART_GetITStatus(USART2,USART_IT_IDLE) != RESET)
  6.         {               
  7.                 USART_ClearITPendingBit(USART2 , USART_IT_IDLE);        //必须先清除总线空闲中断标识,然后读一下数据寄存器,DMA接收才会正确(先读SR,然后读DR才能清除空闲中断标识)注意:这句必须要,否则不能够清除中断标志位。
  8.                 ch =  USART_ReceiveData(USART2);
  9.                

  10.                
  11.                 DMA_Cmd(DMA1_Stream5 , DISABLE);                                         //关闭DMA,防止处理其间有数据
  12.                 DMA_ClearFlag(DMA1_Stream5 , DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//清零标志位
  13.                 ch = USART2_DMA_RX_BUFFER_MAX_LENGTH - DMA_GetCurrDataCounter(DMA1_Stream5);
  14.                 if (ch > 0)
  15.                 {
  16.                         if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  17.                         {
  18.                                 MB_USART2.Outtime_mark = TRUE;
  19.                                 MB_USART2.receCount = ch;
  20.                                 memcpy(MB_USART2.mscomm_buffer , USART2_DMA_RX_Buffer , MB_USART2.receCount);
  21.                         }
  22.                 }
  23.                 DMA_SetCurrDataCounter(DMA1_Stream5 , USART2_DMA_RX_BUFFER_MAX_LENGTH);
  24.                 DMA_Cmd(DMA1_Stream5, ENABLE);
  25.         }
  26.        
  27.         else if (USART_GetITStatus(USART2,USART_IT_TC)!= RESET)
  28.         {
  29.                 USART_ClearITPendingBit(USART2, USART_IT_TC);
  30.                

  31.                

  32.                 DMA_ClearFlag(DMA1_Stream6 , DMA_FLAG_TCIF6 | DMA_FLAG_FEIF6 | DMA_FLAG_DMEIF6 | DMA_FLAG_TEIF6 | DMA_FLAG_HTIF6);
  33.                 DMA_SetCurrDataCounter(DMA1_Stream6 , 0);                        //清除数据长度
  34.                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_BEGINING)
  35.                 {
  36.                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_SEND_OVER;               
  37.                         TIM_Cmd(TIM1, DISABLE);
  38.                         TIM_SetCounter(TIM1, 0x00);
  39.                         TIM_Cmd(TIM1, ENABLE);
  40.                 }               
  41.                 GPIO_USART2_RS485_RECIVE_enable();
  42.         }
  43.        
  44. }
复制代码


回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:46:24 | 显示全部楼层
8. STM32F407   DMA程序

  1. uint8_t USART1_DMA_RX_Buffer[USART1_DMA_RX_BUFFER_MAX_LENGTH];
  2. uint8_t USART1_DMA_TX_Buffer[USART1_DMA_TX_BUFFER_MAX_LENGTH];

  3. uint8_t USART2_DMA_RX_Buffer[USART2_DMA_RX_BUFFER_MAX_LENGTH];
  4. uint8_t USART2_DMA_TX_Buffer[USART2_DMA_TX_BUFFER_MAX_LENGTH];

  5. uint8_t USART3_DMA_RX_Buffer[USART3_DMA_RX_BUFFER_MAX_LENGTH];
  6. uint8_t USART3_DMA_TX_Buffer[USART3_DMA_TX_BUFFER_MAX_LENGTH];


  7. uint8_t UART4_DMA_RX_Buffer[UART4_DMA_RX_BUFFER_MAX_LENGTH];
  8. uint8_t UART4_DMA_TX_Buffer[UART4_DMA_TX_BUFFER_MAX_LENGTH];

  9. uint8_t UART5_DMA_RX_Buffer[UART5_DMA_RX_BUFFER_MAX_LENGTH];
  10. uint8_t UART5_DMA_TX_Buffer[UART5_DMA_TX_BUFFER_MAX_LENGTH];

  11. uint8_t USART6_DMA_RX_Buffer[USART6_DMA_RX_BUFFER_MAX_LENGTH];
  12. uint8_t USART6_DMA_TX_Buffer[USART6_DMA_TX_BUFFER_MAX_LENGTH];


  13. //DMA是高速传输模式,一般是ns级的速度,485是慢速传输,一般是ms级最多是us级的传输


  14. void USART1_DMA_Tx_Configuration(void)
  15. {
  16.         DMA_InitTypeDef  DMA_InitStructure;
  17.        
  18.        
  19.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);                                        //DMA2时钟使能
  20.         DMA_DeInit(DMA2_Stream7);
  21.         while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);                                                //等待DMA可配置
  22.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                         //DMA通道配置
  23.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;                //DMA外设地址
  24.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART1_DMA_TX_Buffer;        //发送缓存指针
  25.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
  26.         DMA_InitStructure.DMA_BufferSize = USART1_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
  27.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  28.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  29.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  30.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  31.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  32.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
  33.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  34.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  35.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  36.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  37.         DMA_Init(DMA2_Stream7, &DMA_InitStructure);                                                                //初始化DMA Stream
  38.         DMA_Cmd(DMA2_Stream7, DISABLE);                                                                                 //开启DMA传输
  39. }





  40. void USART1_DMA_Rx_Configuration(void)
  41. {
  42.         DMA_InitTypeDef  DMA_InitStructure;

  43.        
  44.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);                                        //DMA2时钟使能
  45.         DMA_DeInit(DMA2_Stream5);
  46.         while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE);                                                //等待DMA可配置  
  47.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                  //通道选择
  48.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;                //DMA外设地址
  49.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART1_DMA_RX_Buffer;        //接收缓存指针
  50.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
  51.         DMA_InitStructure.DMA_BufferSize = USART1_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
  52.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  53.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  54.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  55.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  56.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  57.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
  58.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  59.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  60.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  61.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  62.         DMA_Init(DMA2_Stream5 , &DMA_InitStructure);                                                        //初始化DMA_Stream5       
  63.         DMA_Cmd(DMA2_Stream5, ENABLE);                                                                                  //开启DMA传输
  64. }






  65. void USART2_DMA_Tx_Configuration(void)
  66. {
  67.         DMA_InitTypeDef  DMA_InitStructure;
  68.        
  69.        
  70.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
  71.         DMA_DeInit(DMA1_Stream6);
  72.         while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);                                                //等待DMA可配置
  73.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                         //DMA通道配置
  74.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;                //DMA外设地址
  75.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART2_DMA_TX_Buffer;        //发送缓存指针
  76.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
  77.         DMA_InitStructure.DMA_BufferSize = USART2_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
  78.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  79.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  80.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  81.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位       
  82.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  83.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
  84.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  85.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  86.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  87.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  88.         DMA_Init(DMA1_Stream6, &DMA_InitStructure);                                                                //初始化DMA Stream
  89.         DMA_Cmd(DMA1_Stream6, DISABLE);                                                                                 //开启DMA传输
  90. }





  91. void USART2_DMA_Rx_Configuration(void)
  92. {
  93.         DMA_InitTypeDef  DMA_InitStructure;

  94.        
  95.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
  96.         DMA_DeInit(DMA1_Stream5);
  97.         while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE);                                                //等待DMA可配置  
  98.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                  //通道选择
  99.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;                //DMA外设地址
  100.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART2_DMA_RX_Buffer;        //接收缓存指针
  101.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
  102.         DMA_InitStructure.DMA_BufferSize = USART2_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
  103.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  104.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  105.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  106.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  107.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  108.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
  109.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  110.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  111.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  112.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  113.         DMA_Init(DMA1_Stream5 , &DMA_InitStructure);                                                        //初始化DMA_Stream       
  114.         DMA_Cmd(DMA1_Stream5, ENABLE);                                                                                  //开启DMA传输
  115. }





  116. void USART3_DMA_Tx_Configuration(void)
  117. {
  118.         DMA_InitTypeDef  DMA_InitStructure;
  119.        
  120.        
  121.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA2时钟使能
  122.         DMA_DeInit(DMA1_Stream3);
  123.         while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE);                                                //等待DMA可配置
  124.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                         //DMA通道配置
  125.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;                //DMA外设地址
  126.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART3_DMA_TX_Buffer;        //发送缓存指针
  127.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
  128.         DMA_InitStructure.DMA_BufferSize = USART3_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
  129.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  130.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  131.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  132.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位       
  133.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  134.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
  135.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  136.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  137.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  138.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  139.         DMA_Init(DMA1_Stream3, &DMA_InitStructure);                                                                //初始化DMA Stream
  140.         DMA_Cmd(DMA1_Stream3, DISABLE);                                                                                 //开启DMA传输
  141. }





  142. void USART3_DMA_Rx_Configuration(void)
  143. {
  144.         DMA_InitTypeDef  DMA_InitStructure;

  145.        
  146.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA2时钟使能
  147.         DMA_DeInit(DMA1_Stream1);
  148.         while (DMA_GetCmdStatus(DMA1_Stream1) != DISABLE);                                                //等待DMA可配置  
  149.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                  //通道选择
  150.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;                //DMA外设地址
  151.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART3_DMA_RX_Buffer;        //接收缓存指针
  152.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
  153.         DMA_InitStructure.DMA_BufferSize = USART3_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
  154.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  155.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  156.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  157.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  158.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  159.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
  160.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  161.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  162.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  163.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  164.         DMA_Init(DMA1_Stream1 , &DMA_InitStructure);                                                        //初始化DMA_Stream       
  165.         DMA_Cmd(DMA1_Stream1, ENABLE);                                                                                  //开启DMA传输
  166. }





  167. void UART4_DMA_Tx_Configuration(void)
  168. {
  169.         DMA_InitTypeDef  DMA_InitStructure;
  170.        
  171.        
  172.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
  173.         DMA_DeInit(DMA1_Stream4);
  174.         while (DMA_GetCmdStatus(DMA1_Stream4) != DISABLE);                                                //等待DMA可配置
  175.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                         //DMA通道配置
  176.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART4->DR;                //DMA外设地址
  177.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)UART4_DMA_TX_Buffer;        //发送缓存指针
  178.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
  179.         DMA_InitStructure.DMA_BufferSize = UART4_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
  180.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  181.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  182.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  183.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  184.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  185.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
  186.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  187.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  188.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  189.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  190.         DMA_Init(DMA1_Stream4, &DMA_InitStructure);                                                                //初始化DMA Stream
  191.         DMA_Cmd(DMA1_Stream4, DISABLE);                                                                                 //开启DMA传输
  192. }






  193. void UART4_DMA_Rx_Configuration(void)
  194. {
  195.         DMA_InitTypeDef  DMA_InitStructure;

  196.        
  197.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
  198.         DMA_DeInit(DMA1_Stream2);
  199.         while (DMA_GetCmdStatus(DMA1_Stream2) != DISABLE);                                                //等待DMA可配置  
  200.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                  //通道选择
  201.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART4->DR;                //DMA外设地址
  202.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)UART4_DMA_RX_Buffer;        //接收缓存指针
  203.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
  204.         DMA_InitStructure.DMA_BufferSize = UART4_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
  205.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  206.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  207.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  208.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  209.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  210.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
  211.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  212.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  213.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  214.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  215.         DMA_Init(DMA1_Stream2 , &DMA_InitStructure);                                                        //初始化DMA_Stream       
  216.         DMA_Cmd(DMA1_Stream2, ENABLE);                                                                                  //开启DMA传输
  217. }






  218. void UART5_DMA_Tx_Configuration(void)
  219. {
  220.         DMA_InitTypeDef  DMA_InitStructure;
  221.        
  222.        
  223.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
  224.         DMA_DeInit(DMA1_Stream7);
  225.         while (DMA_GetCmdStatus(DMA1_Stream7) != DISABLE);                                                //等待DMA可配置
  226.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                         //DMA通道配置
  227.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR;                //DMA外设地址
  228.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)UART5_DMA_TX_Buffer;        //发送缓存指针
  229.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
  230.         DMA_InitStructure.DMA_BufferSize = UART5_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
  231.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  232.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  233.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  234.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  235.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  236.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
  237.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  238.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  239.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  240.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  241.         DMA_Init(DMA1_Stream7, &DMA_InitStructure);                                                                //初始化DMA Stream
  242.         DMA_Cmd(DMA1_Stream7, DISABLE);                                                                                  //关闭DMA传输       

  243. }





  244. void UART5_DMA_Rx_Configuration(void)
  245. {
  246.         DMA_InitTypeDef  DMA_InitStructure;

  247.        
  248.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);                                        //DMA1时钟使能
  249.         DMA_DeInit(DMA1_Stream0);
  250.         while (DMA_GetCmdStatus(DMA1_Stream0) != DISABLE);                                                //等待DMA可配置  
  251.         DMA_InitStructure.DMA_Channel = DMA_Channel_4;                                                  //通道选择
  252.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR;                //DMA外设地址
  253.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)UART5_DMA_RX_Buffer;        //接收缓存指针
  254.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
  255.         DMA_InitStructure.DMA_BufferSize = UART5_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
  256.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  257.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  258.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  259.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  260.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  261.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
  262.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  263.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  264.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  265.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  266.         DMA_Init(DMA1_Stream0 , &DMA_InitStructure);
  267.         DMA_Cmd(DMA1_Stream0, ENABLE);                                                                                  //开启DMA传输
  268.        
  269. }





  270. ////////////////////////////////////////////////////////////////////////////////////////////
  271. //是否可以这么认为,USART6如果DMA的TX使用DMA2_Stream6,则USART6如果DMA的RX必须使用DMA2_Stream1
  272. //                 USART6如果DMA的TX使用DMA2_Stream7,则USART6如果DMA的RX必须使用DMA2_Stream2
  273. ////////////////////////////////////////////////////////////////////////////////////////////
  274. void USART6_DMA_Tx_Configuration(void)
  275. {
  276.         DMA_InitTypeDef  DMA_InitStructure;
  277.        
  278.        
  279.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);                                        //DMA2时钟使能
  280.         DMA_DeInit(DMA2_Stream6);
  281.         while (DMA_GetCmdStatus(DMA2_Stream6) != DISABLE);                                                //等待DMA可配置
  282.         DMA_InitStructure.DMA_Channel = DMA_Channel_5;                                                         //DMA通道配置
  283.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR;                //DMA外设地址
  284.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART6_DMA_TX_Buffer;        //发送缓存指针
  285.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                                        //DMA传输方向:内存--->外设
  286.         DMA_InitStructure.DMA_BufferSize = USART6_DMA_TX_BUFFER_MAX_LENGTH;                //数据传输字节数量
  287.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  288.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  289.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  290.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  291.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  292.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_High
  293.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  294.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  295.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  296.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  297.         DMA_Init(DMA2_Stream6 , &DMA_InitStructure);                                                        //初始化DMA Stream
  298.         DMA_Cmd(DMA2_Stream6 , DISABLE);                                                                                 //开启DMA传输
  299. }





  300. void USART6_DMA_Rx_Configuration(void)
  301. {
  302.         DMA_InitTypeDef  DMA_InitStructure;

  303.        
  304.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);                                        //DMA2时钟使能
  305.         DMA_DeInit(DMA2_Stream1);
  306.         while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE);                                                //等待DMA可配置  
  307.         DMA_InitStructure.DMA_Channel = DMA_Channel_5;                                                  //通道选择
  308.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR;                //DMA外设地址
  309.         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)USART6_DMA_RX_Buffer;        //接收缓存指针
  310.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;                                //DMA传输方向:外设到存储器模式:外设--->内存
  311.         DMA_InitStructure.DMA_BufferSize = USART6_DMA_RX_BUFFER_MAX_LENGTH;                //缓冲大小
  312.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //外设非增量模式
  313.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        //存储器增量模式
  314.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        //外设数据长度:8位
  315.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                        //存储器数据长度:8位
  316.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        //使用普通模式
  317.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                                        //中等优先级 DMA_Priority_VeryHigh
  318.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  319.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  320.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                //存储器突发单次传输
  321.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                //外设突发单次传输
  322.         DMA_Init(DMA2_Stream1 , &DMA_InitStructure);                                                        //初始化DMA_Stream5       
  323.         DMA_Cmd(DMA2_Stream1 , ENABLE);                                                                                  //开启DMA传输
  324. }






  325. void USART1_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
  326. {               
  327.         if (nSendCount < USART1_DMA_TX_BUFFER_MAX_LENGTH)
  328.         {
  329.                 memcpy(USART1_DMA_TX_Buffer , send_buffer , nSendCount);
  330.                 DMA_Cmd(DMA2_Stream7 , DISABLE);                    //关闭DMA传输
  331.                 while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);        //确保DMA可以被设置
  332.                 DMA_SetCurrDataCounter(DMA2_Stream7 , nSendCount);  //数据传输量
  333.                 DMA_Cmd(DMA2_Stream7 , ENABLE);                               //开启DMA传输
  334.         }
  335. }






  336. void USART2_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
  337. {               
  338.         if (nSendCount < USART2_DMA_TX_BUFFER_MAX_LENGTH)
  339.         {
  340.                 memcpy(USART2_DMA_TX_Buffer , send_buffer , nSendCount);
  341.                 DMA_Cmd(DMA1_Stream6 , DISABLE);                    //关闭DMA传输
  342.                 while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);        //确保DMA可以被设置
  343.                 DMA_SetCurrDataCounter(DMA1_Stream6 , nSendCount);  //数据传输量
  344.                 DMA_Cmd(DMA1_Stream6 , ENABLE);                               //开启DMA传输
  345.         }
  346. }





  347. void USART3_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
  348. {               
  349.         if (nSendCount < USART3_DMA_TX_BUFFER_MAX_LENGTH)
  350.         {
  351.                 memcpy(USART3_DMA_TX_Buffer , send_buffer , nSendCount);
  352.                 DMA_Cmd(DMA1_Stream3 , DISABLE);                    //关闭DMA传输
  353.                 while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE);        //确保DMA可以被设置
  354.                 DMA_SetCurrDataCounter(DMA1_Stream3 , nSendCount);  //数据传输量
  355.                 DMA_Cmd(DMA1_Stream3 , ENABLE);                               //开启DMA传输
  356.         }
  357. }





  358. void UART4_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
  359. {       
  360.         GPIO_UART4_RS485_SEND_enable();
  361.         if (nSendCount < UART4_DMA_TX_BUFFER_MAX_LENGTH)
  362.         {
  363.                 memcpy(UART4_DMA_TX_Buffer , send_buffer , nSendCount);
  364.                 DMA_Cmd(DMA1_Stream4 , DISABLE);                    //关闭DMA传输
  365.                 while (DMA_GetCmdStatus(DMA1_Stream4) != DISABLE);        //确保DMA可以被设置
  366.                 DMA_SetCurrDataCounter(DMA1_Stream4 , nSendCount);  //数据传输量
  367.                 DMA_Cmd(DMA1_Stream4 , ENABLE);                               //开启DMA传输
  368.         }
  369. }






  370. void UART5_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
  371. {       
  372.         if (nSendCount < UART5_DMA_TX_BUFFER_MAX_LENGTH)
  373.         {
  374.                 memcpy(UART5_DMA_TX_Buffer , send_buffer , nSendCount);
  375.                 DMA_Cmd(DMA1_Stream7 , DISABLE);                    //关闭DMA传输
  376.                 while (DMA_GetCmdStatus(DMA1_Stream7) != DISABLE);        //确保DMA可以被设置
  377.                 DMA_SetCurrDataCounter(DMA1_Stream7 , nSendCount);  //数据传输量
  378.                 DMA_Cmd(DMA1_Stream7 , ENABLE);                               //开启DMA传输
  379.         }
  380. }






  381. void USART6_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount)
  382. {       
  383.         if (nSendCount < USART6_DMA_TX_BUFFER_MAX_LENGTH)
  384.         {
  385.                 memcpy(USART6_DMA_TX_Buffer , send_buffer , nSendCount);
  386.                 DMA_Cmd(DMA2_Stream6 , DISABLE);                    //关闭DMA传输
  387.                 while (DMA_GetCmdStatus(DMA2_Stream6) != DISABLE);        //确保DMA可以被设置
  388.                 DMA_SetCurrDataCounter(DMA2_Stream6 , nSendCount);  //数据传输量
  389.                 DMA_Cmd(DMA2_Stream6 , ENABLE);                               //开启DMA传输
  390.         }
  391. }

复制代码




回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:48:14 | 显示全部楼层
9. 串口2+DMA配置初始化程序


  1. void USART2_Configuration(void)
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStructure;
  4.         USART_InitTypeDef USART_InitStructure;
  5.                

  6.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);         //for USART2, USART3, UART4 or UART5.       
  7.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  8.                
  9.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
  10.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);           

  11.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  12.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  13.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  14.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  15.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  18.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  19.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  20.        
  21.         USART_InitStructure.USART_BaudRate = 115200;
  22.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  23.         USART_InitStructure.USART_StopBits = USART_StopBits_1;
  24.         USART_InitStructure.USART_Parity = USART_Parity_No ;
  25.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  26.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  27.         USART_Init(USART2, &USART_InitStructure);
  28.         USART_Cmd(USART2, ENABLE);

  29.         USART_ClearFlag(USART2, USART_FLAG_TC); //清除发送完成标志       
  30.         while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);        //等待空闲帧发送完成后再清零发送完成标志(警告:如果不使能USART_Mode_Tx,会导致单片机在这里死机)
  31.         USART_ClearFlag(USART2, USART_FLAG_TC);        //清除发送完成标志

  32.     USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);                                //禁止USART1接收不为空中断
  33.         USART_ITConfig(USART2, USART_IT_TXE, DISABLE);                                //禁止USART1发送空中断
  34.         USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);                                //开启USART1空闲中断
  35.         USART_ITConfig(USART2, USART_IT_TC, ENABLE);                                //开启USART1传输完成中断
  36.        
  37.         USART_DMACmd(USART2 ,   USART_DMAReq_Tx,ENABLE);                          //使能串口的DMA发送
  38.         USART_DMACmd(USART2 ,   USART_DMAReq_Rx,ENABLE);                          //使能串口的DMA接收

  39. }
复制代码


回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:50:23 | 显示全部楼层
9、串口2变量初始化和串口2启动发送

  1. void MB_USART2_Init(void)
  2. {
  3.         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_READY;
  4.         MB_USART2.MBHosts_Poll_Time = 0x00;
  5.         MB_USART2.Outtime_mark = FALSE;
  6.     MB_USART2.sendCount = 0x00;
  7.     MB_USART2.sendPosi = 0x00;
  8.     MB_USART2.receCount = 0x00;       
  9.         memset(MB_USART2.send_buffer , 0x00 , MSCOMM_BUFFER_LENGTH);
  10.         memset(MB_USART2.mscomm_buffer , 0x00 , MSCOMM_BUFFER_LENGTH);       
  11. }



  12. void USART2_Begin_Send(void)
  13. {
  14. GPIO_USART2_RS485_SEND_enable();
  15.         __NOP();
  16.         __NOP();
  17.         __NOP();
  18.         __NOP();
  19.         __NOP();
  20.         __NOP();
  21.         __NOP();
  22.         __NOP();
  23.         __NOP();
  24.         __NOP();
  25.         __NOP();
  26.         __NOP();
  27.         __NOP();
  28.         __NOP();
  29.         __NOP();
  30.         __NOP();
  31.         __NOP();
  32.         __NOP();
  33.         __NOP();
  34.         __NOP();
  35.         __NOP();
  36.         __NOP();
  37.         __NOP();
  38.         __NOP();
  39.         __NOP();
  40.         __NOP();
  41.         __NOP();
  42.         __NOP();
  43.         __NOP();
  44.         __NOP();       
  45.         USART2_DMA_Begin_Send(MB_USART2.send_buffer , MB_USART2.sendCount);
  46. }
复制代码





回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:53:48 | 显示全部楼层
10.   modbus主站解析从站
  1. void MODBUS_Hosts_Analysize(void)
  2. {
  3.         uint16_t i,j,k;
  4.         uint16_t startAddr;
  5.         uint16_t registerAmount;
  6.         uint16_t tempData;
  7.         uint16_t crcData;

  8.                
  9.         if (MB_USART2.Outtime_mark)
  10.         {
  11.                 MB_USART2.Outtime_mark = FALSE;

  12.                 if (MB_USART2.receCount >= 5)
  13.         {

  14.                        
  15.             switch (MB_USART2.mscomm_buffer[1])
  16.             {
  17.                 case MODBUS_HOSTS_FUNC_ReadCoil:                                       
  18.                                         if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func && MB_USART2.mscomm_buffer[2] == USART2_MBHOSTS_Wait_Queue.ByteCount)
  19.                                         {
  20.                                                 tempData = MB_USART2.mscomm_buffer[2] + 5;
  21.                                                 if (MB_USART2.receCount == tempData)
  22.                                                 {
  23.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , tempData - 2);
  24.                                                         if (crcData == (uint16_t)(MB_USART2.mscomm_buffer[tempData - 2] << 8) + (uint16_t)MB_USART2.mscomm_buffer[tempData - 1])
  25.                                                         {
  26.                                                                 k = 0;
  27.                                                                 for (i = 0 ; i < USART2_MBHOSTS_Wait_Queue.ByteCount ; i++)
  28.                                                                 {
  29.                                                                         for (j = 0 ; j < 8 ; j++)
  30.                                                                         {
  31.                                                                                 if (MB_USART2.mscomm_buffer[3+i] & (0x01 << j))
  32.                                                                                 {
  33.                                                                                         ;//reg0x_buffer[k++] = 0x01;
  34.                                                                                 }
  35.                                                                                 else
  36.                                                                                 {
  37.                                                                                         ;//reg0x_buffer[k++] = 0x00;
  38.                                                                                 }
  39.                                                                                
  40.                                                                                 if (k >= USART2_MBHOSTS_Wait_Queue.RegisterAmount)
  41.                                                                                         break;
  42.                                                                         }
  43.                                                                 }                                                                       
  44.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  45.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  46.                                                                

  47.                                                         }
  48.                                                         else
  49.                                                         {
  50.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  51.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  52.                                                         }
  53.                         }
  54.                     }
  55.                     break;
  56.                                                                        
  57.                                        
  58.                case MODBUS_HOSTS_FUNC_ReadDiscrete:
  59.                                            if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func && MB_USART2.mscomm_buffer[2] == USART2_MBHOSTS_Wait_Queue.ByteCount)
  60.                                         {
  61.                                                 tempData = MB_USART2.mscomm_buffer[2] + 5;
  62.                                                 if (MB_USART2.receCount == tempData)
  63.                                                 {
  64.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , tempData - 2);
  65.                                                         if (crcData ==(((uint16_t)MB_USART2.mscomm_buffer[tempData - 2]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[tempData - 1])
  66.                                                         {
  67.                                                                 k = 0;
  68.                                                                 for (i = 0 ; i < USART2_MBHOSTS_Wait_Queue.ByteCount ; i++)
  69.                                                                 {
  70.                                                                         for (j = 0 ; j < 8 ; j++)
  71.                                                                         {
  72.                                                                                 if (MB_USART2.mscomm_buffer[3+i] & (0x01 << j))
  73.                                                                                 {
  74.                                                                                         ;//reg1x_buffer[k++] = 0x01;
  75.                                                                                 }
  76.                                                                                 else
  77.                                                                                 {
  78.                                                                                         ;//reg1x_buffer[k++] = 0x00;
  79.                                                                                 }

  80.                                                                                 if (k >= USART2_MBHOSTS_Wait_Queue.RegisterAmount)
  81.                                                                                         break;
  82.                                                                         }
  83.                                                                 }                                                       
  84.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  85.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  86.                                                                

  87.                             }
  88.                                                         else
  89.                                                         {
  90.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  91.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  92.                                                         }
  93.                         }
  94.                     }
  95.                     break;

  96.                                        
  97.                 case MODBUS_HOSTS_FUNC_ReadHoldingRegisters:
  98.                                         if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func && MB_USART2.mscomm_buffer[2] == USART2_MBHOSTS_Wait_Queue.ByteCount)
  99.                                         {
  100.                                                 tempData = MB_USART2.mscomm_buffer[2] + 5;
  101.                                                 if (MB_USART2.receCount == tempData)
  102.                                                 {
  103.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , tempData - 2);
  104.                                                         if (crcData ==(((uint16_t)MB_USART2.mscomm_buffer[tempData - 2]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[tempData - 1])
  105.                                                         {

  106.                                                                
  107.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  108.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  109.                                                                

  110.                                                         }
  111.                                                         else
  112.                                                         {
  113.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  114.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  115.                                                         }
  116.                                                 }
  117.                     }
  118.                     break;
  119.                                        
  120.                                
  121.                 case MODBUS_HOSTS_FUNC_ReadInputRegisters:                                       
  122.                                         if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func && MB_USART2.mscomm_buffer[2] == USART2_MBHOSTS_Wait_Queue.ByteCount)
  123.                                         {
  124.                                                 tempData = MB_USART2.mscomm_buffer[2] + 5;
  125.                                                 if (MB_USART2.receCount == tempData)
  126.                                                 {
  127.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , tempData - 2);
  128.                                                         if (crcData ==(((uint16_t)MB_USART2.mscomm_buffer[tempData - 2]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[tempData - 1])
  129.                                                         {
  130.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  131.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  132.                                                                

  133.                                                         }
  134.                                                         else
  135.                                                         {
  136.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  137.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  138.                                                         }
  139.                                                 }
  140.                     }
  141.                     break;


  142.                                 case MODBUS_HOSTS_FUNC_ForceSingleCoil:                                       
  143.                                         if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func)
  144.                                         {
  145.                                                 startAddr = (uint16_t)(MB_USART2.mscomm_buffer[2] << 8) + (uint16_t)MB_USART2.mscomm_buffer[3];
  146.                                                 if (MB_USART2.receCount == 8 && startAddr == USART2_MBHOSTS_Wait_Queue.StartAddr)
  147.                                                 {
  148.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , 6);
  149.                                                         if (crcData == (((uint16_t)MB_USART2.mscomm_buffer[6]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[7])
  150.                                                         {                                                               
  151.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  152.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  153.                                                                

  154.                                                         }
  155.                                                         else
  156.                                                         {
  157.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  158.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  159.                                                         }
  160.                                                 }
  161.                     }
  162.                     break;
  163.                                
  164.                                        
  165.                                 case MODBUS_HOSTS_FUNC_PresetSingleHoldingRegister:                                       
  166.                                           if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func)
  167.                                         {
  168.                                                 startAddr = (uint16_t)(MB_USART2.mscomm_buffer[2] << 8) + (uint16_t)MB_USART2.mscomm_buffer[3];
  169.                                                 if (MB_USART2.receCount == 8 && startAddr == USART2_MBHOSTS_Wait_Queue.StartAddr)
  170.                                                 {
  171.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , 6);
  172.                                                         if (crcData == (((uint16_t)MB_USART2.mscomm_buffer[6]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[7])
  173.                                                         {                                                               
  174.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  175.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  176.                                                                
  177.                                                                 #ifdef __DEBUG_stm32f407__
  178.                                                                         USART2_MODBUS_recv_count++;
  179.                                                                 #endif                                                                       
  180.                                                         }
  181.                                                         else
  182.                                                         {
  183.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  184.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  185.                                                         }
  186.                                                 }
  187.                     }
  188.                     break;

  189.                                
  190.                                 case MODBUS_HOSTS_FUNC_ForceMultipleCoil:
  191.                                           if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func)
  192.                                         {
  193.                                                 startAddr = (uint16_t)(MB_USART2.mscomm_buffer[2] << 8) + (uint16_t)MB_USART2.mscomm_buffer[3];
  194.                                                 registerAmount = (uint16_t)(MB_USART2.mscomm_buffer[4] << 8) + (uint16_t)MB_USART2.mscomm_buffer[5];                                               
  195.                                                 if (MB_USART2.receCount == 8 && startAddr == USART2_MBHOSTS_Wait_Queue.StartAddr && registerAmount == USART2_MBHOSTS_Wait_Queue.RegisterAmount)
  196.                                                 {
  197.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , 6);
  198.                                                         if (crcData == (((uint16_t)MB_USART2.mscomm_buffer[6]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[7])
  199.                                                         {                                                                                                                                       
  200.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  201.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  202.                                                                
  203.                                                                 #ifdef __DEBUG_stm32f407__
  204.                                                                         USART2_MODBUS_recv_count++;
  205.                                                                 #endif                                                                       
  206.                                                         }
  207.                                                         else
  208.                                                         {
  209.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  210.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  211.                                                         }
  212.                                                 }
  213.                     }                                       
  214.                                         break;
  215.                                
  216.                                        
  217.                                 case MODBUS_HOSTS_FUNC_PresetMultipleHoldingRegisters:
  218.                                           if (MB_USART2.mscomm_buffer[0] == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func)
  219.                                         {
  220.                                                 startAddr = (uint16_t)(MB_USART2.mscomm_buffer[2] << 8) + (uint16_t)MB_USART2.mscomm_buffer[3];
  221.                                                 registerAmount = (uint16_t)(MB_USART2.mscomm_buffer[4] << 8) + (uint16_t)MB_USART2.mscomm_buffer[5];                                               
  222.                                                 if (MB_USART2.receCount == 8 && startAddr == USART2_MBHOSTS_Wait_Queue.StartAddr && registerAmount == USART2_MBHOSTS_Wait_Queue.RegisterAmount)
  223.                                                 {
  224.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , 6);
  225.                                                         if (crcData == (((uint16_t)MB_USART2.mscomm_buffer[6]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[7])
  226.                                                         {                                                               
  227.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  228.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  229.                                                                
  230. #ifdef __DEBUG_stm32f407__
  231.                                                                         USART2_MODBUS_recv_count++;
  232.                                                                 #endif                                                                       
  233.                                                         }
  234.                                                         else
  235.                                                         {
  236.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  237.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  238.                                                         }
  239.                                                 }
  240.                     }                                       
  241.                                         break;
  242.                                
  243.                                
  244.                                 case 0x81:
  245.                                 case 0x82:
  246.                                 case 0x83:
  247.                                 case 0x84:
  248.                                 case 0x85:
  249.                                 case 0x8F:
  250.                                 case 0x90:                                       
  251.                                         if ((MB_USART2.mscomm_buffer[0] - 0x80) == USART2_MBHOSTS_Wait_Queue.DeviceAddr && MB_USART2.mscomm_buffer[1] == USART2_MBHOSTS_Wait_Queue.Func)
  252.                                         {
  253.                                                 if (MB_USART2.receCount == 5)
  254.                                                 {
  255.                                                         crcData = CRC16(MB_USART2.mscomm_buffer , 3);
  256.                                                         if (crcData == (((uint16_t)MB_USART2.mscomm_buffer[3]) << 8) + (uint16_t)MB_USART2.mscomm_buffer[4])
  257.                                                         {                                                               
  258.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  259.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_OVER;
  260.                                                         }
  261.                                                         else
  262.                                                         {
  263.                                                                 if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  264.                                                                         MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  265.                                                         }
  266.                                                 }
  267.                                         }
  268.                                         break;       

  269.                                 default:
  270.                                         if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  271.                                                 MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;
  272.                                         break;                               
  273.             }//switch (MB_USART2.mscomm_buffer[1])
  274.                        
  275.                         //USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//DMA通信,则删除
  276.                        
  277.         }//if (MB_USART2.receCount >= 5)
  278.                 else
  279.                 {
  280.                         if (MB_USART2.MBHosts_Query_isr == enum_MODBUS_STATUS_SEND_OVER)
  281.                                 MB_USART2.MBHosts_Query_isr = enum_MODBUS_STATUS_RECV_ERROR;               
  282.                 }

  283.                
  284.     }//if (MB_USART2.Outtime_mark)
  285. }
复制代码

程序

回复 支持 反对

使用道具 举报

发表于 2020-9-10 20:57:18 | 显示全部楼层
比较复杂呀!用了串口+DMA接收不定长报文,用了超时定时器T1,用了队列装载要发送的报文,用了状态机进行主站状态切换
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-12 10:30:18 | 显示全部楼层
ba_wang_mao 发表于 2020-9-10 20:57
比较复杂呀!用了串口+DMA接收不定长报文,用了超时定时器T1,用了队列装载要发送的报文,用了状态机进行主 ...

freemodbus 也是状态机不过你这么写优化起来就比freemodbus 简单了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 03:20 , Processed in 0.071005 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表