【Reproduced】C language program of MODBUS RTU MASTER
From:http://blog.csdn.net/wangshunli/article/details/7530801

   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   

posted on 2015-03-13 23:20 Daimon.gu 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/yongdaiblog-201409/articles/4336230.html

【Reproduced】C language program of MODBUS RTU MASTER相关推荐

  1. 【Reproduced】modbus4j userguide

    [Reproduced]modbus4j userguide 1 使用modbus4j开源项目,通过串口读取数据,过程中遇到点小问题.(转的demo按自己的需求修改的) 2 3 1.串口不对应,导致 ...

  2. Modbus协议栈开发笔记之六:Modbus RTU Master开发

    这一节我们来封装最后一种应用(Modbus RTU Master应用),RTU主站的开发与TCP客户端的开发是一致的.同样的我们也不是做具体的应用,而是实现RTU主站的基本功能.我们将RTU主站的功能 ...

  3. 【逗老师带你学IT】PRTG监控通过Python+Modbus RTU获取温湿度传感器数据

    前文[逗老师带你学IT]PRTG监控通过Python+TCP Modbus获取温湿度传感器数据中我们讲了如何通过Python读取支持TCP Modbus的传感器数据.本章我们讲解下如何读取Modbus ...

  4. 【GPT】Improving Language Understanding by Generative Pre-Training

    Paper Link: Improving Language Understanding by Generative Pre-Training GPT系列文章解读: [GPT2]Language Mo ...

  5. 【NLP】AutoRegressive Language Model

    AutoRegressive Language Model 回归分析(regression analysis)是确定两种或两种以上变数间相互依赖的定量关系的一种统计分析方法.AutoRegressiv ...

  6. 【PyTorch】语言模型/Language model

    1 模型描述 (1)语言模型的定义,来自于维基百科 统计式的语言模型是一个几率分布.语言模型提供上下文来区分听起来相似的单词和短语.例如,短语"再给我两份葱,让我把记忆煎成饼"和& ...

  7. DEVC++【error】: stray ‘\×××’ in program错误原因及解决方法持续更新

    #include <stdio.h> int main() {printf("hello world !\n"): return 0; } 当你写出这样一段狗屎代码,然 ...

  8. 【kubernetes】k8s v1.20高可用多master节点部署

    一,安装环境 1,硬件要求 内存:2GB或更多RAM CPU: 2核CPU或更多CPU 硬盘: 30GB或更多 2,本次环境说明: 操作系统:CentOS 7.9 内核版本:3.10.0-1160 虚 ...

  9. 【linux】串口编程(二)——非阻塞接收

    项目中很少会使用阻塞接收,一般都是select+read监听模式来实现非阻塞接收. 使用selece时,需要处理一些异常情况的返回,比如:系统中断产生EINTR错误:超时错误ETIMEDOUT. 使用 ...

最新文章

  1. 【Flutter】Flutter 启动白屏问题 ( 问题描述 | 在 launch_background.xml 中设置启动过渡 UI )
  2. com.android.dex.DexIndexOverflowException: Cannot merge new index 66299 into a non-jumbo instruction
  3. SYBASE里面出现客户端和服务器端字符集不匹配的情况解决方法
  4. VMware内存回收与分配机质
  5. (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  6. js保存当前html,JavaScript保存当前页面
  7. 【数据库题型大总结】应用题总结
  8. php安装了openssl扩展,php如何安装openssl扩展?
  9. 苹果手机黑屏了怎么办_来电话手机黑屏怎么办
  10. loss值多少才算收敛_库存究竟多少才算合理?
  11. 《数据挖掘导论》绪论
  12. Uva 10247 (组合计数)
  13. 微软阿根廷服务器解锁,XBOX阿根廷服购买教程
  14. 【webView】webView和原生Android交互
  15. 如何实现用户关系的自动绑定?
  16. 最简便的方法搭建Hexo+Github博客,基于Next主题
  17. (附源码)计算机毕业设计SSM基于框架的点餐系统
  18. Python基础操作_字典的遍历
  19. CSS 之 Flex布局
  20. .NET开发中的几个JS奇技淫巧

热门文章

  1. android:exported、enabled属性
  2. C#【时间操作类】使用TimeSpan计算时间差
  3. 一口气搞懂「文件系统」,就靠这 25 张图了
  4. 利用计算机名称共享打印机步骤,如何连接其他电脑共享的打印机(图文教程)...
  5. 正在找工作的同学看过来,zozo最新的java面试题总会,学会月薪3万起!!!
  6. Simulink基础:基本模块操作2(Gain模块与积分模块)
  7. Vue + element-ui合并单元格后,checkbox多选单选取值问题
  8. 微信破解WiFi密码如何操作?一招帮你查看密码!
  9. 微软数据中心将到南非!AWS也将要跟进
  10. 数据库性能调优架构师所需的skillset