基于modbus通信协议的rs232通信

更新时间:2023-06-25 16:09:32 阅读: 评论:0

一、实现基于Modbus协议RS232点到点通信。要求说明程序实现的功能和设计思想、主要的程序流程图,以及带必要注释的源程序。
注:是PC机对PC机,要求在Windows下编程不得使用通信控件,使用多线程实现通信的收发
一、程序实现功能
本题采用的是pc机的com1口进行通信。首先将com1口收发对接对接。然后定义了串口类和modbus类。类都是一样的,然后在MFC对话框下编写人机交互程序.程序实现基于MODBUS协议的RS232点到点通信,程序具有差错校验和帧丢失重传功能。程序可以自由配置串口通信参数、输入设备地址、功能码和发送数据,显示发送的Modbus帧,显示并解析接收到的Modbus帧,取出应用数据。对异常响应、丢失帧进行重传处理。
二、程序设计思想
基于Modbus协议的串口通信程序,使主站能请求访问其它相联的从站设备,并能回应来自其它设备的请求,以及能侦测错误并记录,从站近地址识别主站发来的消息,决定要产生怎
么的行动,若需要回应,从站还将生成反馈信息,并用Modbus协议发出。
Modbus 通信协议是一种串行的主从通信协议, 网络里仅有一台设备可作为主机( 称Master ) , 其它设备作为从机( 称Slaver ) , 主机不需编号, 从机必须编号。协议定义了主机查询及从机应答的信息帧格式。通信时, 主机首先向从机发出请求信息, 符合相应地址码的从机接收通讯命令, 并除去地址码, 读取信息, 如果没有出错, 则执行相应的任务, 然后把执行结果返送给主机。若从机接收到的校验码与本机计算的不同, 则说明数据在通信过程中出现错误, 从机把这次请求视为无效, 功能代码将被修改以用于指出回应消息是错误的, 同时数据段包含了描述此错误信息的代码。当主机收到这一信息时,会重新发送请求信息。校验方式分为LCR( 传送数据为ASCII 时) 校验或CRC( 传送数据为二进制时) 校验, 这里采用LRC 校验方式。信息传输为异步方式, 并以字节为单位。Modbus 协议可支持ASCII 码或二进制格式的数据传输。ACSII 码方式下每一个字节数据分两个字节传送,二进制方式下用一个字节传送, 为了利于上位机的编程选ACSII 码数据方式。网络上的设备连续监测网络上的信息, 包括静止时间。
ASCII消息帧
起始位
设置地址
功能代码
数据
LRC校验
结束符
1个字符
2个字符
2个字符
N个字符
2个字符
2个字符经济常识
Modbus消息帧,在ASCII模式,Modbus消息帧包括地址域、功能码、数据域以及差错校验域。
地址域,在Modbus串行链路上,地址域只含有从站地址。消息帧的地址域包含两个字符(ASCII)。有效的从站地址是0--247(十进制)。单个从站的地址范围是1--247。主站通过将要联络的从站的地址放入消息中的地址域来选定从站。当从站发送回应消息时,它把自己的地址放入回应的地址域中,以便主站知道是哪一个从站作出回应。地址0是用作广播地址,以使所有的从站都能识别。
功能码域,消息帧中的功能代码域指示从站进行何种操作,包含了两个字符(ASCII)。可能的代码范围是十进制的1--255。当然,这些代码分为公共功能码、用户定义的功能码以及保留功能码。当消息从主站发往从站时,功能代码域将告之从站需要执行哪些动作。例如去读取输入的开关状态,读一组寄存器的数据内容,读从设备的诊断状态,允许调入、记录、校验在从设备中的程序等。当从站回应时,它使用功能代码域来指示是正常响应还是异常响应。对于正常响应,从站的响应功能码与请求功能码相等。对于异常响应,从站的功能代码等于请求功能码的最高位置1。
数据域,Modbus消息帧中的数据域主要是包含了请求和响应参数。主站发给从站消息的数据域包含信息为:从站必须用于执行由功能代码所定义的动作。这包括了读取线圈、离散量输入的起始地址、读取的数量等。如果没有错误发生,从站返回的响应数据域内包含请求的数据,如果有错误发生,则响应数据域内为异常码,告诉主站异常的原因。
方框打钩符号错误检测域,标准Modbus串行链路的安全性有两种错误检测方法,根据传输模式的不同而不同,当传输模式采用ASCII,采用纵向冗余校验方法(LRC)对消息内容计算后,可知错误检测域包含两个ASCII字符,不包括开始的冒号符以及回车换行符。LRC方法是将消息中的8Bit的字节连续累加,丢弃了进位。网络规划设计师
标准的MODBUS串行网络采用两种错误检测方法,奇偶校验对每个字符都可用,帧检测(LRC或CRC)应用于整个消息.它们都是在消息发送前由主设备门产生的,从设备在接收过程中检测每个字符和整个消息帧.
三、程序流程图
1. MODBUS主从站消息查询/响应流程
2.主程序流程图
凉山景点
图1 程序主流程图
程序界面中可以输入串口参数,在“打开串口”按键下,同样配置了默认的串口参数,在“配置串口”按键下,若串口没有打开,程序会先打开串口,再配置参数。
3.接收、发送数据流程
           
