线圈的访问属性为读写

对线圈的操作包括:读线圈(0x01)、写单个线圈(0x05)、写多个线圈(0x0F)

读线圈(0x01)

在一个远程设备中,使用该功能码读取线圈的1 至2000 连续状态。请求PDU 详细说明了起始地址,即指定的第一个线圈地址和线圈编号。从零开始寻址线圈。因此寻址线圈1-16 为0-15。根据数据域的每个比特将响应报文中的线圈分成为一个线圈。指示状态为1= ON 和0= OFF。第一个数据字节的LSB(最低有效位)包括在询问中寻址的输出。其它线圈依次类推,一直到这个字节的高位端为止,并在后续字节中从低位到高位的顺序。

如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余比特(一直到字节的高位端)。字节数量域说明了数据的完整字节数。

读线圈状态图

/* 读线圈 */
eMBException eMBFuncReadCoils(UCHAR *pucFrame, USHORT *usLen)
{USHORT usRegAddress;USHORT usCoilCount;UCHAR ucNBytes;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++;/* 线圈数量 */usCoilCount = (USHORT)(pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8);usCoilCount |= (USHORT)(pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1]);/* 检查线圈数量是否合理 */if((usCoilCount >= 1) &&(usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX)){/* 构建响应 *//* PDU指针 */pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];/* PDU长度初始化为0 */*usLen = MB_PDU_FUNC_OFF;/* 功能码 */*pucFrameCur++ = MB_FUNC_READ_COILS;*usLen += 1;/* 字节数 */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);/* 产生异常 */if(eRegStatus != MB_ENOERR){/* 错误转化为异常码 */eStatus = prveMBError2Exception(eRegStatus);}/* 未产生异常 */else{/* 数据长度 */*usLen += ucNBytes;;}}/* 线圈数量不合理 */else{/* 非法数据值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU长度不对 */else{/* 非法数据值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus;
}

写单个线圈(0x05)

在一个远程设备上,使用该功能码写单个输出为ON 或OFF。请求数据域中的常量说明请求的ON/OFF状态。十六进制值FF 00请求输出为ON。十六进制值00 00 请求输出为OFF。其它所有值均是非法的,并且对输出不起作用。请求PDU说明了强制的线圈地址。从零开始寻址线圈。因此,寻址线圈1 为0。线圈值域的常量说明请求的ON/OFF 状态。十六进制值0XFF00请求线圈为ON。十六进制值0X0000请求线圈为OFF。其它所有值均为非法的,并且对线圈不起作用。

正常响应是请求的应答,在写入线圈状态之后返回这个正常响应。

写单个线圈状态图

/* 写单个线圈 */
eMBException eMBFuncWriteCoil(UCHAR *pucFrame, USHORT *usLen)
{USHORT usRegAddress;UCHAR ucBuf[2];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++;/* 判断值是否合法,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转换为位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);/* 产生异常 */if(eRegStatus != MB_ENOERR){/* 错误转化为异常码 */eStatus = prveMBError2Exception(eRegStatus);}}/* 状态值错误 */else{/* 非法数据值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU长度不对 */else{/* 非法数据值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus;
}

写多个线圈(0x0F)

在一个远程设备中,使用该功能码强制线圈序列中的每个线圈为ON 或OFF。请求PDU说明了强制的线圈参考。从零开始寻址线圈。因此,寻址线圈1 为0。请求数据域的内容说明了被请求的ON/OFF 状态。域比特位置中的逻辑“1”请求相应输出为ON。域比特位置中的逻辑“0”请求相应输出为OFF。

正常响应返回功能码、起始地址和强制的线圈数量。

写多个线圈状态图

/* 写多个线圈 */
eMBException eMBFuncWriteMultipleCoils(UCHAR *pucFrame, USHORT *usLen)
{USHORT usRegAddress;USHORT usCoilCnt;UCHAR ucByteCount;UCHAR ucByteCountVerify;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_MUL_ADDR_OFF] << 8);usRegAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1]);/* 第1个线圈寻址为0,所以地址加一 */usRegAddress++;/* 线圈数量 */usCoilCnt = (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8);usCoilCnt |= (USHORT)(pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1]);/* 字节数 */ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];/* 计算字节数 */if((usCoilCnt & 0x0007) != 0){ucByteCountVerify = (UCHAR)(usCoilCnt / 8 + 1);}else{ucByteCountVerify = (UCHAR)(usCoilCnt / 8);}/* 检查线圈数量和字节数是否合理 */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);/* 产生异常 */if(eRegStatus != MB_ENOERR){/* 错误转化为异常码 */eStatus = prveMBError2Exception(eRegStatus);}/* 未产生异常 */else{/* 数据长度 */*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;}}/* 线圈数量或字节数不合理 */else{/* 非法数据值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}}/* PDU长度不对 */else{/* 非法数据值 */eStatus = MB_EX_ILLEGAL_DATA_VALUE;}return eStatus;
}

