Mfc 通过Visual C+中的MSComm输入Modbus+;

Mfc 通过Visual C+中的MSComm输入Modbus+;,mfc,serial-port,modbus,mscomm32,Mfc,Serial Port,Modbus,Mscomm32,我对Modbus协议一无所知。 我的设置由三个具有不同地址的设备组成。它们都通过RS232与COM1相连。我使用Modbus Poll检查输入数据,工作正常。我现在要做的是读取vc++(MFC)应用程序中的保持寄存器。对于串行通信,我使用MSComm类。我已经写了一点代码,但根本没有输入 我现在的代码是: BOOL Crs232test4Dlg::OpenConnection () { char error [513]; try { if (! m_MS

我对Modbus协议一无所知。 我的设置由三个具有不同地址的设备组成。它们都通过RS232与COM1相连。我使用Modbus Poll检查输入数据,工作正常。我现在要做的是读取vc++(MFC)应用程序中的保持寄存器。对于串行通信,我使用MSComm类。我已经写了一点代码,但根本没有输入

我现在的代码是:

BOOL Crs232test4Dlg::OpenConnection ()
{
    char error [513];

    try
    {
        if (! m_MSComm.GetPortOpen ())
        {
            m_MSComm.SetCommPort (1);
            m_MSComm.SetSettings ("9600,N,8,1");
            m_MSComm.SetInputLen (4);
            // Receive Data as Text
            m_MSComm.SetInputMode (0);
            m_MSComm.SetPortOpen (true);
            m_MSComm.SetCommID (1);
           return m_MSComm.GetPortOpen ();
        }
        AfxMessageBox ("Success!!!!", MB_OK);
        return TRUE;
    }

    catch (CException *e)
    {
        e->GetErrorMessage (error, 512);
        AfxMessageBox (error, MB_OK);
        return FALSE;
    }
}


void Crs232test4Dlg::OnVaisalaComm ()
{
    if (m_MSComm.GetCommEvent () == 2)
    {
        COleVariant in_dat;
        in_dat = m_MSComm.GetInput ();
        Sleep (100);
        CString strInput (in_dat.bstrVal);
        m_Input = m_Input + strInput;
        UpdateData (FALSE);
    }
}
我现在想输出m_输入,但一点也没变。设置SetCommID时,我也会收到警告(属性是只读的),我认为这并不重要

有谁能给我指点路,因为我现在真的不知道

问候


编辑:根据一个通信示例,我尝试像处理文件一样处理设备

m_hCom = CreateFile(m_sComPort, 
        GENERIC_READ | GENERIC_WRITE,
        0, // exclusive access
        NULL, // no security
        OPEN_EXISTING,
        0, // no overlapped I/O
        NULL); // null template
// :(colon) Address=1 Function=3 Starting register= 40001 (To write 400001 or 0?)
Registers to read=4 checksum CR LF
char    strASCII[] = "3A 30 31 30 33 30 30 30 30 30 30 30 34 46 38 0D 0A";

bWriteRC = WriteFile (m_hCom, strASCII, strlen(strASCII), &iBytesWritten, NULL);

memset(sBuffer,0,sizeof(sBuffer));
// Reading output of the M3
bReadRC = ReadFile (m_hCom, &sBuffer, 1, &iBytesRead, NULL);

if (bReadRC && iBytesRead > 0)
    {
        sResult = sBuffer;
    }
    else
    {
        sResult = "Read Failed";
        dwError = GetLastError();

        sprintf(sMsg, "Read length failed: RC=%d Bytes read=%d, "
                "Error=%d ",
                bReadRC, iBytesRead, dwError);
        AfxMessageBox(sMsg);
    } 
我得到读取长度失败错误。strASCII通常不会分开,只是为了更好的观察。 我已经检查了Modbus Poll中的通信。我的输出是正确的,但它似乎没有得到数据


编辑:我知道了。非常感谢你的帮助。我输入了错误的校验和。

不是答案,而是解决问题的指南

  • 你最好的朋友应该是:

    1) 零调制解调器232female232female电缆与第二台具有com端口的计算机(或带有usb->串行转换器的笔记本电脑)。。。用你们自己的线对线焊接电缆可能是最好的解决方案

    2) windows hyper terminal在大多数windows上预装了简单但可靠的应用程序。。。在comPort模式下启动,使用与您期望的模块相同的比特率/奇偶校验/停止位参数


  • 首先,在comps和“chat”两个句子上运行hterm,检查连接和电缆是否正常
  • 然后在第一个comp上运行程序,在另一个comp上运行hterm,检查程序是否正常
  • Modbus模块有时在Master发送模块地址查询之前不会发送任何信息,因此您的程序可能需要先发送一些信息(为了进行调查,您可以使用其他连接的comp而不是MBUS模块记录Modbus池)
。。。考虑到windows信令队列和MSCOmm类的所有方面,这可能是正常的,但为了消除项目启动时通信失败的所有可能原因,您可能更喜欢简单地将COM端口作为文件进行威胁,并在一些while循环中从中读取。。。一些简短版本的。。。在启动时设置串行参数并读取名为comX的文件


上面的链接在下载时有很好的cSerialClass实现,但没有任何错误检查的简单入门是。

不是答案,而是故障排查指南

  • 你最好的朋友应该是:

    1) 零调制解调器232female232female电缆与第二台具有com端口的计算机(或带有usb->串行转换器的笔记本电脑)。。。用你们自己的线对线焊接电缆可能是最好的解决方案

    2) windows hyper terminal在大多数windows上预装了简单但可靠的应用程序。。。在comPort模式下启动,使用与您期望的模块相同的比特率/奇偶校验/停止位参数


  • 首先,在comps和“chat”两个句子上运行hterm,检查连接和电缆是否正常
  • 然后在第一个comp上运行程序,在另一个comp上运行hterm,检查程序是否正常
  • Modbus模块有时在Master发送模块地址查询之前不会发送任何信息,因此您的程序可能需要先发送一些信息(为了进行调查,您可以使用其他连接的comp而不是MBUS模块记录Modbus池)
