MODBUS RTU MASTER的C语言代码

转自:https://blog.csdn.net/chuanshaoke/article/details/7352602   [csharp] view plain copy    
  1. 这是我几年前写的一个关于MODBUS RTU MASTER的C语言代码,用于嵌入式控制器内。另一个触摸屏MCGS_E作为MODBUS RTU SLAVE。  
[csharp] view plain copy    
  1. 下面是相关代码,以前测试过,可以运行。由于目前的代码尚有很多地方值得改进,所以近期想把它改进重写。高手们有什么建议,请多多赐教。  
[csharp] view plain copy    
  1. 若您找到网络上有共享的MODBUS的源代码,请与我分享。非常感谢。  
[csharp] view plain copy    
  1. 下面没有main()函数,大家可以自己写个,把ListenToTouch函数放进去就可以了。  
[csharp] view plain copy    
  1. /*********************************************************************************/  
  2. /*函数名称: strmcpy()                            
  3. *输入参数:  共  个参数; 
  4. *输出参数:  共  个参数; 
  5. *返回值:    
  6. *需储存的参数: 共  个参数;     
  7. *功能介绍:   
  8.         (1)字符数组拷贝;               
  9. *修改日志: 
  10. *[2006-3-6 17:07]   Ver. 1.00 
  11.         开始编写; 
  12.         完成;                                      
  13. /*                                       */  
  14. /*********************************************************************************/  
  15.   
  16. void strmcpy(unsigned char dest[], unsigned char src[], int count)  
  17. {  
  18.     int i;  
  19.       
  20.     for(i = 0; i < count; i ++)  
  21.     {  
  22.         dest[i] = src[i];  
  23.     }  
  24.     dest[i] = '/0';  
  25. }  
  26.   
  27. /*****************************************************************************/  
  28.   
  29.   
  30. /*********************************************************************************/  
  31. /*函数名称: bitmcpy()                            
  32. *输入参数:  共  个参数; 
  33. *输出参数:  共  个参数; 
  34. *返回值:    
  35. *需储存的参数: 共  个参数;     
  36. *功能介绍:   
  37.         (1)开关量数组拷贝;              
  38. *修改日志: 
  39. *[2006-3-7 14:59]   Ver. 1.00 
  40.         开始编写; 
  41.         完成;                                      
  42. /*                                       */  
  43. /*********************************************************************************/  
  44.   
  45. void bitmcpy(int dest[], int src[], int count)  
  46. {  
  47.     int i;  
  48.       
  49.     for(i = 0; i < count; i ++)  
  50.     {  
  51.         dest[i] = src[i];  
  52.     }  
  53. }  
  54.   
  55. /*****************************************************************************/  
  56.   
  57.   
  58. /*********************************************************************************/  
  59. /*函数名称: strmcmp()                            
  60. *输入参数:  共  个参数; 
  61. *输出参数:  共  个参数; 
  62. *返回值:    
  63. *需储存的参数: 共  个参数;     
  64. *功能介绍:   
  65.         (1)字符数组比较;相同则返回0,不相同则返回1;                
  66. *修改日志: 
  67. *[2006-3-6 17:41]   Ver. 1.00 
  68.         开始编写; 
  69.         完成;                                      
  70. /*                                       */  
  71. /*********************************************************************************/  
  72.   
  73. int strmcmp(unsigned char str1[], unsigned char str2[], int count)  
  74. {  
  75.     int i;  
  76.       
  77.     for(i = 0; i < count; i ++)  
  78.     {  
  79.         if(str1[i] != str2[i])  
  80.         {  
  81.             return 1;         
  82.         }  
  83.     }  
  84.     return 0;  
  85. }  
  86.   
  87. /*****************************************************************************/  
  88.   
  89.   
  90. /*********************************************************************************/  
  91. /*函数名称: Datamcmp()                           
  92. *输入参数:  共  个参数; 
  93. *输出参数:  共  个参数; 
  94. *返回值:    
  95. *需储存的参数: 共  个参数;     
  96. *功能介绍:   
  97.         (1)浮点数组比较;相同则返回0,不相同则返回1;                
  98. *修改日志: 
  99. *[2006-3-6 18:05]   Ver. 1.00 
  100.         开始编写; 
  101.         完成;      
  102. *[2006-3-9 13:52] 
  103.         加了一层括号,以前是错误的 
  104.         if(!((data1[i] - data2[i] < 0.0001) && (data1[i] - data2[i] > -0.0001)))                                       
  105. /*                                       */  
  106. /*********************************************************************************/  
  107.   
  108. int Datamcmp(float data1[], float data2[], int count)  
  109. {  
  110.     int i;  
  111.       
  112.     for(i = 0; i < count; i ++)  
  113.     {  
  114.         if(!((data1[i] - data2[i] < 0.0001) && (data1[i] - data2[i] > -0.0001)))  
  115.         {  
  116.             return 1;         
  117.         }  
  118.     }  
  119.     return 0;  
  120. }  
  121.   
  122. /*****************************************************************************/  
  123.   
  124.   
  125. /*********************************************************************************/  
  126. /*函数名称: Bitmcmp()                            
  127. *输入参数:  共  个参数; 
  128. *输出参数:  共  个参数; 
  129. *返回值:    
  130. *需储存的参数: 共  个参数;     
  131. *功能介绍:   
  132.         (1)开关量数组比较;相同则返回0,不相同则返回1;               
  133. *修改日志: 
  134. *[2006-3-6 18:10]   Ver. 1.00 
  135.         开始编写; 
  136.         完成;                                      
  137. /*                                       */  
  138. /*********************************************************************************/  
  139.   
  140. int Bitmcmp(int data1[], int data2[], int count)   
  141. {   
  142.     int i;  
  143.       
  144.     for(i = 0; i < count; i ++)  
  145.     {  
  146.         if(data1[i] != data2[i])  
  147.         {  
  148.             return 1;         
  149.         }  
  150.     }  
  151.     return 0;  
  152. }  
  153.   
  154. /*****************************************************************************/  
  155.   
  156.   
  157. /*********************************************************************************/  
  158. /*函数名称: GetCRC16()                           
  159. *输入参数:  共  个参数; 
  160. *输出参数:  共  个参数; 
  161. *返回值:    
  162. *需储存的参数: 共  个参数;     
  163. *功能介绍:   
  164.         (1)CRC16校验; 返回校验码;               
  165. *修改日志: 
  166. *[2005-11-28 16:40]     Ver. 1.00 
  167.         开始编写; 
  168.         完成;                                      
  169. /*                                       */  
  170. /*********************************************************************************/  
  171.   
  172. unsigned short GetCRC16(unsigned char *puchMsg, unsigned short usDataLen)   
  173. {   
  174.     /* CRC 高位字节值表 */   
  175.     unsigned char auchCRCHi[256] = {  
  176.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
  177.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
  178.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
  179.     0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,   
  180.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
  181.     0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,   
  182.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
  183.     0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
  184.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
  185.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,   
  186.     0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
  187.     0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,   
  188.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
  189.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,   
  190.     0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
  191.     0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,   
  192.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
  193.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
  194.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
  195.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
  196.     0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
  197.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,   
  198.     0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
  199.     0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
  200.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
  201.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40  
  202.     };   
  203.       
  204.     unsigned char auchCRCLo[256] = {  
  205.     0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,   
  206.     0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,   
  207.     0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,   
  208.     0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,   
  209.     0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,   
  210.     0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,   
  211.     0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,   
  212.     0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,   
  213.     0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,   
  214.     0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,   
  215.     0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,   
  216.     0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,   
  217.     0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,   
  218.     0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,   
  219.     0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,   
  220.     0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,   
  221.     0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,   
  222.     0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,   
  223.     0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,   
  224.     0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,   
  225.     0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,   
  226.     0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,   
  227.     0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,   
  228.     0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,   
  229.     0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,   
  230.     0x43, 0x83, 0x41, 0x81, 0x80, 0x40  
  231.     };  
  232.       
  233.     unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */   
  234.     unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */   
  235.     unsigned uIndex = 0; /* CRC循环中的索引 */   
  236.       
  237.     while (usDataLen--) /* 传输消息缓冲区 */   
  238.     {   
  239.         uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */   
  240.         uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;   
  241.         uchCRCLo = auchCRCLo[uIndex] ;   
  242.     }   
  243.     return (unsigned short)((unsigned short)uchCRCHi << 8 | uchCRCLo) ;   
  244. }   
  245. /*****************************************************************************/  
  246.   
  247.   
  248. /*********************************************************************************/  
  249. /*函数名称: SendRtuCmdToModBus()                             
  250. *输入参数:  共  个参数; 
  251. *输出参数:  共  个参数; 
  252. *返回值:   无 
  253. *需储存的参数: 共  个参数;     
  254. *功能介绍:   
  255.         (1)发送ModBus RTU 指令到 Modbus Slave,加上CRC16校验码;                 
  256. *修改日志: 
  257. *[2005-11-28 16:40]     Ver. 1.00 
  258.         开始编写; 
  259.         完成;  
  260. *[2006-3-1 9:02] 
  261.         返回类型改为void;                                      
  262. /*                                       */  
  263. /*********************************************************************************/  
  264.   
  265. void SendRtuCmdToModBus(int ModPort, unsigned char cmd[], unsigned short len)  
  266. {   
  267.     unsigned short CRC16;  
  268.       
  269.     CRC16=GetCRC16(cmd,len);  
  270.     ToComBufn(ModPort,cmd,len);  
  271.     ToCom(ModPort, (unsigned char)(CRC16 >> 8 & 0x00FF));     /* send CRC16 high */  
  272.     ToCom(ModPort, (unsigned char)(CRC16 & 0x00FF));    /* send CRC16 low */      
  273. }  
  274. /*****************************************************************************/  
  275.   
  276.   
  277. /*********************************************************************************/  
  278. /*函数名称: ReadModBusRtuSlave()                             
  279. *输入参数:  共 8 个参数; 
  280. *输出参数:  共 5 个参数; 
  281. *返回值:   成功与否    1:成功, 2:失败; 
  282. *需储存的参数: 共 0 个参数;    
  283. *功能介绍:   
  284.         (1)读取ModBusRtuSlave,并解码输出反馈字符串相关内容;  
  285.         ReadModBusRtuSlave(COMPORT1, ModAddr, ModFunction, ModByteNum,  
  286.             ModData, &ModDataLen, ModTimeout=10, waitTime=30)        
  287. *修改日志: 
  288. *[2005-11-28 16:40]     Ver. 1.00 
  289.         开始编写; 
  290.         完成;  
  291. *[2006-3-1 9:23] 
  292.         增加了int counter = 0; 
  293.         unsigned char ModBusMessage[MOD_STR_MAX_LEN];    
  294. *[2006-3-1 13:46]        
  295.         增加了 strmcpy(ModData, ModBusMessage + 3, ModBusIdx - 5);                                  
  296. /*                                       */  
  297. /*********************************************************************************/  
  298.   
  299. int ReadModBusRtuSlave(int ModPort, unsigned char *ModAddr, unsigned char *ModFunction, unsigned char *ModByteNum,   
  300.     unsigned char ModData[], unsigned char *ModDataLen, unsigned ModTimeout, unsigned waitTime)  
  301. {     
  302.     unsigned char data;  
  303.     unsigned long t;  
  304.     int i;  
  305.     unsigned short CRC16;  
  306.     int ModBusIdx = 0;  
  307.     int counter = 0;  
  308.     unsigned char ModBusMessage[MOD_STR_MAX_LEN] = {'/0'};  
  309.       
  310.     while((!(IsCom(ModPort)) && (counter < waitTime)))  
  311.     {  
  312.         DelayMs(1);  
  313.         counter ++;  
  314.     }  
  315.       
  316.     StopWatchStart(MODBUS_STOP_WATCH);  
  317.     do  
  318.     {  
  319.         while(IsCom(ModPort) && (ModBusIdx < MOD_STR_MAX_LEN - 1))  
  320.         {  
  321.                 data = ReadCom(ModPort);  
  322.                 ModBusMessage[ModBusIdx ++]=data;  
  323.                 StopWatchStart(MODBUS_STOP_WATCH);  
  324.             /*     Print("[%02X]",data); */  
  325.         }  
  326.         StopWatchReadValue(MODBUS_STOP_WATCH, &t);  
  327.     }  
  328.         while(t <= ModTimeout);  
  329.               
  330.     if (ModBusIdx == 0) return 0;  
  331.     ModBusMessage[ModBusIdx] = '/0';  
  332.     StopWatchStop(MODBUS_STOP_WATCH);  
  333.               
  334.       
  335.     CRC16 = GetCRC16(ModBusMessage,ModBusIdx - 2);  
  336.     /* for(i=0; i> 8 & 0x00FF) == ModBusMessage[ModBusIdx - 2] && (unsigned char)(CRC16 & 0x00FF) == ModBusMessage[ModBusIdx - 1]) 
  337.     { 
  338.         *ModAddr = ModBusMessage[0]; 
  339.         *ModFunction = ModBusMessage[1]; 
  340.         *ModByteNum = ModBusMessage[2]; 
  341.          
  342.         strmcpy(ModData, ModBusMessage + 3, ModBusIdx - 5);  
  343.     /*  Print(" idx%d  ", ModBusIdx - 5);   /*test*/  
  344.         /*  for(i = 3; i < ModBusIdx - 2; i++) 
  345.         { 
  346.             ModData[i - 3] = ModBusMessage[i]; 
  347.         } 
  348.         ModData[i] = '/0';   
  349.         */  
  350.         *ModDataLen = ModBusIdx - 5;  
  351.         /*  Print("{DataLen=%d}/n/r", *ModDataLen); */  
  352.         return 1;  
  353.     }  
  354.     else   
  355.     {  
  356.         *ModDataLen = 0;  
  357.         return 0;  
  358.         /* CRC16 error */  
  359.     /*  Print("{CRC16 Error}/n/r"); */  
  360.     }      
  361. }  
  362.   
  363. /*-------------------------------------------------------------------------------*/  
  364.   
  365.   
  366. /*********************************************************************************/  
  367. /*函数名称: ResponseFromModBusRtuSlave()                             
  368. *输入参数:  共 8 个参数; 
  369. *输出参数:  共 5 个参数; 
  370. *返回值:   成功与否    1:成功, 2:失败; 
  371. *需储存的参数: 共 0 个参数;    
  372. *功能介绍:   
  373.         (1)写参数到ModBusRtuSlave后,ModbusRtuSlave反馈字符串; 
  374.                  
  375. *修改日志: 
  376. *[2006-3-1 12:34]   Ver. 1.00 
  377.         开始编写; 
  378. *[2006-3-1 12:48]        
  379.         完成;  
  380. *[2006-3-6 16:32] 
  381.         strcpy(totalStr, ModBusMessage); 
  382.         改为 strmcpy(totalStr, ModBusMessage, ModBusIdx);                                      
  383. /*                                       */  
  384. /*********************************************************************************/  
  385.   
  386. int ResponseFromModBusRtuSlave(int ModPort, unsigned char totalStr[],   
  387.     unsigned char *ModAddr, unsigned char *ModFunction, unsigned short *ModDataAddr,   
  388.     unsigned short *ModDataNum, unsigned ModTimeout, unsigned waitTime)  
  389. {         
  390.     unsigned char data;  
  391.     unsigned long t;      
  392.     unsigned short CRC16;     
  393.     int ModBusIdx = 0;  
  394.     int counter = 0;  
  395.     unsigned char ModBusMessage[MOD_STR_MAX_LEN] = {'/0'};  
  396.       
  397.     while((!(IsCom(ModPort)) && (counter < waitTime)))  
  398.     {  
  399.         DelayMs(1);  
  400.         counter ++;  
  401.     }  
  402.       
  403.     StopWatchStart(MODBUS_STOP_WATCH);  
  404.     do  
  405.     {  
  406.         while(IsCom(ModPort) && (ModBusIdx < MOD_STR_MAX_LEN - 1))  
  407.         {  
  408.                 data = ReadCom(ModPort);  
  409.                 ModBusMessage[ModBusIdx ++]=data;  
  410.                 StopWatchStart(MODBUS_STOP_WATCH);  
  411.             /*     Print("[%02X]",data); */  
  412.         }  
  413.         StopWatchReadValue(MODBUS_STOP_WATCH, &t);  
  414.     }  
  415.         while(t <= ModTimeout);  
  416.               
  417.     if (ModBusIdx == 0) return 0;  
  418.     ModBusMessage[ModBusIdx] = '/0';  
  419.     strmcpy(totalStr, ModBusMessage, ModBusIdx);  
  420.     StopWatchStop(MODBUS_STOP_WATCH);  
  421.               
  422.       
  423.     CRC16 = GetCRC16(ModBusMessage,ModBusIdx - 2);  
  424.       
  425.     if((unsigned char)(CRC16 >> 8 & 0x00FF) == ModBusMessage[ModBusIdx - 2] && (unsigned char)(CRC16 & 0x00FF) == ModBusMessage[ModBusIdx - 1])  
  426.     {  
  427.         *ModAddr = ModBusMessage[0];  
  428.         *ModFunction = ModBusMessage[1];  
  429.           
  430.         *ModDataAddr = (unsigned short)((unsigned short)ModBusMessage[2] << 8 | ModBusMessage[3]);  
  431.         *ModDataNum  = (unsigned short)((unsigned short)ModBusMessage[4] << 8 | ModBusMessage[5]);  
  432.                       
  433.         return 1;  
  434.     }  
  435.     else   
  436.     {  
  437.         return 0;  
  438.         /* CRC16 error */  
  439.     /*  Print("{CRC16 Error}/n/r"); */  
  440.     }      
  441. }  
  442.   
  443. /*-------------------------------------------------------------------------------*/  
  444.   
  445.   
  446. /*********************************************************************************/  
  447. /*函数名称: ResponseSingleBitFromModBus()                            
  448. *输入参数:  共 8 个参数; 
  449. *输出参数:  共 5 个参数; 
  450. *返回值:   成功与否    1:成功, 2:失败; 
  451. *需储存的参数: 共 0 个参数;    
  452. *功能介绍:   
  453.         (1)写参数到ModBusRtuSlave后,ModbusRtuSlave反馈字符串; 
  454.                  
  455. *修改日志: 
  456. *[2006-3-7 14:40]   Ver. 1.00 
  457.         开始编写; 
  458. *[2006-3-7 14:40]        
  459.         完成;                                          
  460. /*                                       */  
  461. /*********************************************************************************/  
  462.   
  463. int ResponseSingleBitFromModBus(int ModPort, unsigned char totalStr[],   
  464.     unsigned char *ModAddr, unsigned char *ModFunction, unsigned short *ModDataAddr,   
  465.     unsigned short *ModDataState, unsigned ModTimeout, unsigned waitTime)  
  466. {         
  467.     unsigned char data;  
  468.     unsigned long t;      
  469.     unsigned short CRC16;     
  470.     int ModBusIdx = 0;  
  471.     int counter = 0;  
  472.     unsigned char ModBusMessage[MOD_STR_MAX_LEN] = {'/0'};  
  473.       
  474.     while((!(IsCom(ModPort)) && (counter < waitTime)))  
  475.     {  
  476.         DelayMs(1);  
  477.         counter ++;  
  478.     }  
  479.       
  480.     StopWatchStart(MODBUS_STOP_WATCH);  
  481.     do  
  482.     {  
  483.         while(IsCom(ModPort) && (ModBusIdx < MOD_STR_MAX_LEN - 1))  
  484.         {  
  485.                 data = ReadCom(ModPort);  
  486.                 ModBusMessage[ModBusIdx ++]=data;  
  487.                 StopWatchStart(MODBUS_STOP_WATCH);  
  488.             /*     Print("[%02X]",data); */  
  489.         }  
  490.         StopWatchReadValue(MODBUS_STOP_WATCH, &t);  
  491.     }  
  492.         while(t <= ModTimeout);  
  493.               
  494.     if (ModBusIdx == 0) return 0;  
  495.     ModBusMessage[ModBusIdx] = '/0';  
  496.     strmcpy(totalStr, ModBusMessage, ModBusIdx);  
  497.     StopWatchStop(MODBUS_STOP_WATCH);  
  498.               
  499.       
  500.     CRC16 = GetCRC16(ModBusMessage,ModBusIdx - 2);  
  501.       
  502.     if((unsigned char)(CRC16 >> 8 & 0x00FF) == ModBusMessage[ModBusIdx - 2] && (unsigned char)(CRC16 & 0x00FF) == ModBusMessage[ModBusIdx - 1])  
  503.     {  
  504.         *ModAddr = ModBusMessage[0];  
  505.         *ModFunction = ModBusMessage[1];  
  506.           
  507.         *ModDataAddr = (unsigned short)((unsigned short)ModBusMessage[2] << 8 | ModBusMessage[3]);  
  508.         if(ModBusMessage[4])   *ModDataState  = 1;  
  509.         else   *ModDataState  = 0;  
  510.                       
  511.         return 1;  
  512.     }  
  513.     else   
  514.     {  
  515.         return 0;  
  516.         /* CRC16 error */  
  517.     /*  Print("{CRC16 Error}/n/r"); */  
  518.     }      
  519. }  
  520.   
  521. /*-------------------------------------------------------------------------------*/  
  522.   
  523.   
  524. /*********************************************************************************/  
  525. /*函数名称: ChangeAllParameterDataByModBus()                             
  526. *输入参数:  共  个参数; 
  527. *输出参数:  共  个参数; 
  528. *返回值:   无 
  529. *需储存的参数: 共  个参数;     
  530. *功能介绍:   
  531.         (1) 将MODBUSSLAVE返回的数据字符转化为参数值; 
  532.         (2) void *memcpy(void *dest, const void *src, size_t n)  
  533.         (3) 四个字符的顺序应倒一下。             
  534. *修改日志: 
  535. *[2006-3-1 14:10]   Ver. 1.00 
  536.         开始编写; 
  537. *[2006-3-1 14:35] 
  538.         完成;  
  539. *[2006-3-6 15:57] 
  540.         四个字符的顺序应倒一下。                                                     
  541. /*                                       */  
  542. /*********************************************************************************/  
  543.   
  544. void ChangeAllParameterDataByModBus(float parameterData[], unsigned char ModDataBack[], unsigned short num)  
  545. {  
  546.     int i;  
  547.     char singleStr[5] = {'/0','/0','/0','/0','/0'};   
  548.     float *pf;  
  549.         float dataf = 0;         
  550.         int len = 4;      
  551.           
  552.         pf = &dataf;  
  553.               
  554.     for(i = 0; i < num; i ++)  
  555.     {  
  556.         singleStr[0] = ModDataBack[i * 4 + 3];  
  557.         singleStr[1] = ModDataBack[i * 4 + 2];  
  558.         singleStr[2] = ModDataBack[i * 4 + 1];  
  559.         singleStr[3] = ModDataBack[i * 4 ];  
  560.         singleStr[4] = '/0';  
  561.         memcpy(pf, singleStr, len);  
  562.         parameterData[i] = *pf;  
  563.     /*  Print("%-6.2f/t", parameterData[i]);    /*test*/  
  564.     }  
  565. }  
  566.   
  567. /*-------------------------------------------------------------------------------*/  
  568.   
  569.   
  570. /*********************************************************************************/  
  571. /*函数名称: ChangeAllButtonsDataByModBus()                           
  572. *输入参数:  共  个参数; 
  573. *输出参数:  共  个参数; 
  574. *返回值:   无 
  575. *需储存的参数: 共  个参数;     
  576. *功能介绍:   
  577.         (1) 将MODBUSSLAVE返回的数据字符转化为按钮值;               
  578. *修改日志: 
  579. *[2006-3-1 14:03]   Ver. 1.00 
  580.         开始编写;    
  581. *[2006-3-1 14:10] 
  582.         完成;                                          
  583. /*                                       */  
  584. /*********************************************************************************/  
  585.   
  586. void ChangeAllButtonsDataByModBus(int buttonData[], unsigned char ModDataBack[], unsigned short num)  
  587. {  
  588.     unsigned char button8Data = 0;  
  589.     int i, j;  
  590.           
  591.     for(j = 0; j < (int)(num / 8); j ++)   
  592.     {  
  593.         button8Data = ModDataBack[j];  
  594.         for(i = 0; i < 8; i ++)  
  595.         {  
  596.             buttonData[i + j * 8] = (int)(button8Data & (int) pow(2, i)) / (int) pow(2, i);  
  597.         }  
  598.     }  
  599.     button8Data = ModDataBack[j];  
  600.     for(i = 0; i < num % 8; i ++)  
  601.     {  
  602.         buttonData[i + j * 8] = (int)(button8Data & (int) pow(2, i)) / (int) pow(2, i);  
  603.     }     
  604. }  
  605.   
  606. /*-------------------------------------------------------------------------------*/  
  607.   
  608.   
  609. /*********************************************************************************/  
  610. /*函数名称: WordDataToModbusStr()                            
  611. *输入参数:  共  个参数; 
  612. *输出参数:  共  个参数; 
  613. *返回值:   无 
  614. *需储存的参数: 共  个参数;     
  615. *功能介绍:   
  616.         (1)parameterData 或AIData转化为MODBUSSLAVE的WORD值的STR;  
  617.         (2) void *memcpy(void *dest, const void *src, size_t n)  
  618.         (3) 四个字符的顺序应倒一下。                 
  619. *修改日志: 
  620. *[2006-3-1 14:37]   Ver. 1.00 
  621.         开始编写; 
  622. *[2006-3-1 14:49]        
  623.         完成;  
  624. *[2006-3-6 15:57] 
  625.         四个字符的顺序应倒一下。                                     
  626. /*                                       */  
  627. /*********************************************************************************/  
  628.   
  629. void WordDataToModbusStr(unsigned char writeCmdStr[], float data[], unsigned short num, unsigned short startAddr)  
  630. {  
  631.     int i;  
  632.     char singleStr[5] = {'/0','/0','/0','/0','/0'};   
  633.     float *pf;  
  634.     unsigned char *pstr;  
  635.         float dataf = 0;         
  636.         int len = 4;      
  637.           
  638.         pf = &dataf;  
  639.         pstr = singleStr;  
  640.               
  641.     for(i = 0; i < num; i ++)  
  642.     {  
  643.         *pf = data[i];  
  644.         memcpy(pstr, pf, len);  
  645.         writeCmdStr[startAddr + i * 4 + 3] = singleStr[0];  
  646.         writeCmdStr[startAddr + i * 4 + 2] = singleStr[1];  
  647.         writeCmdStr[startAddr + i * 4 + 1] = singleStr[2];  
  648.         writeCmdStr[startAddr + i * 4 ] = singleStr[3];       
  649.     }     
  650. }  
  651.   
  652. /*-------------------------------------------------------------------------------*/  
  653.   
  654.   
  655. /*********************************************************************************/  
  656. /*函数名称: BitDataToModbusStr()                             
  657. *输入参数:  共  个参数; 
  658. *输出参数:  共  个参数; 
  659. *返回值:   无 
  660. *需储存的参数: 共  个参数;     
  661. *功能介绍:   
  662.         (1)data转化为MODBUSSLAVE的WORD值的STR;                 
  663. *修改日志: 
  664. *[2006-3-1 14:51]   Ver. 1.00 
  665.         开始编写;    
  666. *[2006-3-1 15:02] 
  667.         完成;                                      
  668. /*                                       */  
  669. /*********************************************************************************/  
  670.   
  671. void BitDataToModbusStr(unsigned char writeCmdStr[], int data[], unsigned short num, unsigned short startAddr)  
  672. {  
  673.     int i, j;     
  674.     unsigned char button8Data = 0;  
  675.           
  676.     for(j = 0; j < (int)(num / 8); j ++)   
  677.     {  
  678.         button8Data = 0;  
  679.         for(i = 0; i < 8; i ++)  
  680.         {  
  681.             button8Data += data[i + j * 8] * (int) pow(2, i);  
  682.         }  
  683.         writeCmdStr[startAddr + j] = button8Data;  
  684.     }  
  685.       
  686.     if(num % 8)  
  687.     {  
  688.         button8Data = 0;  
  689.         for(i = 0; i < num % 8; i ++)  
  690.         {  
  691.             button8Data += data[i + j * 8] * (int) pow(2, i);  
  692.         }  
  693.         writeCmdStr[startAddr + j] = button8Data;  
  694.     }  
  695. }  
  696.   
  697. /*-------------------------------------------------------------------------------*/  
  698.   
  699.   
  700. /*********************************************************************************/  
  701. /*函数名称: ReadWordFromModBusSlave()                            
  702. *输入参数:  共 2 个参数; 
  703. *输出参数:  共 1 个参数; 
  704. *返回值:   成功与否; 
  705. *需储存的参数: 共 1 个参数;    
  706. *功能介绍:   
  707.         (1) 从触摸屏中读取设定参数值; 
  708.         (2) 读取指令为 01 03 HA LA HN LN HC LC;其中 01 为MODBUSSLAVE的地址, 
  709.             03 为读连续多个WORD寄存器的功能码,HA LA 为第一个寄存器的高低位地址, 
  710.             HN LN 为寄存器数量的高低位,HC LC 为CRC校验码; 
  711.         (3) 触摸屏reset后各个参数归零,7188检测到此状态后向除摸屏发送设定参数; 
  712. *修改日志: 
  713. *[2005-11-28 16:51]     Ver. 1.00 
  714.         开始编写; 
  715. *[2005-11-28 18:10]      
  716.         完成初稿,未测试; 
  717. *[2006-3-3 9:38] 
  718.         static unsigned char oldModDataBack[400];改为形参; 
  719. *[2006-3-3 17:58] 
  720.         增加int kind形参;    
  721. *[2006-3-6 16:34]        
  722.         strmcpy(oldModDataBack, ModDataBack, ModDataLenBack);    
  723. *[2006-3-9 12:33] 
  724.         去掉       
  725.         (strmcmp(oldModDataBack, ModDataBack, ModDataLenBack))                                   
  726. /*                                       */  
  727. /*********************************************************************************/  
  728.   
  729. int ReadWordFromModBusSlave(int kind, int comPort, float parameterData[], unsigned short num,   
  730.     unsigned short ModDataAddr, int parameterEEPROMAddr, unsigned char oldModDataBack[])  
  731. {             
  732.     float parameterJudge[50];     
  733.       
  734.     unsigned char readCmdStr[15];  
  735.     unsigned char ModAddr = 1;  
  736.     unsigned char ModFunction = 3;  
  737.     unsigned short ModDataNum;        
  738.     unsigned short readCmdLen = 6;  
  739.     int isReadOK = 0;     
  740.       
  741.     unsigned char ModAddrBack = 0;  
  742.     unsigned char ModFunctionBack = 0;  
  743.     unsigned char ModByteNumBack = 0;  
  744.     unsigned char ModDataBack[MOD_STR_MAX_LEN] = {'/0'};  
  745.   
  746.     unsigned char ModDataLenBack = 0;  
  747.       
  748. /*  unsigned short ModWord[100];    */  
  749.       
  750.     int parameterDecimalEEPROM[PARAMETER_DATA_NUM] = PARAMETER_DECIMAL_EEPROM;  /* adjust */  
  751.     int parameterStartAddr = 0;  
  752.     char i7188Addr[5];  
  753.     strcpy(i7188Addr, I7188_ADDRESS);       /* adjust */  
  754.       
  755.     if(kind == 1)  
  756.     {  
  757.         strcpy(i7188Addr, I7188_ADDRESS);  
  758.     }  
  759.     else if(kind == 2)  
  760.     {  
  761.         strcpy(i7188Addr, I7188_ADDRESS_2);  
  762.     }  
  763.     else if(kind == 3)  
  764.     {  
  765.         strcpy(i7188Addr, I7188_ADDRESS_3);  
  766.     }  
  767.           
  768.     ModDataNum = (unsigned short)num * 2;  
  769.           
  770.     readCmdStr[0] = ModAddr;  
  771.     readCmdStr[1] = ModFunction;   
  772.     readCmdStr[2] = (unsigned char)(ModDataAddr >> 8 & 0x00FF);  
  773.     readCmdStr[3] = (unsigned char)(ModDataAddr & 0x00FF);  
  774.     readCmdStr[4] = (unsigned char)(ModDataNum >> 8 & 0x00FF);  
  775.     readCmdStr[5] = (unsigned char)(ModDataNum & 0x00FF);     
  776.     readCmdStr[6] = '/0';  
  777.       
  778.     ClearCom(comPort);  
  779.     SendRtuCmdToModBus(comPort, readCmdStr, readCmdLen);  
  780.           
  781.     isReadOK = ReadModBusRtuSlave(comPort, &ModAddrBack, &ModFunctionBack, &ModByteNumBack,   
  782.         ModDataBack, &ModDataLenBack, MOD_TIMEOUT, MOD_WAITTIME);  
  783.       
  784.     if (1 == isReadOK)  
  785.     {     
  786.         if((ModAddr == ModAddrBack) && (ModFunction == ModFunctionBack) && (ModByteNumBack == ModDataLenBack))   
  787.         {  
  788.             if (ModDataNum * 2 == ModDataLenBack)       /*!!!*/  
  789.             {                     
  790.                 ChangeAllParameterDataByModBus(parameterJudge, ModDataBack, num);     
  791.             /*  Print(" %f  %f  %f /t", parameterData[0], parameterData[1],parameterData[2]);    
  792.                 Print("/n%f  %f  %f /t", parameterJudge[0], parameterJudge[1],parameterJudge[2]);    
  793.             */  if(parameterJudge[0] >= 0.1)     /* 以温度设定值为判断点判断正确性 */  
  794.                 {  
  795.                 /*  Print(" cp1.5 /n"); */  
  796.                       
  797.                     if(Datamcmp(parameterData, parameterJudge, num))  
  798.                     {  
  799.                         Print(" cp1.6 /n");  
  800.                         ChangeAllParameterDataByModBus(parameterData, ModDataBack, num);      
  801.                       
  802.                         if(IS_RS485)  Set485DirToTransmit(COMPORT1);  
  803.                         SendParameterDataToPCForwardly(COMPORT1, parameterData, i7188Addr);  
  804.                         if(IS_RS485)  WaitTransmitOver(COMPORT1);  
  805.                         if(IS_RS485)  {DelayMs(2); Set485DirToReceive(COMPORT1);}  
  806.                       
  807.                         WriteDataToEEPROM(parameterData, parameterDecimalEEPROM, num, parameterEEPROMAddr, parameterStartAddr);  
  808.                     }  
  809.                       
  810.                     strmcpy(oldModDataBack, ModDataBack, ModDataLenBack);  
  811.                 }  
  812.                 else  
  813.                 {  
  814.                     /*未初始化,发送数据以初始*/                      
  815.                     WriteMultipleWordToModBusSlave(comPort, parameterData, num, ModDataAddr);  
  816.                 }  
  817.             /*  Print("/n %f  %f  %f /t", parameterData[0], parameterData[1],parameterData[2]); */  
  818.             }  
  819.             return 1;  
  820.         }  
  821.         else  
  822.         {  
  823.             /*收到的字符串不匹配*/  
  824.             return 0;  
  825.         }  
  826.     }  
  827.     else  
  828.     {  
  829.         /*未收到字符串或CRC校验出错*/  
  830.         return 0;  
  831.     }  
  832. }  
  833.   
  834. /*-------------------------------------------------------------------------------*/  
  835.   
  836.   
  837. /*********************************************************************************/  
  838. /*函数名称: ReadBitFromModBusSlave()                             
  839. *输入参数:  共 2 个参数; 
  840. *输出参数:  共 1 个参数; 
  841. *返回值:   成功与否; 
  842. *需储存的参数: 共 1 个参数;    
  843. *功能介绍:   
  844.         (1) 从触摸屏中读取按钮值; 
  845.         (2) 读取指令为 01 01 HA LA HN LN HC LC;其中 01 为MODBUSSLAVE的地址, 
  846.             01 为读连续多个BIT线圈的功能码,HA LA 为第一个BIT的高低位地址, 
  847.             HN LN 为BIT数量的高低位,HC LC 为CRC校验码; 
  848. *修改日志: 
  849. *[2005-11-28 18:10]     Ver. 1.00 
  850.         开始编写; 
  851. *[2005-11-28 18:42]      
  852.         完成初稿,未测试; 
  853. *[2006-3-3 9:38] 
  854.         static unsigned char oldModDataBack[400];改为形参; 
  855. *[2006-3-3 17:58] 
  856.         增加int kind形参; 
  857. *[2006-3-6 16:35] 
  858.         strmcpy(oldModDataBack, ModDataBack, ModDataLenBack);    
  859. *[2006-3-9 12:35] 
  860.         去掉  (strmcmp(oldModDataBack, ModDataBack, ModDataLenBack))                                                   
  861. /*                                       */  
  862. /*********************************************************************************/  
  863.   
  864. int ReadBitFromModBusSlave(int kind, int comPort, int buttonData[], unsigned short num,   
  865.     unsigned short ModDataAddr, int buttonNVRAMAddr, unsigned char oldModDataBack[])  
  866. {     
  867.     int buttonJudge[30];  
  868.     unsigned char readCmdStr[15];  
  869.     unsigned char ModAddr = 1;  
  870.     unsigned char ModFunction = 1;    
  871.     unsigned short ModDataNum;    
  872.     unsigned short readCmdLen = 6;  
  873.     int isReadOK = 0;     
  874.       
  875.     unsigned char ModAddrBack = 0;  
  876.     unsigned char ModFunctionBack = 0;  
  877.     unsigned char ModByteNumBack = 0;  
  878.     unsigned char ModDataBack[300] = {'/0'};  
  879.   
  880.     unsigned char ModDataLenBack = 0;  
  881.       
  882. /*  unsigned short ModBit[100]; */  
  883.     char i7188Addr[5];  
  884.     strcpy(i7188Addr, I7188_ADDRESS);       /* adjust */  
  885.       
  886.     if(kind == 1)  
  887.     {  
  888.         strcpy(i7188Addr, I7188_ADDRESS);  
  889.     }  
  890.     else if(kind == 2)  
  891.     {  
  892.         strcpy(i7188Addr, I7188_ADDRESS_2);  
  893.     }  
  894.     else if(kind == 3)  
  895.     {  
  896.         strcpy(i7188Addr, I7188_ADDRESS_3);  
  897.     }  
  898.       
  899.     ModDataNum = (unsigned short)num;  
  900.       
  901.     readCmdStr[0] = ModAddr;  
  902.     readCmdStr[1] = ModFunction;   
  903.     readCmdStr[2] = (unsigned char)(ModDataAddr >> 8 & 0x00FF);  
  904.     readCmdStr[3] = (unsigned char)(ModDataAddr & 0x00FF);  
  905.     readCmdStr[4] = (unsigned char)(ModDataNum >> 8 & 0x00FF);  
  906.     readCmdStr[5] = (unsigned char)(ModDataNum & 0x00FF);     
  907.     readCmdStr[6] = '/0';  
  908.       
  909.     ClearCom(comPort);  
  910.     SendRtuCmdToModBus(comPort, readCmdStr, readCmdLen);  
  911.           
  912.     isReadOK = ReadModBusRtuSlave(comPort, &ModAddrBack, &ModFunctionBack, &ModByteNumBack,   
  913.         ModDataBack, &ModDataLenBack, MOD_TIMEOUT, MOD_WAITTIME);  
  914.       
  915.     if (1 == isReadOK)  
  916.     {         
  917.         if((ModAddr == ModAddrBack) && (ModFunction == ModFunctionBack) && (ModByteNumBack == ModDataLenBack))   
  918.         {  
  919.             ChangeAllButtonsDataByModBus(buttonJudge, ModDataBack, num);          
  920.                               
  921.             if(Bitmcmp(buttonData, buttonJudge, num))  
  922.             {  
  923.                 ChangeAllButtonsDataByModBus(buttonData, ModDataBack, num);       
  924.               
  925.                 if(IS_RS485)  Set485DirToTransmit(COMPORT1);  
  926.                 SendButtonDataToPC(COMPORT1, buttonData, i7188Addr);      
  927.                 if(IS_RS485)  WaitTransmitOver(COMPORT1);  
  928.                 if(IS_RS485)  {DelayMs(2); Set485DirToReceive(COMPORT1);}  
  929.                 WriteButtonToNVRAM(buttonData, num, buttonNVRAMAddr);     
  930.             }                     
  931.                               
  932.             strmcpy(oldModDataBack, ModDataBack, ModDataLenBack);         
  933.                       
  934.             return 1;  
  935.         }  
  936.         else  
  937.         {  
  938.             /*收到的字符串不匹配*/  
  939.             return 1;  
  940.         }  
  941.     }  
  942.     else  
  943.     {  
  944.         /*未收到字符串或CRC校验出错*/  
  945.         return 0;  
  946.     }  
  947. }  
  948.   
  949. /*-------------------------------------------------------------------------------*/  
  950.   
  951.   
  952. /*********************************************************************************/  
  953. /*函数名称: WriteMultipleWordToModBusSlave()                             
  954. *输入参数:  共 2 个参数; 
  955. *输出参数:  共 1 个参数; 
  956. *返回值:   成功与否; 
  957. *需储存的参数: 共 1 个参数;    
  958. *功能介绍:   
  959.         (1) 从触摸屏中写入设定参数值; 
  960.         (2) 指令为 01 16 HA LA HN LN HD LD ...... HC LC;其中 01 为MODBUSSLAVE的地址, 
  961.             16 为写连续多个WORD寄存器的功能码,HA LA 为第一个寄存器的高低位地址, 
  962.             HN LN 为寄存器数量的高低位,HC LC 为CRC校验码; 
  963.             HD LD 为数据高低位; 
  964. *修改日志: 
  965. *[2005-11-28 18:43]     Ver. 1.00 
  966.         开始编写; 
  967. *[2006-3-1 12:20]        
  968.         中间隔了很多时间; 
  969.         完成初稿,未测试;                            
  970. /*                                       */  
  971. /*********************************************************************************/  
  972.   
  973. int WriteMultipleWordToModBusSlave(int comPort, float parameterData[], unsigned short num, unsigned short ModDataAddr)  
  974. {     
  975.     unsigned char writeCmdStr[MOD_STR_MAX_LEN];             /* adjust */  
  976.     unsigned char ModAddr = 1;  
  977.     unsigned char ModFunction = 16;   
  978.     unsigned short ModDataNum;    
  979.     unsigned short readCmdLen;  
  980.     int isReadOK = 0;     
  981.       
  982.     unsigned short byteCount;  
  983.     unsigned char totalStrBack[300] = {'/0'};  
  984.     unsigned char ModAddrBack = 0;  
  985.     unsigned char ModFunctionBack = 0;  
  986.     unsigned short ModDataAddrBack;  
  987.     unsigned short ModDataNumBack;  
  988.       
  989.     ModDataNum = (unsigned short)num * 2;  
  990.     byteCount = (unsigned short)num * 4;  
  991.     readCmdLen = 7 + byteCount;  
  992.       
  993.     writeCmdStr[0] = ModAddr;  
  994.     writeCmdStr[1] = ModFunction;   
  995.     writeCmdStr[2] = (unsigned char)(ModDataAddr >> 8 & 0x00FF);  
  996.     writeCmdStr[3] = (unsigned char)(ModDataAddr & 0x00FF);  
  997.     writeCmdStr[4] = (unsigned char)(ModDataNum >> 8 & 0x00FF);  
  998.     writeCmdStr[5] = (unsigned char)(ModDataNum & 0x00FF);    
  999.     writeCmdStr[6] = (unsigned char)(byteCount  & 0x00FF);  
  1000.     WordDataToModbusStr(writeCmdStr, parameterData, num, 7);  
  1001.     writeCmdStr[7 + byteCount] = '/0';  
  1002.       
  1003.     ClearCom(comPort);  
  1004.     SendRtuCmdToModBus(comPort, writeCmdStr, readCmdLen);  
  1005.           
  1006.     isReadOK = ResponseFromModBusRtuSlave(comPort, totalStrBack,   
  1007.         &ModAddrBack, &ModFunctionBack, &ModDataAddrBack,   
  1008.         &ModDataNumBack, MOD_TIMEOUT, MOD_WAITTIME);  
  1009.       
  1010.     if (1 == isReadOK)  
  1011.     {             
  1012.         if((ModAddr == ModAddrBack) && (ModFunction == ModFunctionBack) && (ModDataAddr == ModDataAddrBack)  
  1013.             && (ModDataNum == ModDataNumBack))   
  1014.         {             
  1015.             return 1;  
  1016.         }  
  1017.         else  
  1018.         {             
  1019.             return 0;     
  1020.         }  
  1021.     }  
  1022.     else  
  1023.     {  
  1024.         /*未收到字符串或CRC校验出错*/  
  1025.         return 0;  
  1026.     }  
  1027. }  
  1028.   
  1029. /*-------------------------------------------------------------------------------*/  
  1030.   
  1031.   
  1032. /*********************************************************************************/  
  1033. /*函数名称: WriteMultipleBitToModBusSlave()                          
  1034. *输入参数:  共 2 个参数; 
  1035. *输出参数:  共 1 个参数; 
  1036. *返回值:   成功与否; 
  1037. *需储存的参数: 共 1 个参数;    
  1038. *功能介绍:   
  1039.         (1) 从触摸屏中写入BIT; 
  1040.         (2) 指令为 01 15 HA LA HN LN HD LD ...... HC LC;其中 01 为MODBUSSLAVE的地址, 
  1041.             16 为读连续多个WORD寄存器的功能码,HA LA 为第一个BIT的高低位地址, 
  1042.             HN LN 为BIT数量的高低位,HC LC 为CRC校验码; 
  1043.             HD LD 为数据高低位; 
  1044. *修改日志: 
  1045. *[2006-3-1 12:58]   Ver. 1.00 
  1046.         开始编写;    
  1047. *[2006-3-1 13:29] 
  1048.         完成;                              
  1049. /*                                       */  
  1050. /*********************************************************************************/  
  1051.   
  1052. int WriteMultipleBitToModBusSlave(int comPort, int DOData[], unsigned short num, unsigned short ModDataAddr)  
  1053. {     
  1054.     unsigned char writeCmdStr[100];       
  1055.     unsigned char ModAddr = 1;  
  1056.     unsigned char ModFunction = 15;  
  1057.     unsigned short ModDataNum;        
  1058.     unsigned short readCmdLen;  
  1059.     int isReadOK = 0;     
  1060.       
  1061.     unsigned short byteCount;  
  1062.     unsigned char totalStrBack[300] = {'/0'};  
  1063.     unsigned char ModAddrBack = 0;  
  1064.     unsigned char ModFunctionBack = 0;  
  1065.     unsigned short ModDataAddrBack;  
  1066.     unsigned short ModDataNumBack;  
  1067.       
  1068.     ModDataNum = (unsigned short)num;  
  1069.     if(num % 8)  
  1070.         byteCount = (unsigned short)(num / 8 + 1);  
  1071.     else    byteCount = (unsigned short)(num / 8);  
  1072.       
  1073.     readCmdLen = 7 + byteCount;  
  1074.       
  1075.     writeCmdStr[0] = ModAddr;  
  1076.     writeCmdStr[1] = ModFunction;   
  1077.     writeCmdStr[2] = (unsigned char)(ModDataAddr >> 8 & 0x00FF);  
  1078.     writeCmdStr[3] = (unsigned char)(ModDataAddr & 0x00FF);  
  1079.     writeCmdStr[4] = (unsigned char)(ModDataNum >> 8 & 0x00FF);  
  1080.     writeCmdStr[5] = (unsigned char)(ModDataNum & 0x00FF);    
  1081.     writeCmdStr[6] = (unsigned char)(byteCount  & 0x00FF);  
  1082.     BitDataToModbusStr(writeCmdStr, DOData, num, 7);  
  1083.     writeCmdStr[7 + byteCount] = '/0';  
  1084.       
  1085.     ClearCom(comPort);  
  1086.     SendRtuCmdToModBus(comPort, writeCmdStr, readCmdLen);  
  1087.           
  1088.     isReadOK = ResponseFromModBusRtuSlave(comPort, totalStrBack,   
  1089.         &ModAddrBack, &ModFunctionBack, &ModDataAddrBack,   
  1090.         &ModDataNumBack, MOD_TIMEOUT, MOD_WAITTIME);  
  1091.       
  1092.     if (1 == isReadOK)  
  1093.     {     
  1094.         if((ModAddr == ModAddrBack) && (ModFunction == ModFunctionBack) && (ModDataAddr == ModDataAddrBack)  
  1095.             && (ModDataNum == ModDataNumBack))   
  1096.         {  
  1097.             return 1;  
  1098.         }  
  1099.         else  
  1100.         {  
  1101.             return 0;     
  1102.         }  
  1103.     }  
  1104.     else  
  1105.     {  
  1106.         /*未收到字符串或CRC校验出错*/  
  1107.         return 0;  
  1108.     }  
  1109. }  
  1110.   
  1111. /*-------------------------------------------------------------------------------*/  
  1112.   
  1113.   
  1114. /*********************************************************************************/  
  1115. /*函数名称: WriteSingleBitToModBusSlave()                            
  1116. *输入参数:  共 2 个参数; 
  1117. *输出参数:  共 1 个参数; 
  1118. *返回值:   成功与否; 
  1119. *需储存的参数: 共 1 个参数;    
  1120. *功能介绍:   
  1121.         (1) 从触摸屏中写入BIT; 
  1122.         (2) 指令为 01 05 HA LA HD LD ...... HC LC;其中 01 为MODBUSSLAVE的地址, 
  1123.             05 为写单个BIT功能码,HA LA 为第一个BIT的高低位地址, 
  1124.             HN LN 为BIT数量的高低位,HC LC 为CRC校验码; 
  1125.             HD LD 为数据高低位; 
  1126. *修改日志: 
  1127. *[2006-3-7 14:06]   Ver. 1.00 
  1128.         开始编写;    
  1129. *[2006-3-7 14:40] 
  1130.         完成;  
  1131. *[2006-3-9 12:44] 
  1132.         去掉了等待接收反馈的功能;                                    
  1133. /*                                       */  
  1134. /*********************************************************************************/  
  1135.   
  1136. int WriteSingleBitToModBusSlave(int comPort, int DOData[], unsigned short num, unsigned short ModDataAddr)  
  1137. {     
  1138.     unsigned char writeCmdStr[15];        
  1139.     unsigned char ModAddr = 1;  
  1140.     unsigned char ModFunction = 5;  
  1141.     unsigned short ModDataState;          
  1142.     unsigned short readCmdLen = 6;  
  1143. /*  int isReadOK = 0;    
  1144.      
  1145.     unsigned short byteCount; 
  1146.     unsigned char totalStrBack[100]; 
  1147.     unsigned char ModAddrBack = 0; 
  1148.     unsigned char ModFunctionBack = 0; 
  1149.     unsigned short ModDataAddrBack; 
  1150.     unsigned short ModDataStateBack; 
  1151. */    
  1152.     ModDataState = DOData[num];  
  1153.       
  1154.     writeCmdStr[0] = ModAddr;  
  1155.     writeCmdStr[1] = ModFunction;   
  1156.     writeCmdStr[2] = (unsigned char)(ModDataAddr >> 8 & 0x00FF);  
  1157.     writeCmdStr[3] = (unsigned char)(ModDataAddr & 0x00FF);       
  1158.     if(ModDataState)    writeCmdStr[4] = (unsigned char)(0x00FF);  
  1159.     else    writeCmdStr[4] = (unsigned char)(0x0000);     
  1160.     writeCmdStr[5] = (unsigned char)(0x0000);  
  1161.     writeCmdStr[6] = '/0';  
  1162.       
  1163. /*  ClearCom(comPort);  */  
  1164.     SendRtuCmdToModBus(comPort, writeCmdStr, readCmdLen);  
  1165.     return 1;  
  1166.       
  1167. /*       
  1168.     isReadOK = ResponseSingleBitFromModBus(comPort, totalStrBack,  
  1169.         &ModAddrBack, &ModFunctionBack, &ModDataAddrBack,  
  1170.         &ModDataStateBack, MOD_TIMEOUT, MOD_WAITTIME); 
  1171.      
  1172.     if (1 == isReadOK) 
  1173.     {        
  1174.         Print("/tB %u %u   %u %u  %u %u  %u %u", ModAddr, ModAddrBack, ModFunction, ModFunctionBack, ModDataAddr, ModDataAddrBack, ModDataState, ModDataStateBack); 
  1175.         if((ModAddr == ModAddrBack) && (ModFunction == ModFunctionBack) && (ModDataAddr == ModDataAddrBack) 
  1176.             && (ModDataState == ModDataStateBack))  
  1177.         { 
  1178.             Print("/tretur sB1 /t"); 
  1179.             return 1; 
  1180.         } 
  1181.         else 
  1182.         { 
  1183.             Print("/tretur sB0 /t"); 
  1184.             return 0;    
  1185.         } 
  1186.     } 
  1187.     else 
  1188.     { 
  1189.         /*未收到字符串或CRC校验出错* / 
  1190.         return 0; 
  1191.     } 
  1192. */    
  1193. }  
  1194.   
  1195. /*-------------------------------------------------------------------------------*/  
  1196.   
  1197.   
  1198. /*********************************************************************************/  
  1199. /*函数名称: WriteBitByBitToModBusSlave()                             
  1200. *输入参数:  共  个参数; 
  1201. *输出参数:  共  个参数; 
  1202. *返回值:   成功与否; 
  1203. *需储存的参数: 共  个参数;     
  1204. *功能介绍:   
  1205.         (1) 一个一个地将BIT写如触摸屏中; 
  1206.         (2) 可能很耗时;   
  1207. *修改日志: 
  1208. *[2006-3-7 14:40]   Ver. 1.00 
  1209.         开始编写;    
  1210. *[2006-3-7 14:51] 
  1211.         完成;                              
  1212. /*                                       */  
  1213. /*********************************************************************************/  
  1214.   
  1215. int WriteBitByBitToModBusSlave(int comPort, int DOData[], int dataOld[], unsigned short num, unsigned short ModDataAddr)  
  1216. {     
  1217.     int i;  
  1218.       
  1219.     for(i = 0; i < num; i ++)  
  1220.     {  
  1221.         if(DOData[i] != dataOld[i])  
  1222.         {         
  1223.             DelayMs(1);  
  1224.             WriteSingleBitToModBusSlave(comPort, DOData, i, ModDataAddr + i);                     
  1225.         }  
  1226.     }  
  1227.     return 1;  
  1228. }  
  1229.   
  1230. /*-------------------------------------------------------------------------------*/  
  1231.   
  1232.   
  1233. /*********************************************************************************/  
  1234. /*函数名称: WriteAllBitByBitToModBusSlave()                          
  1235. *输入参数:  共  个参数; 
  1236. *输出参数:  共  个参数; 
  1237. *返回值:   成功与否; 
  1238. *需储存的参数: 共  个参数;     
  1239. *功能介绍:   
  1240.         (1) 一个一个地将BIT写如触摸屏中; 
  1241.         (2) 可能很耗时;   
  1242. *修改日志: 
  1243. *[2006-3-9 12:52]   Ver. 1.00 
  1244.         开始编写;    
  1245. *[2006-3-9 12:52] 
  1246.         完成;                              
  1247. /*                                       */  
  1248. /*********************************************************************************/  
  1249.   
  1250. int WriteAllBitByBitToModBusSlave(int comPort, int DOData[], unsigned short num, unsigned short ModDataAddr)  
  1251. {     
  1252.     int i;  
  1253.       
  1254.     for(i = 0; i < num; i ++)  
  1255.     {         
  1256.         DelayMs(1);  
  1257.         WriteSingleBitToModBusSlave(comPort, DOData, i, ModDataAddr + i);                     
  1258.           
  1259.     }  
  1260.     return 1;  
  1261. }  
  1262.   
  1263. /*-------------------------------------------------------------------------------*/  
  1264.   
  1265.   
  1266. /*********************************************************************************/  
  1267. /*函数名称: ListenToTouch()                          
  1268. *输入参数:  共  个参数; 
  1269. *输出参数:  共  个参数; 
  1270. *返回值:   无; 
  1271. *需储存的参数: 共  个参数;     
  1272. *功能介绍:   
  1273.         (1)监控Touch触摸屏; 
  1274.         (2) init的工作给 WriteMultipleWordToModBusSlave 是否成功。 
  1275.         (3) 必须要DelayMs(50)才能使一下个response正确。 
  1276. *修改日志: 
  1277. *[2006-3-1 17:19]   Ver. 1.00 
  1278.         开始编写;    
  1279. *[2006-3-1 17:33] 
  1280.         完成;  
  1281. *[2006-3-9 14:10] 
  1282.         测试通过;                                
  1283. /*                                       */  
  1284. /*********************************************************************************/  
  1285.   
  1286. void ListenToTouch(int comPort, int buttonData[], float parameterData[], int DOData[], float AIData[])  
  1287. {  
  1288.     int kind = 1;                   /* adjust */  
  1289.       
  1290.     unsigned short parameterNum = PARAMETER_DATA_NUM;  
  1291.     unsigned short parameterAddr = PARAMETER_MODBUS_ADDR_1; /* adjust */  
  1292.       
  1293.     unsigned short buttonNum = BUTTON_DATA_NUM;  
  1294.     unsigned short buttonAddr = BUTTON_MODBUS_ADDR_1;   /* adjust */  
  1295.       
  1296.     unsigned short DONum = DIGITAL_OUT_DATA_NUM;  
  1297.     unsigned short DOAddr = DO_MODBUS_ADDR_1;   /* adjust */  
  1298.       
  1299.     unsigned short AINum = ANALOG_IN_DATA_NUM;  
  1300.     unsigned short AIAddr = AI_MODBUS_ADDR_1;   /* adjust */  
  1301.       
  1302.     int buttonNVRAMAddr = BUTTON_ADDR_1;        /* adjust */      
  1303.     int parameterEEPROMAddr = EEPROM_BLOCK;     /* adjust */  
  1304.       
  1305.     static unsigned char oldModWordBack[MOD_STR_MAX_LEN] = {'/0'};  /* 以前的str */  
  1306.     static unsigned char oldModBitBack[MOD_STR_MAX_LEN] = {'/0'};  
  1307.       
  1308.     static int responseFromTouch_init = 0;      /*首次初始化*/  
  1309. /*  static int responseFromTouch_P = 0; 
  1310.     static int responseFromTouch_Btn = 0;    
  1311.     static int oldButtonData[30] = {0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; 
  1312.     static int oldDOData[30] = {0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; 
  1313. */    
  1314.     int response;       /*test*/  
  1315.       
  1316. /*  Print("/n/n");  */  
  1317.     if(0 == responseFromTouch_init)     /* 第一次写入Touch_Btn失败重新写 */  
  1318.     {     
  1319.     /*  responseFromTouch_Btn = WriteMultipleBitToModBusSlave(comPort, buttonData, buttonNum, buttonAddr); 
  1320.     */  response = WriteAllBitByBitToModBusSlave(comPort, buttonData, buttonNum, buttonAddr);         
  1321.     /*  bitmcpy(oldButtonData, buttonData, buttonNum);  */  
  1322.     }  
  1323.     else  
  1324.     {  
  1325.         /* 读取按钮值 */  
  1326.         response = ReadBitFromModBusSlave(kind, comPort, buttonData, buttonNum, buttonAddr, buttonNVRAMAddr, oldModBitBack);  
  1327.     }  
  1328.     DelayMs(50);  
  1329. /*  Print(" rb%d", response);   */  
  1330.       
  1331.     if(0 == responseFromTouch_init)         /* 第一次写入Touch_P失败重新写 */  
  1332.     {         
  1333.         responseFromTouch_init = WriteMultipleWordToModBusSlave(comPort, parameterData, parameterNum, parameterAddr);  
  1334.         response = responseFromTouch_init;  
  1335.     /*  responseFromTouch_P = 1;    /*test*/  
  1336.     }     
  1337.     else  
  1338.     {  
  1339.         /* 读取设定参数 */  
  1340.         response = ReadWordFromModBusSlave(kind, comPort, parameterData, parameterNum, parameterAddr, parameterEEPROMAddr, oldModWordBack);  
  1341.     }  
  1342.       
  1343. /*  Print(" p%d", responseFromTouch_P); 
  1344.     Print(" rp%d", response);   */  
  1345.     DelayMs(2);  
  1346.     /* 写入开关量 */  
  1347. /*  response = WriteMultipleBitToModBusSlave(comPort, DOData, DONum, DOAddr);    
  1348. */    
  1349.     response = WriteAllBitByBitToModBusSlave(comPort, DOData, DONum, DOAddr);  
  1350. /*  bitmcpy(oldDOData, DOData, DONum);  */  
  1351.           
  1352. /*  Print(" d%d", response);    */  
  1353.     DelayMs(40);  
  1354.     /* 写入采样值 */  
  1355.     response = WriteMultipleWordToModBusSlave(comPort, AIData, AINum, AIAddr);  
  1356. /*  Print(" a%d", response);    */  
  1357.     if(response);  
  1358. }  
  1359.   
  1360. /*-------------------------------------------------------------------------------*/ 
上一篇:uiPath项目


下一篇:心选建站---根据企业和个人阿里云建站的优点与缺点