FreeModbus线圈相关推荐

  1. freemodbus线圈中的位操作

    连续位的操作函数: xMBUtilSetBits(UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHAR ucValue): xMBUti ...

  2. Freemodbus 1.5

    源:http://blog.sina.com.cn/s/blog_4935209001012eax.html 网站位置:http://www.freemodbus.org/index.php?lang ...

  3. STM32F103/107 移植Freemodbus RTU

    1.简介 FreeMODBUS一个奥地利人写的Modbus协议.它是一个针对嵌入式应用的一个免费(自由)的通用MODBUS协议的移植.Modbus是一个工业制造环境中应用的一个通用协议.Modbus通 ...

  4. uip+freemodbus网络通信

    前言: TCP/IP协议通过uip协议栈来实现,应用层的modbus协议使用freemodbus来实现,另外还需要一个网卡(笔者使用的是KSZ8851网卡控制器)来实现底层的数据传输(包括物理层.数据 ...

  5. FreeModbus V1.6 主机

    FreeModbus是一款开源的Modbus协议栈,但是只有从机开源,主机源码是需要收费的.同时网上也没有发现比较好的开源的Modbus主机协议栈,所以才开发这款支持主机模式的FreeModbus协议 ...

  6. STM32 移植FreeModbus详细过程

    modbus是一个非常好的串口协议(当然也能用在网口上),它简洁.规范.强大.可以满足大部分的工业.嵌入式需求.我写的这个四个寄存器都可以用(输入寄存器.保持寄存器.线圈寄存器.离散寄存器).不像别的 ...

  7. FreeModbus源码详解

    本篇按照FreeModbus协议栈的工作流程,对源代码进行总结解析:FreeModbus协议栈作为从机,等待主机传送的数据,当从机接收到一帧完整的报文后,对报文进行解析,然后响应主机,发送报文给主机, ...

  8. freemodbus移植

    freemodbus下载地址:GitHub - cwalter-at/freemodbus: BSD licensed MODBUS RTU/ASCII and TCP slave freemodbu ...

  9. FreeModbus 移植笔记- 1-认识FreeModbus

    FreeModbus 移植笔记 目录 1 FreeMODBUS介绍 2 FreeMODBUS官网及源码下载地址 3 移植之前的准备 3.1 FreeModbus V1.6 ​​​​​​​3.2 Mod ...

最新文章

  1. NutzCodeInsight 2.0.7 发布,为 nutz-sqltpl 提供友好的 ide 支持
  2. 网站外链发布的细节注意事项!
  3. 2057. [ZLXOI2015]殉国
  4. python-IO多路复用,select模块
  5. python 坐标轴刻度_给妹子讲python-S02E08坐标轴与主次刻度
  6. 怀孕参加计算机考试有辐射吗,电脑辐射对孕妇的影响大不大 会对胎儿造成什么影响...
  7. C++调用Matlab 注意事项
  8. 15原型模式(Prototype)
  9. postgresql中装gis插件_PostgreSQL插件PostGIS安装
  10. jQuery实现多条件筛选
  11. STM32工作笔记0012---认识老化试验
  12. mysql中的union用法以及子查询综合应用
  13. WEB前端使用SheetJS读写excel文件
  14. 51单片机实现简单计算器
  15. 动手学深度学习pytorch入门
  16. mysql2014汉化版_SQLServer2014企业版下载
  17. 智商太低,竟然算不出病狗神题了
  18. BTN7971电机驱动
  19. Docker学习之docker重启参数--restart=always的作用
  20. PHP上传用户头像及头像的缩略图

热门文章

  1. Qt文档阅读笔记-TextEdit QML Type官方解析及实例
  2. C++ STL string修改
  3. WEB安全基础-WEB服务器相关知识
  4. 5.6m元多项式的表示
  5. java8的时间工具类_JAVA8日期工具类
  6. JS判断视频Video的播放、暂停、结束完成及获取长度事件监听处理
  7. 更新widget 导致widget host(home) 挂掉
  8. QT 线程池 + TCP 小试(一)线程池的简单实现
  9. C/C++ 线程三种并发方式比较(传统互斥量加锁方式, no lock不加锁的方式, 原子函数方式)
  10. 优先队列实现迪杰特斯拉模板