| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384 |
- /********************************************************************
- 版权所有:
- 文件版本: V1.00
- 文件名称: Modbus.c
- 生成日期: 2008年11月13日
- 作 者:xxxxxx
- 使用范围:
- 功 能: Modbus规约处理,为节省RAM空间,MODBUS规约处理,借用了103规约的结构定义
- 更新信息:
- 更新日志1:
- 修改者:
- 修改日期:
- 修改内容:
- 修改原因:
- *********************************************************************/
- #include "head.h"
- struct MODBUS_CMD_LEN
- {
- u8 cmd;
- u8 len;
- }; // 16*2
-
- struct MODBUS_CMD_LEN tModbusCmd[]=
- {
- {0x01,0},
- {0x02,0},
- {0x03,0},
- {0x04,0},
- {0x05,4},
- {0x06,4},
- {0x07,1},
- {0x0b,1},
- {0x0c,0},
- {0x0F,4},
- {0x10,4},
- {0x11,0},
- {0x85,1},
- };
- int modbus_cmd_num=sizeof(tModbusCmd)/sizeof(tModbusCmd[0]);
- BYTE MoDusCRCtableHi[] = // Modbus 高位校验码
- {
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
- 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40
- } ;
- //-------------------------------------------------------------
- //@@***********************************************************
- // MoDus CRC 低位字节值表
- //@@***********************************************************
- //-------------------------------------------------------------
- BYTE MoDusCRCtableLo[] =
- {
- 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
- 0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
- 0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
- 0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
- 0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
- 0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
- 0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
- 0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
- 0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
- 0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
- 0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
- 0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
- 0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
- 0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
- 0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
- 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40
- } ;
- /**************************************************************************
- 函数名称:Modbus_CRC16
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:Modbus规约的CRC校验
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- WORD Modbus_CRC16(BYTE *inbytes, WORD CRCnumber) // 返回,低字节在高位
- {
- BYTE crcbyteHi = 0xFF ;
- BYTE crcbyteLo = 0xFF ;
- BYTE uIndex ;
-
- while (CRCnumber--)
- {
- uIndex = crcbyteHi ^ *inbytes++ ;
- crcbyteHi = crcbyteLo ^ MoDusCRCtableHi[uIndex] ;
- crcbyteLo = MoDusCRCtableLo[uIndex] ;
- }
- return ( (crcbyteHi << 8) | crcbyteLo ) ;
- }
- int _getslaveaddr(char *buf)
- {
- char *str,str1[6];
- int val=0;
- str=strstr(buf,"_slave");
- if(str)
- {
- memcpy(str1,&str[6],2);
- str1[2]='\0';
- val=strtoul(str1,NULL,10);
- }
- return val;
- }
- static void _getmodbusinf(MODBUS_DEF *pt,u8 *filestr)
- {
- u8 str[64];
- if(filestr[0]=='[') // 是规约类型
- {
- pt->bcfg=false;
- sprintf(str,"[COM%d_MODBUS]",pt->chnl);
- if(strcmp(filestr,"[MODBUS_ALL]")==0||strcmp(filestr,str)==0)
- {
- pt->bcfg=true;
- }
- return;
- }
- if(!pt->bcfg)return;
- if(strstr(filestr,"yxcmd")) // 遥信命令码
- {
- pt->yxcmd=getstrval(filestr);
- }
- else if(strstr(filestr,"yccmd")) //
- {
- pt->yccmd=getstrval(filestr);
- }
- else if(strstr(filestr,"ykcmd")) //
- {
- pt->ykcmd=getstrval(filestr);
- }
- else if(strstr(filestr,"ddcmd")) //
- {
- pt->ddcmd=getstrval(filestr);
- }
- else if(strstr(filestr,"yxreadbit")) //
- {
- pt->readbit=getstrval(filestr);
- }
- else if(strstr(filestr,"yxbytes")) //
- {
- pt->yxbitbytes=getstrval(filestr);
- }
- else if(strstr(filestr,"ycbytes")) //
- {
- pt->ycbitbytes=getstrval(filestr);
- }
- else if(strstr(filestr,"ykbytes")) //
- {
- pt->ykbitbytes=getstrval(filestr);
- }
- else if(strstr(filestr,"ddbytes")) //
- {
- pt->ddbitbytes=getstrval(filestr);
- }
- else if(strstr(filestr,"ykval_h")) //
- {
- pt->ykval_h=getstrval(filestr);
- }
- else if(strstr(filestr,"ykval_f")) //
- {
- pt->ykval_f=getstrval(filestr);
- }
- else if(strstr(filestr,"retrytime")) //
- {
- pt->retrytime=getstrval(filestr)*SAM_FREQUENCY; // 单位秒,转为dTcounter 值
- }
- else if(strstr(filestr,"sendinteraltime")) //
- {
- pt->sendinteraltime=getstrval(filestr)*SAMFREQ/20; // 单位毫秒,转为dTcounter值
- }
- else if(strstr(filestr,"coiladdr")) //
- {
- pt->coiladdr=getstrval(filestr); // 线圈地址
- }
- else if(strstr(filestr,"cmd_dinum")) //
- {
- pt->cmd_dinum=getstrval(filestr); // 点号长度
- }
- else if(strstr(filestr,"cmd_datnum")) //
- {
- pt->cmd_datnum=getstrval(filestr); // 数据长度
- }
- else if(strstr(filestr,"dat_dir")) //
- {
- pt->dat_dir=getstrval(filestr); //数据方向
- }
- else if(strstr(filestr,"yxdi")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_YX<<4)|MODBUS_INF_DI);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"ycdi")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_YC<<4)|MODBUS_INF_DI);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"dddi")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_DD<<4)|MODBUS_INF_DI);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"yxnum")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_YX<<4)|MODBUS_INF_NUM);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"ycnum")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_YC<<4)|MODBUS_INF_NUM);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"ddnum")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_DD<<4)|MODBUS_INF_NUM);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"yxbit")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=((MODBUS_TYPE_YX<<4)|MODBUS_INF_BITS);
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"sendaddr")) //
- {
- pt->tinf[pt->infnum].slaveaddr=_getslaveaddr(filestr);
- pt->tinf[pt->infnum].val=getstrval(filestr);
- pt->tinf[pt->infnum].type=MODBUS_INF_SENDADDR;
- pt->infnum++;
- if(pt->infnum>=MODBUS_INF_MAX)pt->infnum=MODBUS_INF_MAX-1;
- }
- else if(strstr(filestr,"ycrate")) //
- {
- pt->yc_rate=getstrval(filestr);
- }
- #ifdef MODBUS_YX_REG_NUM
- else if(strstr(filestr,"yxregnum")) //
- {
- pt->yxregnum=getstrval(filestr);
- }
- #endif
-
- }
- static int modbus_init_inf(MODBUS_DEF *pt)
- {
- u32 i,file_length;
- struct file * pfile;
- u8 *filebuf;
- u8 filestr[128],*pstr,strlenth;
- loff_t pos;
- // 打开文件
- pfile = rt_file_open("/app/data/pcolcfg.ini",O_RDONLY ,0);
- if(IS_ERR(pfile))
- {
- dp_err_n_c_rt("error! 无法打开 pcolcfg.ini\r\n");
- return -1;
- }
- // 得到文件长度
- file_length = rt_file_getfile_size(pfile);
- if(file_length <= 0)
- {
- rt_file_close(pfile,0);
- return -2;
- }
- // 分配内存
- filebuf = rt_malloc(file_length);
- if((filebuf) == NULL)
- {
- rt_file_close(pfile,0);
- return -3;
- }
- pos = 0;
- if(rt_file_read(pfile,filebuf,file_length,&pos) != file_length)
- {
- rt_file_close(pfile,0);
- rt_free(filebuf);
- return -4;
- }
- pstr = filestr;
- strlenth=0; // 纠错处理
- //找到\r\n位置,得到一行长度
- for(i = 0; i < file_length; i++)
- {
- *pstr++=filebuf[i];
- strlenth++;
- if(filebuf[i] == 0x0a||strlenth>=128)
- {
- int j;
- pstr = filestr;
- for(j=0;j<strlenth;j++)
- {
- if(*pstr==' '||*pstr=='\t') // 取空格或tab 前的字符
- {
- *pstr='\0';
- break;
- }
- pstr++;
- }
- *pstr='\0';
- _getmodbusinf(pt,filestr);
- pstr=filestr;
- strlenth=0;
- }
- }
- rt_file_close(pfile,0); // 关闭文件
- rt_free(filebuf); // 释放内存
- return 0;
- }
- typedef struct MODBUS_SLAVE_DEF
- {
- u8 cmd;
- u8 type;
- u8 dinum;
- u8 bitbytes;
- u8 readbit;
- #ifdef MODBUS_YX_REG_NUM
- u8 yxregnum;
- #endif
- WORD dimin;
- WORD dimax;
- WORD slaveaddr;
-
- }MODBUS_SLAVE_DEF;
- void modbus_count_slaveaddr(MODBUS_DEF *pt,u8 chnl,LINK_TABLE* lt,u32 num,BYTE cmd,BYTE bitbytes,BYTE readbit,BYTE type)
- {
- u8 ch;
- u8 addr=0;
- u16 di;
- MODBUS_SLAVE_DEF tms[32];
- int i,j,slavenum;
- #ifdef MODBUS_YX_REG_NUM
- BYTE yxregnum = pt->yxregnum;
- WORD yx_dimin=0,yx_dimax=0;
- #endif
- memset(&tms,0,sizeof(tms));
- slavenum=0;
- for(j=0;j<num;j++)
- {
- ch=(u8)((lt->cp_s>>21)&0x0f);
- addr=(u8)((lt->cp_s>>16)&0x1f);
- di=(u16)lt->cp_s;
-
- if(addr>0&&(ch==chnl)) // 通道相符
- {
- if(slavenum==0)
- {
- tms[slavenum].slaveaddr=addr;
- tms[slavenum].dimax=di;
- tms[slavenum].dimin=di;
- tms[slavenum].cmd=cmd;
- tms[slavenum].bitbytes=bitbytes;
- tms[slavenum].readbit=readbit;
- tms[slavenum].type=type;
- tms[slavenum].dinum=1;
- #ifdef MODBUS_YX_REG_NUM
- tms[slavenum].yxregnum=yxregnum;
- #endif
- slavenum++;
-
- }
- else
- {
- for(i=0;i<slavenum;i++)
- {
- if(tms[i].slaveaddr==addr&& (tms[i].type==type) )// 同一类型,同一子站地址
- {
- if(di<tms[i].dimin)
- {
- tms[i].dimin=di;
- }
- if(di>tms[i].dimax)
- {
- tms[i].dimax=di;
- }
- tms[i].dinum++; // 个数加1
- break;
- }
- }
- if(i==slavenum)
- {
- tms[slavenum].slaveaddr=addr;
- tms[slavenum].dimax=di;
- tms[slavenum].dimin=di;
- tms[slavenum].cmd=cmd;
- tms[slavenum].bitbytes=bitbytes;
- tms[slavenum].readbit=readbit;
- tms[slavenum].type=type;
- tms[slavenum].dinum=1;
- #ifdef MODBUS_YX_REG_NUM
- tms[slavenum].yxregnum=yxregnum;
- #endif
- slavenum++;
- }
- }
- }
- lt++;
- }
-
- for(i=0;i<slavenum;i++)
- {
- WORD maxsmin;
- for(j=0;j<pt->infnum;j++) // 判断字节数类型,是否有重新定义
- {
- if(tms[i].slaveaddr==pt->tinf[j].slaveaddr)
- {
-
- if(((pt->tinf[j].type>>4)&0x0f)==tms[i].type)
- {
- if((pt->tinf[j].type&0x0f)==MODBUS_INF_BITS)
- {
- tms[i].readbit=pt->tinf[j].val;
- }
- }
- }
- }
- #ifdef MODBUS_YX_REG_NUM
- yx_dimax = tms[i].dimax;
- yx_dimin = tms[i].dimin;
- #endif
- if(type==MODBUS_TYPE_YX && tms[i].readbit==1 && tms[i].dimin!=0) // 遥信且按bit取值
- {
- #ifndef LINK_MODBUS_YX_CP
- tms[i].dimax>>=4; // 最低4bit为 位序号
- tms[i].dimin>>=4; // 最低4bit为 位序号
- #endif
- }
- pt->tcmd[pt->cmdnum].slaveaddr=tms[i].slaveaddr;
- pt->tcmd[pt->cmdnum].cmd=tms[i].cmd;
- pt->tcmd[pt->cmdnum].bitbytes=tms[i].bitbytes;;
- pt->tcmd[pt->cmdnum].readbit=tms[i].readbit;;
- pt->tcmd[pt->cmdnum].di=tms[i].dimin;
- pt->tcmd[pt->cmdnum].type=tms[i].type;
- maxsmin=tms[i].dimax-tms[i].dimin+1;
- #ifdef MODBUS_YX_REG_NUM
- if((type==MODBUS_TYPE_YX&&tms[i].readbit==1))
- {
- if(tms[i].yxregnum==0)
- {
- pt->tcmd[pt->cmdnum].num=(yx_dimax-yx_dimin+1)%16?(yx_dimax-yx_dimin+1)/16+1:(yx_dimax-yx_dimin+1)/16;
- }
- else
- {
- pt->tcmd[pt->cmdnum].num=yx_dimax-yx_dimin+1;
- }
- }
- else
- {
- pt->tcmd[pt->cmdnum].num=(maxsmin>tms[i].dinum)?maxsmin:tms[i].dinum; // 取个数大的为寄存器个数
- }
- #else
- pt->tcmd[pt->cmdnum].num=(maxsmin>tms[i].dinum)?maxsmin:tms[i].dinum; // 取个数大的为寄存器个数
- #endif
- pt->tcmd[pt->cmdnum].byxfirst=false;
- if(tms[i].bitbytes==4||tms[i].bitbytes==13) // 四个字节或浮点数
- {
- pt->tcmd[pt->cmdnum].num*=2; // 寄存器个数加倍
- }
- for(j=0;j<pt->infnum;j++) // 更新重新定义的点号和召唤个数
- {
- if(pt->tcmd[pt->cmdnum].slaveaddr==pt->tinf[j].slaveaddr)
- {
-
- if(((pt->tinf[j].type>>4)&0x0f)==pt->tcmd[pt->cmdnum].type)
- {
- if((pt->tinf[j].type&0x0f)==MODBUS_INF_DI)
- {
- pt->tcmd[pt->cmdnum].di=pt->tinf[j].val;
- }
- else if((pt->tinf[j].type&0x0f)==MODBUS_INF_NUM)
- {
- pt->tcmd[pt->cmdnum].num=pt->tinf[j].val;
- }
- }
- }
- }
- pt->cmdnum++;
- if(pt->cmdnum>=MODBUS_CMD_NUM)
- {
- pt->cmdnum=MODBUS_CMD_NUM-1;
- }
- }
- }
- void modbus_sendaddr_init(MODBUS_DEF *pt)
- {
- int i;
- for(i=0;i<pt->cmdnum;i++)
- {
- int j;
- pt->tcmd[i].sendaddr=pt->tcmd[i].slaveaddr;
- for(j=0;j<pt->infnum;j++)
- {
- if((pt->tinf[j].type==MODBUS_INF_SENDADDR)&&(pt->tinf[j].slaveaddr==pt->tcmd[i].slaveaddr))
- {
- pt->tcmd[i].sendaddr=pt->tinf[j].val;
- }
- }
- }
- }
- /**************************************************************************
- 函数名称:Modbus_Init
- 函数版本:1.00
- 作者:
- 创建日期:2008.9.1
- 函数功能说明:Modbus规约初始化
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_Init(MODBUS_DEF *pt,BYTE chnl)
- {
- int i;
- memset(pt,0,sizeof(MODBUS_DEF));
- pt->type=IEC_MODBUS_M;
- pt->chnl=chnl;
- pt->bData=false;
- pt->sendbuf=g_tRsComm[chnl].sendbuf;
- pt->dsendtime=dTCounter;
- pt->yxcmd=2;
- pt->yccmd=3;
- pt->ykcmd=5;
- pt->ddcmd=4;
- pt->yxbitbytes=1;
- pt->ycbitbytes=2;
- pt->ykbitbytes=2;
- pt->ddbitbytes=4;
- pt->ykval_h=0xff00;
- pt->ykval_f=0x0000;
- pt->coiladdr=0;
- pt->readbit=0;
- pt->cmd_datnum=2;
- pt->cmd_dinum=2;
- pt->dat_dir=0;
- pt->yc_rate=1;
- modbus_init_inf(pt);
- modbus_count_slaveaddr(pt,chnl+2,&g_lt_di[0],g_lt_di_num,pt->yxcmd,pt->yxbitbytes,pt->readbit,MODBUS_TYPE_YX);
- modbus_count_slaveaddr(pt,chnl+2,&g_lt_ac[0],g_lt_ac_num,pt->yccmd,pt->ycbitbytes,0,MODBUS_TYPE_YC);
- modbus_count_slaveaddr(pt,chnl+2,&g_lt_dd[0],g_lt_dd_num,pt->ddcmd,pt->ddbitbytes,0,MODBUS_TYPE_DD);
- modbus_sendaddr_init(pt);
- rt_printf("\r\nmodbus_init(channel=%d):\r\n",chnl);
- for(i=0;i<pt->cmdnum;i++)
- {
- rt_printf("chnl=%d addr=%d sendaddr=%d di=%04x cmd=%d num=%d type=%d bitbytes=%d readbit=%d\r\n",chnl,pt->tcmd[i].slaveaddr,pt->tcmd[i].sendaddr,pt->tcmd[i].di,pt->tcmd[i].cmd,pt->tcmd[i].num,pt->tcmd[i].type,pt->tcmd[i].bitbytes,pt->tcmd[i].readbit);
- }
-
- }
- /**************************************************************************
- 函数名称:Modbus_Recv_Rst
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:复归数据的接受
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_recv_rst(MODBUS_DEF *pt)
- {
- pt->nTypeCounter=0;
- pt->nRecvLenth=0;
- pt->nRecvCounter=0;
- pt->dWaitTime=dTCounter;
-
- }
- int get_cmd_len(u8 cmd)
- {
- int i;
- for(i=0;i<modbus_cmd_num;i++)
- {
- if(tModbusCmd[i].cmd==cmd)
- {
- return tModbusCmd[i].len;
- }
- }
- return -1;
- }
- /**************************************************************************
- 函数名称:Modbus_Recv
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:Modbus规约的数据接收处理,此处有3.5位的时间判断处理
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_Recv(MODBUS_DEF *pt,unsigned char byRevData)
- {
- int len;
- if(pt->bData)return ;
- if(dTCounter-pt->dWaitTime>T_5ms) //检测到空闲间隔 3.5个字符
- {
- pt->recvbuf[pt->nRecvCounter++]=byRevData;
- switch(pt->nTypeCounter)
- {
- case 0: // 子站地址
- if(byRevData==pt->slaveaddr)
- {
- pt->nTypeCounter++;
- }
- else
- {
- modbus_recv_rst(pt);
- }
- break;
- case 1: //功能码
- pt->nTypeCounter++;
- break;
- case 2: //字节数
- len=get_cmd_len(pt->recvbuf[1]);
- pt->nTypeCounter++;
- pt->nRecvCnt=0;
- if(len==0)
- {
- pt->nRecvLenth=byRevData+2;
- }
- else if(len>0)
- {
- pt->nRecvLenth=len+1;
- }
- else
- {
- modbus_recv_rst(pt);
- }
-
- break;
- case 3: // CRC L 或其他数据
- pt->nRecvCnt++;
- if(pt->nRecvCnt>=pt->nRecvLenth)
- {
- modbus_recv_rst(pt);
- pt->bData=true;
- }
- break;
- default:
- modbus_recv_rst(pt);
- break;
- }
- }
- else //奇偶校验出错,舍弃已接收的数据
- {
- modbus_recv_rst(pt);
- }
- }
- /**************************************************************************
- 函数名称:Modbus_ErrorEcho
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:Modbus规约错误帧应答
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_errorecho(MODBUS_DEF *pt,unsigned char *ps,unsigned char err)
- {
- BYTE *pd=pt->sendbuf;
- WORD crc;
- pd[0]=5;
- pd[1]=pt->tcmd[pt->bCurrent].slaveaddr; // 地址
- pd[2]=ps[1]|0x80; // 命令码
- pd[3]=err; // 错误码
- crc=Modbus_CRC16(&pd[1],3);
- pd[4]=(BYTE)(crc>>8);
- pd[5]=(BYTE)(crc);
- }
- /**************************************************************************
- 函数名称:Modbus_ReadData
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:Modbus规约读数据应答,响应 02 03命令
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_send(MODBUS_DEF *pt)
- {
- if(g_print_lnk && (g_print_port & (1<<pt->chnl)))
- {
- print_msg("TX_MODBUS:",&g_tRsComm[pt->chnl].sendbuf[1],g_tRsComm[pt->chnl].sendbuf[0]);
- }
-
- RS_Send_Enable(pt->chnl);
- g_tRsComm[pt->chnl].nSendCnt=1; // 发送缓冲区的第一个字节为发送长度
- g_tRsComm[pt->chnl].bSend=true;
- pt->slaveaddr=g_tRsComm[pt->chnl].sendbuf[1];
- if(!g_bCommLed)g_bCommLed=true;
-
- //统计发送帧数
- }
- void modbus_read(MODBUS_DEF *pt,BYTE index)
- {
- BYTE *pd=pt->sendbuf;
- int num=0;
- WORD crc;
- pt->readdi=pt->tcmd[index].di;
- pd[num++]=0;
- pd[num++]=pt->tcmd[index].slaveaddr; // 地址
- pd[num++]=pt->tcmd[index].cmd; // 命令码
- if(pt->cmd_dinum>1) pd[num++]=(BYTE)(pt->tcmd[index].di>>8);
- pd[num++]=(BYTE)(pt->tcmd[index].di);
- if(pt->cmd_datnum>1) pd[num++]=(BYTE)(pt->tcmd[index].num>>8);
- pd[num++]=(BYTE)(pt->tcmd[index].num);
- crc=Modbus_CRC16(&pd[1],num-1);
- pd[num++]=(BYTE)(crc>>8);
- pd[num++]=(BYTE)(crc);
- pd[0]=num-1;
- modbus_send(pt);
- }
- void modbus_write(MODBUS_DEF *pt,BYTE addr,WORD di,BYTE num,BYTE *pdat)
- {
- BYTE *pd=pt->sendbuf;
- WORD crc;
- int i,j;
- BYTE slaveaddr=addr;
- int cnt=0;
- for(j=0;j<pt->infnum;j++)
- {
- if((pt->tinf[j].type==MODBUS_INF_SENDADDR)&&(pt->tinf[j].slaveaddr==addr))
- {
- slaveaddr=pt->tinf[j].val;
- }
- }
- pt->readdi=di;
- pd[cnt++]=0;
- pd[cnt++]=slaveaddr; // 地址
- pd[cnt++]=pt->ykcmd; // 命令码
- if(pt->cmd_dinum>1) pd[cnt++]=(BYTE)(di>>8);
- pd[cnt++]=(BYTE)(di);
- for(i=0;i<num;i++)
- {
- pd[cnt++]=*pdat++;
- }
- crc=Modbus_CRC16(&pd[1],cnt-1);
- pd[cnt++]=(BYTE)(crc>>8);
- pd[cnt++]=(BYTE)(crc);
- pd[0]=cnt-1;
- modbus_send(pt);
- }
- void modbus_slave_yk(u8 ch,u8 ti,u8 cot,u8 v,u16 cp ,u8 yktype)
- {
- LINK_TABLE * lt;
- struct do_table *dt;
- LINKYK_DEF *yk;
- char buf[128];
-
- // 查找点表,如果找到,保存。
- lt = tbl_link_do(ch,cp);
- if(lt)
- {
- dt = &g_do_table[lt->tbl_index];
- yk = &g_lnk_yk[dt->owner];
- if(cp != yk->cp_s)
- {
- rt_printf_time("lnk_slave_yk err:cp=%04x,cp_s=%04x",cp,yk->cp_s);
- return;
- }
- if((cot&0x3f)==IEC_COT_ACT)
- {
- cot=IEC_COT_ACTCON|(cot&0xc0);
- }
- else if((cot&0x3f)==IEC_COT_DEACT)
- {
- cot=IEC_COT_DEACTCON|(cot&0xc0);
- }
-
- yk->data[yktype].ti=ti;
- yk->data[yktype].cot=cot;
- yk->data[yktype].v=v;
- yk->flag[yktype] = true;
-
- sprintf(buf,"级联遥控上行:(ch=%d,cp_s=%04x,cp_m=%04x,ti=%02x,cot=%02x,v=%02x)",ch,lt->cp_s,dt->cp,ti,cot,v);
- log_str_time(LOG_OPERATE,buf,0,0);
- rt_printf_time("%s\r\n",buf);
- }
- else
- {
- rt_printf_time("lnk_slave_yk:查找级联表失败 ch=%d,cp=%04x.\r\n",ch,cp);
- }
-
- }
- /**************************************************************************
- 函数名称:Modbus_Applay
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:Modbus规约应用数据处理
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_Applay(MODBUS_DEF *pt)
- {
- BYTE *pd;
- WORD crc,crc1;
- BYTE cmd;
- int len;
- if(!pt->bData)return;
-
- cmd=pt->recvbuf[1];
- len=get_cmd_len(cmd);
- if(len==0) //带字节数的报文 如 1 2 3 4
- {
- len=pt->recvbuf[2]+1; // 含字节数本身
- pd=&pt->recvbuf[3]; // 数据
- }
- else if(len>0) // 不带字节数的报文,如 5 0x0f 0x10等
- {
- pd=&pt->recvbuf[2]; // 数据
- }
- else
- {
- pt->bData=false;
- return;
- }
- if(g_print_lnk && (g_print_port & (1<<pt->chnl)))
- {
- print_msg("RX_MODBUS:",pt->recvbuf,(len+4));
- }
- crc=(WORD)(pt->recvbuf[len+2]<<8)+pt->recvbuf[len+3];
- crc1=Modbus_CRC16(&pt->recvbuf[0],len+2);
- if(crc==crc1) //crc校验通过,若不通过,不应答
- {
- MODBUS_CMD_DEF *pcmd;
- pcmd=&pt->tcmd[pt->bCurrent];
- if(cmd==pcmd->cmd)
- {
- int i;
- u16 ch,cp;
- LINK_TABLE * lt;
- ch=((pt->chnl+2)<<5)+pcmd->slaveaddr;
- switch(pcmd->type) // 判断命令码
- {
- case MODBUS_TYPE_YX: //
- {
- WORD dat;
- //struct di_table *dt;
- if(pcmd->readbit==1) // 按位取遥信
- {
- int bytenum=1;
- if(pcmd->bitbytes==2)
- {
- bytenum=2;
- }
- for(i=0;i<len/bytenum;i++)
- {
- int j,k=8;
- if(bytenum==2) // 按字读
- {
- if(!pt->dat_dir)
- {
- dat=(pd[0]<<8) | (pd[1]<<0);
- }
- else
- {
- dat=(pd[1]<<8) | (pd[0]<<0);
- }
- pd+=2;
- k=16;
- }
- else
- {
- dat=*pd++;
- }
-
- for(j=0;j<k;j++) //刷新遥信
- {
-
- //cp=(((pcmd->di+i)<<4)|j); // 将bit 位加入点号中
-
- #ifdef LINK_MODBUS_YX_CP
- cp=(pcmd->di+(k*i))+j;
- #else
- cp=((pcmd->di<<4)+(k*i))+j; // 将bit 位加入点号中
- #endif
-
- lt = tbl_link_di(ch,cp);
-
- if(lt)
- {
- int cpv,v;
- //dt = &g_di_table[lt->tbl_index];
- cpv=sw_di_get(lt->owner,lt->indexno);
- v=((dat>>j)&0x01)+1;
- sw_di_set(lt->owner,lt->indexno,v); //转为双点保存
- if(cpv>=0&&pcmd->byxfirst) // 遥信已初始化过,产生soe
- {
- //rt_printf("%s:i=%d,j=%d,cp=%04x,lt->cp=%04x,cpv=%d,v=%d,dat=%x\r\n",__func__,i,j,cp,lt->cp,cpv,v,dat);
- if(v!=cpv)
- {
- struct timespec ts;
- clk_time_get(&ts);
- v = lt->is_inverse ? ((~v)&0x03) : v;
- soe_record_lnk(lt->cp ,v,&ts,(s32)lt,lt->is_mix,lt->cp_s);
- }
- }
- }
- }
- }
- }
- else // 按字节取遥信
- {
- for(i=0;i<len;i++)
- {
- dat=*pd++;
- cp=pcmd->di+i; // 将bit 位加入点号中
- lt = tbl_link_di(ch,cp);
- if(lt)
- {
- int cpv,v;
- //dt = &g_di_table[lt->tbl_index];
- cpv=sw_di_get(lt->owner,lt->indexno);
- v=dat+1;
- sw_di_set(lt->owner,lt->indexno,v);
- if(cpv>=0&&pcmd->byxfirst) // 遥信已初始化过,产生soe
- {
- if(v!=cpv)
- {
- struct timespec ts;
- clk_time_get(&ts);
- v = lt->is_inverse ? ((~v)&0x03) : v;
- soe_record_lnk(lt->cp ,v,&ts,(s32)lt,lt->is_mix,lt->cp_s);
- }
- }
- }
-
- }
- }
- pcmd->byxfirst=true;
- }
- break;
- case MODBUS_TYPE_YC: //
- case MODBUS_TYPE_DD: //
- {
- BYTE num;
- struct ac_table *at;
- struct dd_table *dt;
- qs16 v;
- float fv;
- if(pcmd->bitbytes==13||pcmd->bitbytes==4) //浮点
- {
- num=len/4;
- }
- else // 整形 2字节
- {
- num=len/2;
- }
- for(i=0;i<num;i++)
- {
- if(pcmd->bitbytes==13)
- {
- union{
- float ff;
- u8 tt[4];
- }ff;
-
- // 浮点
- if(!pt->dat_dir)
- {
- #ifdef MODE_LITTLE_ENDIAN
- ff.tt[3]=*pd++;
- ff.tt[2]=*pd++;
- ff.tt[1]=*pd++;
- ff.tt[0]=*pd++;
- #else
- ff.tt[0]=*pd++;
- ff.tt[1]=*pd++;
- ff.tt[2]=*pd++;
- ff.tt[3]=*pd++;
- #endif
- }
- else
- {
- pd += CopySwap(ff.tt,pd,4,false);
- }
- fv = ff.ff;
- v=fv;
- }
- else if(pcmd->bitbytes==4)
- {
- if(!pt->dat_dir)
- {
- v = (pd[0]<<24) | (pd[1]<<16) |(pd[2]<<8) | (pd[3]<<0); // 高字节在前
- }
- else
- {
- v = (pd[3]<<24) | (pd[2]<<16) |(pd[1]<<8) | (pd[0]<<0); // 高字节在前
- }
- pd += 4;
- fv=v;
- }
- else
- {
- if(!pt->dat_dir)
- {
- v = (pd[0]<<8) | (pd[1]<<0);
- }
- else
- {
- v = (pd[1]<<8) | (pd[0]<<0);
- }
- pd += 2;
- fv=v;
- }
- cp=pcmd->di+i;
-
- if(pcmd->type==MODBUS_TYPE_YC)
- {
- int divbase=pt->yc_rate;
- if(divbase==0)divbase=1;
- v*=(Q16_BASE/divbase);
- lt = tbl_link_ac(ch,cp);
- if(lt)
- {
-
- at = &g_ac_table[lt->tbl_index];
- if(at->owner == 0)
- {
- g_sw_pub.ac_in[at->indexno-1] = v;
- }
- else
- {
- g_sw[at->owner-1].ac_in[at->indexno-1] = v;
- }
- }
- }
- else
- {
- lt = tbl_link_dd(ch,cp);
- if(lt)
- {
- dt = &g_dd_table[lt->tbl_index];
- if(dt->owner >0)
- {
- g_sw[dt->owner-1].dd[dt->indexno-1].fv= fv;
- g_sw[dt->owner-1].dd[dt->indexno-1].bchanged= 0;
- }
- }
- }
- }
- }
-
- break;
- default:break;
-
- }
- }
- else if(cmd==pt->ykcmd) // 遥控应答
- {
- LINKYK_DEF *yk;
- yk = &g_lnk_yk[pt->yksendindex];
- modbus_slave_yk(yk->chnl,yk->data[IECLINK_YK_SND].ti,7,yk->data[IECLINK_YK_SND].v,yk->cp_s,IECLINK_YK_ACK);
- modbus_slave_yk(yk->chnl,yk->data[IECLINK_YK_SND].ti,10,yk->data[IECLINK_YK_SND].v,yk->cp_s,IECLINK_YK_END);
- }
- pt->bRecvOk=true;
- pt->dsendtime=dTCounter;
- }
- else
- {
- rt_printf("\r\n modbus 接收报文crc校验错误 !\r\n");
- }
- pt->bData=false;
- modbus_recv_rst(pt);
- }
- /**************************************************************************
- 函数名称:Modbus_AutoTime
- 函数版本:1.00
- 作者:
- 创建日期:2008.11.15
- 函数功能说明:Modbus规约定时处理函数,主要是超时处理
- 输入参数:
- 输出参数:
- 返回值:
- 更新信息:
- 更新日志1:
- 日期:
- 修改者:
- 修改内容:
- 修改原因:
- ***************************************************************************/
- void modbus_AutoTimer(MODBUS_DEF *pt)
- {
- if((dTCounter-pt->dsendtime>pt->retrytime)||(pt->bRecvOk&&(dTCounter-pt->dsendtime>pt->sendinteraltime)))// 超时处理或接收到报文后延时sendinteraltime
- {
- pt->dsendtime=dTCounter;
- pt->bRecvOk=false;
- // 遥控
- if(pt->yk_send_flag)
- {
- int i;
- for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
- {
- if(pt->yk_send_flag & (1<<i))
- {
- u16 val;
- u8 v,cot,ti,dat[8];
- LINKYK_DEF *yk = &g_lnk_yk[i];
- v=yk->data[IECLINK_YK_SND].v;
- cot=yk->data[IECLINK_YK_SND].cot;
- ti=yk->data[IECLINK_YK_SND].ti;
- if(v&0x80) // 遥控选择,遥控撤销,直接回复应答
- {
- if(pt->tyk.yk_st!= YK_STATUS_NONE && pt->tyk.yk_st!= YK_STATUS_TIMEOUT)
- {
- //已经有遥控命令选择或在执行
- cot|=IEC_COT_PN;
- memset(&pt->tyk,0,sizeof(REMOTEYKSTATUS));
- }
- else
- {
- // 记录选择动作
- pt->tyk.yk_st=YK_STATUS_SEL;
- pt->tyk.no=ti;
- pt->tyk.val=(v&0x3f);
- pt->tyk.wMaster=yk->cp_s;
- pt->tyk.dTStart=dTCounter;
- }
- modbus_slave_yk(yk->chnl,ti,cot,v,yk->cp_s,IECLINK_YK_ACK);
- pt->bRecvOk=true;
-
- }
- else if(cot==IEC_COT_DEACT) // 遥控选择,遥控撤销,直接回复应答
- {
- if(pt->tyk.yk_st!= YK_STATUS_SEL)
- {
- cot|=IEC_COT_PN;
- }
- modbus_slave_yk(yk->chnl,ti,cot,v,yk->cp_s,IECLINK_YK_ACK);
- pt->bRecvOk=true;
- memset(&pt->tyk,0,sizeof(REMOTEYKSTATUS));
- }
- else // 遥控执行
- {
- if((ti != 0xff)
- && ((pt->tyk.yk_st!= YK_STATUS_SEL) // 和遥控选择的数据不对应
- ||(v !=pt->tyk.val)
- ||(yk->cp_s !=pt->tyk.wMaster)
- ||(ti != pt->tyk.no)))
-
- {
- cot|=IEC_COT_PN;
- modbus_slave_yk(yk->chnl,ti,cot,v,yk->cp_s,IECLINK_YK_ACK);
- pt->bRecvOk=true;
- }
- else
- {
- u8 num=0;
- pt->tyk.yk_st=YK_STATUS_EXE;
- pt->tyk.dTStart=dTCounter;
- if(ti==45)v+=1; // 单点转为双点 2=合 1=分
- if(v==2) //遥控合
- {
- val=pt->ykval_h;
- }
- else
- {
- val=pt->ykval_f;
- }
- if(pt->ykcmd==0x0f||pt->ykcmd==0x10) // 0F和10命令,需增加线圈地址
- {
- dat[0]=(u8)(pt->coiladdr>>8);
- dat[1]=(u8)(pt->coiladdr);
- dat[2]=pt->ykbitbytes; //个数
- dat[3]=(u8)(val>>8);
- dat[4]=(u8)(val>>0);
- num=pt->ykbitbytes+3;
- }
- else
- {
- dat[0]=(u8)(val>>8);
- dat[1]=(u8)(val>>0);
- num=pt->ykbitbytes;
- }
- #ifdef LINK_MODBUS_YK_MERGE
- if(v==2) //遥控合
- {
- modbus_write(pt,(yk->chnl&0x1f),yk->cp_s+1,num,dat);
- }
- else
- {
- modbus_write(pt,(yk->chnl&0x1f),yk->cp_s,num,dat);
- }
- #else
- modbus_write(pt,(yk->chnl&0x1f),yk->cp_s,num,dat);
- #endif
-
- pt->yksendindex=i; //保存发送 g_lnk_yk 索引
- }
- memset(&pt->tyk,0,sizeof(REMOTEYKSTATUS));
- }
- // 清除标志
- g_lnk_yk[i].flag[IECLINK_YK_SND]=false;
- pt->yk_send_flag &= ~(1<<i);
- }
- }
- }
- else if(pt->cmdnum>0)
- {
- pt->bCurrent++;
- if(pt->bCurrent>=pt->cmdnum)pt->bCurrent=0;
- modbus_read(pt,pt->bCurrent);
- }
- }
- if(pt->tyk.yk_st==YK_STATUS_SEL)
- {
- if(dTCounter- pt->tyk.dTStart>=tRunPara.dYKTime)//遥控选择超时
- {
- memset(&pt->tyk,0,sizeof(REMOTEYKSTATUS));
- // 置遥控超时状态,方便用户查看
- pt->tyk.yk_st = YK_STATUS_TIMEOUT;
- }
- }
-
- }
- /**************************endfile****************************************/
|