。。。考虑到windows信令队列和MSCOmm类的所有方面,这可能是正常的,但为了消除项目启动时通信失败的所有可能原因,您可能更喜欢简单地将COM端口作为文件进行威胁,并在一些while循环中从中读取。。。一些简短版本的。。。在启动时设置串行参数并读取名为comX的文件

上面的链接在下载时有很好的cSerialClass实现,但没有任何错误检查的简单初级读物是。

这里有两个问题:

1/不能使用RS232将三个设备连接在一起。RS232是点对点的,这意味着只有两个设备可以连接在一起

2/从机仅在主机查询时发送数据。如果主设备没有首先发送MODBUS请求,您将永远无法从从从设备获得回复

PS:我觉得应该在端口打开之前调用m_MSComm.SetCommID(),而不是在端口打开之后

为了创建正确的请求,您可以参考标准:

第一个文档将指导您如何构建请求(PDU),而第二个文档将详细说明如何将请求封装在适合串行通信的“传输”帧(ADU)中

最常见的请求是“读取保持寄存器”(func.#3)。如果您的从设备具有地址5,并且您希望读取从地址10开始的两个寄存器,那么您的请求将类似于: 0x05 0x03 0x000A 0x0002 0x????(其中“??”是CRC16值,我懒得计算它)。

这里有两个问题:

1/不能使用RS232将三个设备连接在一起。RS232是点对点的,这意味着只有两个设备可以连接在一起

2/从机仅在主机查询时发送数据。如果主设备没有首先发送MODBUS请求,您将永远无法从从从设备获得回复

PS:我觉得应该在端口打开之前调用m_MSComm.SetCommID(),而不是在端口打开之后

为了创建正确的请求,您可以参考标准:

第一个文档将指导您如何构建请求(PDU),而第二个文档将详细说明如何将请求封装在适合串行通信的“传输”帧(ADU)中

最常见的请求是“读取保持寄存器”(func.#3)。如果您的sla