天天看點

.Net Micro Framework研究—TCP/IP通信

試驗平台:Digi MF開發闆

關于網絡通信方面,Digi提供了兩個程式,一個是TCP Server運作在Digi的開發闆上,一個是TCP Client程式,運作在PC上,通過網絡,上位機很容易控制Digi開發的IO信号。用戶端程式運作後的界面如下:

(圖MF071029004.jpg)

如果僅僅運作一下示例程式,那顯然不過瘾!既然序列槽實作了Modbus Rtu協定,那麼網口就實作Modbus Tcp協定吧,實作的Modbus Tcp協定比我們用序列槽實作Modbus Rtu的指令要多一個,不僅實作了3号指令,也實作了16号指令,這樣我們就可以通過Modbus Tcp讀寫Digi開發闆的資料了。這次我們操作的是Digi開發闆上的5個LED燈。用OutputPort對象去操作。

操作GPIO的相關代碼如下:

//讀GPIO信号

DataBuff[0] = 0;

DataBuff[1] = (byte)((output[0].Read() ? 1 : 0) | (output[1].Read() ? 2 : 0) | (output[2].Read() ? 4 : 0) | (output[3].Read() ? 8 : 0) | (output[4].Read() ? 16 : 0));

//寫GPIO信号

bool[] bFlag = new bool[5];

bFlag[0]=(DataBuff[1] & 0x01)>0 ? true:false;

bFlag[1]=(DataBuff[1] & 0x02)>0 ? true:false;

bFlag[2]=(DataBuff[1] & 0x04)>0 ? true:false;

bFlag[3]=(DataBuff[1] & 0x08)>0 ? true:false;

bFlag[4]=(DataBuff[1] & 0x10)>0 ? true:false;

for (i = 0; i < 5; i++)

{

   output[i].Write(bFlag[i]);

}

網絡操作相關源碼如下:

using System;

using Microsoft.SPOT;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

using Microsoft.SPOT.Hardware;

namespace MFModbusTcp

    public class ModbusTcpSlave

    {

        //MF開發闆 IO燈

        private OutputPort[] output=new OutputPort[5];

        Cpu.Pin[] pin = new Cpu.Pin[5] { (Cpu.Pin)0, (Cpu.Pin)1, (Cpu.Pin)2, (Cpu.Pin)5, (Cpu.Pin)6 };

        private Socket socketServer;

        private Socket s = null;

        //變量緩沖區

        private byte[] m_bytData = new byte[256];

        private byte[] m_InputTCPBuf = new byte[1024];

        private byte[] m_OutputTCPBuf = new byte[1024];

        public byte[] DataBuff = new byte[1024];

        //啟動Modbus Tcp服務

        public void Run()

        {

            //初始化 GPIO

            for (int i = 0; i < 5; i++)

            {

                output[i] = new OutputPort(pin[i], false);

            }

            socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            socketServer.Bind(new IPEndPoint(DottedDecimalToIp(0, 0, 0, 0), 502));

            socketServer.Listen(1);

            Debug.Print("Modbus Tcp Slave Started");

            while (true)

                s = socketServer.Accept();

                while (s != null)

                {

                    if ((int)s.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error) != 0) goto ExitServer;

                    if (s.Available > 0)

                    {

                        TCP_DealwithCommand();

                    }            

                    Thread.Sleep(10);

                }

         ExitServer:

            s.Close();

            s = null;

            Debug.Print("Modbus Tcp Slave Exit");

        }

        //資料解析

        private void TCP_DealwithCommand()

            int i = 0;

            int lngSendNum = 0;

            int lngDataNum = 0;

            int lngDataAddr = 0;

            //接收資料

            int intRet=s.Receive(m_InputTCPBuf);

            //Debug.Print("Receive Num:" + intRet.ToString());

            for (i = 0; i < 12; i++) m_OutputTCPBuf[i] = m_InputTCPBuf[i];

            //---------------------------------------------------------------

            //Modbus 讀指令

            if (m_InputTCPBuf[7] == 3)

                … …

            //Modbus 寫指令

            if (m_InputTCPBuf[7] == 16)

                … …

        //IP位址轉化

        private long DottedDecimalToIp(byte a1, byte a2, byte a3, byte a4)

            return (long)((ulong)a4 << 24 | (ulong)a3 << 16 | (ulong)a2 << 8 | (ulong)a1);

    }

程式部署運作後,我們就可以用标準的Modbus Tcp Client程式測試了,我使用的是YFIOServer。

1、  先配置Modbus Tcp驅動程式

(圖MF071029001.jpg)

2、  再配置IO連接配接變量

3、  開始讀寫GPIO,此時GPIO燈的亮滅,完全被寫入的資料控制了。

總論:很難想像,操作TCP的代碼比C#的代碼還要簡潔高效,不到十幾分鐘,就把一個C#代碼改造為MF代碼,并且在很短的時間内就調試成功。微軟的下一個戰略看來馬上就成為現實:全世界的每一個智能裝置都用MF上網J。