FreeModbus保持寄存器
保持寄存器的訪問屬性為讀寫
對保持寄存器的操作包括:讀保持寄存器(0x03)、寫單個保持寄存器(0x06)、寫多個保持寄存器(0x10)、讀寫多個保持寄存器(0x17)
?
讀保持寄存器(0x03)
在一個遠(yuǎn)程設(shè)備中,使用該功能碼讀取保持寄存器連續(xù)塊的內(nèi)容。請求PDU說明了起始寄存器地址和寄存器數(shù)量。從零開始尋址寄存器。因此,尋址寄存器1-16 為0-15。
將響應(yīng)報文中的寄存器數(shù)據(jù)分成每個寄存器有兩字節(jié),在每個字節(jié)中直接地調(diào)整二進(jìn)制內(nèi)容。對于每個寄存器,第一個字節(jié)包括高位比特,并且第二個字節(jié)包括低位比特。
讀保持寄存器狀態(tài)圖
/* 讀保持寄存器 */ eMBException eMBFuncReadHoldingRegister(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegAddress;USHORT usRegCount;UCHAR *pucFrameCur;eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗PDU長度是否合理 */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個寄存器尋址為0,所以地址加一 */usRegAddress++;/* 寄存器數(shù)量 */usRegCount = (USHORT)(pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8);usRegCount = (USHORT)(pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1]);/* 檢查寄存器數(shù)量是否合理 */if((usRegCount >= 1) && (usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX)){/* 構(gòu)建響應(yīng) *//* PDU指針 */pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];/* PDU長度初始化為0 */*usLen = MB_PDU_FUNC_OFF;/* 功能碼 */*pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;*usLen += 1;/* 字節(jié)數(shù) */*pucFrameCur++ = (UCHAR)(usRegCount * 2);*usLen += 1;/* 讀取保持寄存器數(shù)據(jù) */eRegStatus = eMBRegHoldingCB(pucFrameCur, usRegAddress, usRegCount, MB_REG_READ);/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}/* 未產(chǎn)生異常 */else{/* 數(shù)據(jù)長度 */*usLen += usRegCount * 2;}}/* 寄存器數(shù)量不合理 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU長度不對 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus; }?
寫單個保持寄存器(0x06)
在一個遠(yuǎn)程設(shè)備中,使用該功能碼寫單個保持寄存器。請求PDU 說明了被寫入寄存器的地址。從零開始尋址寄存器。因此,尋址寄存器1 為0。
正常響應(yīng)是請求的應(yīng)答,在寫入寄存器內(nèi)容之后返回這個正常響應(yīng)。
寫單個保持寄存器狀態(tài)圖
/* 寫單個保持寄存器 */ eMBException eMBFuncWriteHoldingRegister(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegAddress;eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗PDU長度是否合理 */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個寄存器尋址為0,所以地址加一 */usRegAddress++;/* 讀寫保持寄存器數(shù)據(jù) */eRegStatus = eMBRegHoldingCB(&pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],usRegAddress, 1, MB_REG_WRITE);/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}}/* PDU長度不對 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus; }?
寫多個保持寄存器(0x10)
在一個遠(yuǎn)程設(shè)備中,使用該功能碼寫連續(xù)寄存器塊(1 至約120 個寄存器)。在請求數(shù)據(jù)域中說明了請求寫入的值。每個寄存器將數(shù)據(jù)分成兩字節(jié)。
正常響應(yīng)返回功能碼、起始地址和被寫入寄存器的數(shù)量。
寫多個保持寄存器狀態(tài)圖
/* 寫多個保持寄存器 */ eMBException eMBFuncWriteMultipleHoldingRegister(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegAddress;USHORT usRegCount;UCHAR ucRegByteCount;eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗PDU長度是否合理 */if(*usLen >= (MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + 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個寄存器尋址為0,所以地址加一 */usRegAddress++;/* 寄存器數(shù)量 */usRegCount = (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8);usRegCount |= (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1]);/* 字節(jié)數(shù) */ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];/* 檢查寄存器數(shù)量和字節(jié)數(shù)是否合理 */if((usRegCount >= 1) &&(usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX) &&(ucRegByteCount == (UCHAR)(2 * usRegCount))){/* 寫保持寄存器數(shù)據(jù) */eRegStatus = eMBRegHoldingCB(&pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF], usRegAddress, usRegCount, MB_REG_WRITE);/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}else{/* 數(shù)據(jù)長度 */*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;}}/* 寄存器數(shù)量或字節(jié)數(shù)不合理 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU長度不對 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus; }?
讀寫多個保持寄存器(0x17)
在一個單獨MODBUS 事務(wù)中,這個功能碼實現(xiàn)了一個讀操作和一個寫操作的組合。從零開始尋址保持寄存器。因此,尋址保持寄存器1-16 為0-15。請求說明了起始地址、被讀取的保持寄存器號和起始地址、保持寄存器號以及被寫入的數(shù)據(jù)。在寫數(shù)據(jù)域中,字節(jié)數(shù)說明隨后的字節(jié)號。
正常響應(yīng)包括被讀出的寄存器組的數(shù)據(jù)。在讀數(shù)據(jù)域中,字節(jié)數(shù)域說明隨后的字節(jié)數(shù)量。
讀寫多個保持寄存器狀態(tài)圖
/* 讀寫多個保持寄存器 */ eMBException eMBFuncReadWriteMultipleHoldingRegister(UCHAR *pucFrame, USHORT *usLen) {USHORT usRegReadAddress;USHORT usRegReadCount;USHORT usRegWriteAddress;USHORT usRegWriteCount;UCHAR ucRegWriteByteCount;UCHAR *pucFrameCur;eMBException eStatus = MB_EX_NONE;eMBErrorCode eRegStatus;/* 校驗PDU長度是否合理 */if(*usLen >= (MB_PDU_FUNC_READWRITE_SIZE_MIN + MB_PDU_SIZE_MIN)){/* 讀寄存器地址 */usRegReadAddress = (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] << 8U);usRegReadAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1]);/* 第1個寄存器尋址為0,所以地址加一 */usRegReadAddress++;/* 讀寄存器數(shù)量 */usRegReadCount = (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] << 8U);usRegReadCount |= (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1]);/* 寫寄存器地址 */usRegWriteAddress = (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] << 8U);usRegWriteAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1]);/* 第1個寄存器尋址為0,所以地址加一 */usRegWriteAddress++;/* 寫寄存器數(shù)量 */usRegWriteCount = (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] << 8U);usRegWriteCount |= (USHORT)(pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1]);/* 寫字節(jié)數(shù) */ucRegWriteByteCount = pucFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF];/* 檢查讀、寫寄存器數(shù)量和寫字節(jié)數(shù)是否合理 */if((usRegReadCount >= 1) && (usRegReadCount <= 0x7D) &&(usRegWriteCount >= 1) && (usRegWriteCount <= 0x79) &&((2 * usRegWriteCount) == ucRegWriteByteCount)){/* 寫保持寄存器數(shù)據(jù) */eRegStatus = eMBRegHoldingCB(&pucFrame[MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF],usRegWriteAddress, usRegWriteCount, MB_REG_WRITE);if(eRegStatus == MB_ENOERR){/* 構(gòu)建響應(yīng) *//* PDU指針 */pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];/* PDU長度初始化為0 */*usLen = MB_PDU_FUNC_OFF;/* 功能碼 */*pucFrameCur++ = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;*usLen += 1;/* 字節(jié)數(shù) */*pucFrameCur++ = (UCHAR) (usRegReadCount * 2);*usLen += 1;/* 讀取保持寄存器數(shù)據(jù) */eRegStatus = eMBRegHoldingCB(pucFrameCur, usRegReadAddress, usRegReadCount, MB_REG_READ);/* 未產(chǎn)生異常 */if(eRegStatus == MB_ENOERR){/* 數(shù)據(jù)長度 */*usLen += 2 * usRegReadCount;}}/* 產(chǎn)生異常 */if(eRegStatus != MB_ENOERR){/* 錯誤轉(zhuǎn)化為異常碼 */eStatus = prveMBError2Exception(eRegStatus);}}/* 寄存器數(shù)量或字節(jié)數(shù)不合理 */else{/* 非法數(shù)據(jù)值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}return eStatus; }?
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的FreeModbus保持寄存器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 清华大学张文增教授110页PPT讲专利申
- 下一篇: S5PV210裸机之Nandflash