Snap7写入S7-1200 PLC

时间:2015-11-25 14:54:36

标签: c++-cli plc s7-1200 siemens

我正在尝试使用C ++ / CLI应用程序向西门子PLC写一些内容。

读取正常(除了第一次读取它给出奇数值)。

但写作正在做一些与我想要的完全不同的事情。

您可以在下面找到代码:

    private: void WriteSiemensDB()
    {
        byte* buffer;

        if (ConnectToSiemensPLC()) //Check if you are connected to PLC
        {
        String^ msg;
        int DBNumber = 2;
        bool NDR;

        //Getting the values 1 time so buffer has a value
        buffer = sPLC->ReadDB(DBNumber);

        //give variables a value to write it to the PLC
        NDR = true;

        sPLC->SetBitAt(buffer, 0, 0, NDR); //Convert a bool to a bit

        msg = sPLC->WriteDB(DBNumber, buffer); //write to the Datablock in Siemens

        MessageBox::Show(msg); //Show if it worked or not
    }
}

sPLC-> SetBitAt方法:

void SiemensPLC::SetBitAt(byte buffer[], int Pos, int Bit, bool Value)
{
    byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    if (Bit < 0) Bit = 0;
    if (Bit > 7) Bit = 7;

    if (Value)
    {
        buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
    }
    else
    {
        buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
    }
}

WriteDB方法:

System::String^ SiemensPLC::WriteDB(int DBnumber, byte buffer[])
{
    int Result;
    String^ msg;
    Result = MyClient->DBWrite(DBnumber, 0, 80, buffer);

    if (Result == 0)
    {
        msg = "Gelukt!"; //success
    }
    else
    {
        msg = "Mislukt, error:" + Result; //failed
    }
    return msg;
}

我实际上得到了消息“Gelukt”,但它仍然写出了rwong值。填写我的buffer会出错。我在使用缓冲区做错了吗?

在C#中我有相同类型的应用程序,但缓冲区是byte buffer[];

我的问题是:

  • C#中的byte* buffer;和C#中的byte buffer[];之间有什么区别?
  • 当我在调试时将鼠标悬停在缓冲区上时,它显示buffer* = 0 ''。这是否意味着它是空的?如果是这样,为什么它仍然会向我的PLC发送随机数?

1 个答案:

答案 0 :(得分:1)

  

C ++中的byte* buffer;和C#中的byte buffer[];之间有什么区别?

假设你有typedef unsigned char byte;

在C ++ / CLI中,byte* buffer;声明了一个buffer变量,它是指向byte的指针。在C#中,您将其写为byte* buffer;上下文中的unsafe。语法是一样的。

在C#中,byte[] buffer;声明了buffer变量,该变量是byte值的托管数组。 C ++ / CLI语法为array<byte> buffer;

请注意byte buffer[N];是本机数组的C ++语法,是同一个东西。那个可以衰减到byte*指针。

看起来您的代码使用了本机内存缓冲区,但如果没有ReadDB的来源,则无法确定这一点。

  

当我在调试时将鼠标悬停在缓冲区上时,它显示buffer* = 0 ''。这是否意味着它是空的?如果是这样,为什么它仍然会向我的PLC发送随机数?

这意味着缓冲区中的第一个字节是0。如果您的缓冲区应该包含C字符串数据,则表示它包含空字符串。

  

我是否在使用缓冲区做错了什么?

最有可能。但我无法确切地说出错误,因为你没有发布ReadDB的来源。

但有几个红旗:

  • 缓冲区大小是多少?您的代码并不知道ReadDB返回的内容,那么您应该如何确保自己不会溢出呢?
  • 谁是缓冲区的拥有者,这意味着:谁应该释放它?它可能存在于堆上,因此您的代码正在泄漏内存。如果它存在于ReadDB堆栈中,则会出现内存损坏问题。无论哪种方式,这段代码都是错误的。