FreeModbus线圈
線圈的訪問屬性為讀寫
對(duì)線圈的操作包括:讀線圈(0x01)、寫單個(gè)線圈(0x05)、寫多個(gè)線圈(0x0F)
?
讀線圈(0x01)
在一個(gè)遠(yuǎn)程設(shè)備中,使用該功能碼讀取線圈的1 至2000 連續(xù)狀態(tài)。請(qǐng)求PDU 詳細(xì)說明了起始地址,即指定的第一個(gè)線圈地址和線圈編號(hào)。從零開始尋址線圈。因此尋址線圈1-16 為0-15。根據(jù)數(shù)據(jù)域的每個(gè)比特將響應(yīng)報(bào)文中的線圈分成為一個(gè)線圈。指示狀態(tài)為1= ON 和0= OFF。第一個(gè)數(shù)據(jù)字節(jié)的LSB(最低有效位)包括在詢問中尋址的輸出。其它線圈依次類推,一直到這個(gè)字節(jié)的高位端為止,并在后續(xù)字節(jié)中從低位到高位的順序。
如果返回的輸出數(shù)量不是八的倍數(shù),將用零填充最后數(shù)據(jù)字節(jié)中的剩余比特(一直到字節(jié)的高位端)。字節(jié)數(shù)量域說明了數(shù)據(jù)的完整字節(jié)數(shù)。
讀線圈狀態(tài)圖
/* 讀線圈 */ eMBException eMBFuncReadCoils(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegAddress;USHORT usCoilCount;UCHAR ucNBytes;UCHAR *pucFrameCur;eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗(yàn)PDU長(zhǎng)度是否合理 */if(*usLen == (MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN)){/* 線圈地址 */usRegAddress = (USHORT)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8);usRegAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1]);/* 第1個(gè)線圈尋址為0,所以地址加一 */usRegAddress++;/* 線圈數(shù)量 */usCoilCount = (USHORT)(pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8);usCoilCount |= (USHORT)(pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1]);/* 檢查線圈數(shù)量是否合理 */if((usCoilCount >= 1) &&(usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX)){/* 構(gòu)建響應(yīng) *//* PDU指針 */pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];/* PDU長(zhǎng)度初始化為0 */*usLen = MB_PDU_FUNC_OFF;/* 功能碼 */*pucFrameCur++ = MB_FUNC_READ_COILS;*usLen += 1;/* 字節(jié)數(shù) */if((usCoilCount & 0x0007) != 0){ucNBytes = (UCHAR)(usCoilCount / 8 + 1);}else{ucNBytes = (UCHAR)(usCoilCount / 8);}*pucFrameCur++ = ucNBytes;*usLen += 1;/* 讀取線圈值 */eRegStatus = eMBRegCoilsCB(pucFrameCur, usRegAddress, usCoilCount, MB_REG_READ);/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯(cuò)誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}/* 未產(chǎn)生異常 */else{/* 數(shù)據(jù)長(zhǎng)度 */*usLen += ucNBytes;;}}/* 線圈數(shù)量不合理 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU長(zhǎng)度不對(duì) */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus; }?
寫單個(gè)線圈(0x05)
在一個(gè)遠(yuǎn)程設(shè)備上,使用該功能碼寫單個(gè)輸出為ON 或OFF。請(qǐng)求數(shù)據(jù)域中的常量說明請(qǐng)求的ON/OFF狀態(tài)。十六進(jìn)制值FF 00請(qǐng)求輸出為ON。十六進(jìn)制值00 00 請(qǐng)求輸出為OFF。其它所有值均是非法的,并且對(duì)輸出不起作用。請(qǐng)求PDU說明了強(qiáng)制的線圈地址。從零開始尋址線圈。因此,尋址線圈1 為0。線圈值域的常量說明請(qǐng)求的ON/OFF 狀態(tài)。十六進(jìn)制值0XFF00請(qǐng)求線圈為ON。十六進(jìn)制值0X0000請(qǐng)求線圈為OFF。其它所有值均為非法的,并且對(duì)線圈不起作用。
正常響應(yīng)是請(qǐng)求的應(yīng)答,在寫入線圈狀態(tài)之后返回這個(gè)正常響應(yīng)。
寫單個(gè)線圈狀態(tài)圖
/* 寫單個(gè)線圈 */ eMBException eMBFuncWriteCoil(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegAddress;UCHAR ucBuf[2];eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗(yàn)PDU長(zhǎng)度是否合理 */if(*usLen == (MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN)){/* 線圈地址 */usRegAddress = (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8);usRegAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1]);/* 第1個(gè)線圈尋址為0,所以地址加一 */usRegAddress++;/* 判斷值是否合法,ON:0xFF00 OFF:0x0000 */if((pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00) &&((pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF) ||(pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00))){/* 將ON/OFF轉(zhuǎn)換為位1/0 */ucBuf[1] = 0;if(pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF){ucBuf[0] = 1;}else{ucBuf[0] = 0;}/* 寫入線圈值 */eRegStatus = eMBRegCoilsCB(&ucBuf[0], usRegAddress, 1, MB_REG_WRITE);/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯(cuò)誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}}/* 狀態(tài)值錯(cuò)誤 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU長(zhǎng)度不對(duì) */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus; }?
寫多個(gè)線圈(0x0F)
在一個(gè)遠(yuǎn)程設(shè)備中,使用該功能碼強(qiáng)制線圈序列中的每個(gè)線圈為ON 或OFF。請(qǐng)求PDU說明了強(qiáng)制的線圈參考。從零開始尋址線圈。因此,尋址線圈1 為0。請(qǐng)求數(shù)據(jù)域的內(nèi)容說明了被請(qǐng)求的ON/OFF 狀態(tài)。域比特位置中的邏輯“1”請(qǐng)求相應(yīng)輸出為ON。域比特位置中的邏輯“0”請(qǐng)求相應(yīng)輸出為OFF。
正常響應(yīng)返回功能碼、起始地址和強(qiáng)制的線圈數(shù)量。
寫多個(gè)線圈狀態(tài)圖
/* 寫多個(gè)線圈 */ eMBException eMBFuncWriteMultipleCoils(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegAddress;USHORT usCoilCnt;UCHAR ucByteCount;UCHAR ucByteCountVerify;eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗(yàn)PDU長(zhǎng)度是否合理 */if(*usLen > (MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN)){/* 線圈地址 */usRegAddress = (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8);usRegAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1]);/* 第1個(gè)線圈尋址為0,所以地址加一 */usRegAddress++;/* 線圈數(shù)量 */usCoilCnt = (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8);usCoilCnt |= (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1]);/* 字節(jié)數(shù) */ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];/* 計(jì)算字節(jié)數(shù) */if((usCoilCnt & 0x0007) != 0){ucByteCountVerify = (UCHAR)(usCoilCnt / 8 + 1);}else{ucByteCountVerify = (UCHAR)(usCoilCnt / 8);}/* 檢查線圈數(shù)量和字節(jié)數(shù)是否合理 */if((usCoilCnt >= 1) &&(usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX) &&(ucByteCountVerify == ucByteCount)){/* 寫入線圈值 */eRegStatus = eMBRegCoilsCB(&pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],usRegAddress, usCoilCnt, MB_REG_WRITE);/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯(cuò)誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}/* 未產(chǎn)生異常 */else{/* 數(shù)據(jù)長(zhǎng)度 */*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;}}/* 線圈數(shù)量或字節(jié)數(shù)不合理 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU長(zhǎng)度不對(duì) */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus; }?
總結(jié)
以上是生活随笔為你收集整理的FreeModbus线圈的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不懂这37个数据中心术语,怎么混数据圈饭
- 下一篇: 北上广年终奖地图