图 2 接收线程程序流程图                          图3发送线程程序流程图
4. 串口通信类CSerialPort流程图
图4 串口类线程程序流程图people可数吗
四、源程序
1.串口类的定义(CSerialPort.h
#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__
#define WM_COMM_BREAK_DETECTED        WM_USER+1    // A break was detected on input.
#define WM_COMM_CTS_DETECTED        WM_USER+2    // The CTS (clear-to-nd) signal changed state.
#define WM_COMM_DSR_DETECTED        WM_USER+3    // The DSR (data-t-ready) signal changed state.
#define WM_COMM_ERR_DETECTED        WM_USER+4    // A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
#define WM_COMM_RING_DETECTED        WM_USER+5    // A ring indicator was detected.
#define WM_COMM_RLSD_DETECTED        WM_USER+6    // The RLSD (receive-line-signal-detect) signal changed state.
#define WM_COMM_RXCHAR                WM_USER+7    // A character was received and placed in the input buffer.
#define WM_COMM_RXFLAG_DETECTED        WM_USER+8    // The event character was received and placed in the input buffer. 
#define WM_COMM_TXEMPTY_DETECTED    WM_USER+9    // The last character in the output buffer was nt. 
class CSerialPort
{                                                       
public:
    // contruction and destruction
    CSerialPort();
    virtual        ~CSerialPort();
    // port initialisation                                           
    BOOL        InitPort(CWnd* pPortOwner, UINT portnr = 1, UINT baud = 19200, char parity = 'N', UINT databits = 8, UINT stopsbits = 1, DWORD dwCommEvents = EV_RXCHAR | EV_CTS, UINT nBufferSize = 512);
    // start/stop comm watching
数码单反    BOOL        StartMonitoring();
    BOOL        RestartMonitoring();
    BOOL        StopMonitoring();
    DWORD        GetWriteBufferSize();
    DWORD        GetCommEvents();
    DCB            GetDCB();
    HANDLE                m_hComm;
    void        WriteToPort(char* string);
protected:
    // protected memberfunctions
    void        ProcessErrorMessage(char* ErrorText);
    static UINT    CommThread(LPVOID pParam);
    static void    ReceiveChar(CSerialPort* port, COMSTAT comstat);
    static void    WriteChar(CSerialPort* port);
    // thread
    CWinThread*            m_Thread;
    // synchronisation objects
    CRITICAL_SECTION    m_csCommunicationSync;
    BOOL                m_bThreadAlive;
    // handles
    HANDLE                m_hShutdownEvent;
    HANDLE                m_hWriteEvent;
    HANDLE                m_hEventArray[3];
    // structures
    OVERLAPPED            m_ov;
    COMMTIMEOUTS        m_CommTimeouts;
    DCB                    m_dcb;
    // owner window
    CWnd*                m_pOwner;
    // misc
    UINT                m_nPortNr;
    char*                m_szWriteBuffer;
    DWORD                m_dwCommEvents;
    DWORD                m_nWriteBufferSize;
};
#endif __SERIALPORT_H__
住宅风水方位
2.串口的一些成员函数实现(CSerialPort.cpp
2.1串口线程函数
树莓种植UINT CSerialPort::CommThread(LPVOID pParam)
{
    CSerialPort *port = (CSerialPort*)pParam;

本文发布于:2023-06-25 16:09:32,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1054471.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:功能   地址   消息   程序   信息
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图