C#调用PComm(线程安全)

3/3/2017来源:C/C++教程人气:2215

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Threading; using System.Collections;

namespace PCommApp { public class PComm { [DllImport(“PComm.dll”, EntryPoint = “sio_open”)] public static extern int sio_open(int port);

[DllImport("PComm.dll", EntryPoint = "sio_ioctl")] public static extern int sio_ioctl(int port, int baud, int mode); [DllImport("PComm.dll", EntryPoint = "sio_DTR")] public static extern int sio_DTR(int port, int mode); [DllImport("PComm.dll", EntryPoint = "sio_RTS")] public static extern int sio_RTS(int port, int mode); [DllImport("PComm.dll", EntryPoint = "sio_close")] public static extern int sio_close(int port); [DllImport("PComm.dll", EntryPoint = "sio_read")] public static extern int sio_read(int port, ref byte buf, int length); [DllImport("PComm.dll", EntryPoint = "sio_write")] public static extern int sio_write(int port,ref byte buf, int length); [DllImport("PComm.dll", EntryPoint = "sio_SetReadTimeouts")] public static extern int sio_SetReadTimeouts(int port, int TotalTimeouts, int IntervalTimeouts); [DllImport("PComm.dll", EntryPoint = "sio_SetWriteTimeouts")] public static extern int sio_SetWriteTimeouts(int port,int TotalTimeouts,int IntervalTimeouts); [DllImport("PComm.dll", EntryPoint = "sio_AbortRead")] public static extern int sio_AbortRead(int port); [DllImport("PComm.dll", EntryPoint = "sio_AbortWrite")] public static extern int sio_AbortWrite(int port); [DllImport("PComm.dll", EntryPoint = "sio_getmode")] public static extern int sio_getmode(int port); [DllImport("PComm.dll", EntryPoint = "sio_getbaud")] public static extern int sio_getbaud(int port); [DllImport("PComm.dll", EntryPoint = "sio_flowctrl")] public static extern int sio_flowctrl(int port,int mode); // Function return error code PRivate const int SIO_OK = 0; private const int SIO_BADPORT = -1; private const int SIO_OUTCONTROL = -2; private const int SIO_NODATA = -4; private const int SIO_OPENFAIL = -5; private const int SIO_RTS_BY_HW = -6; private const int SIO_BADPARAM = -7; private const int SIO_WIN32FAIL = -8; private const int SIO_BOARDNOTSUPPORT = -9; private const int SIO_ABORT_WRITE = -11; private const int SIO_WRITETIMEOUT = -12; // Self Define function return error code private const int ERR_NOANSWER = -101; // Baud rate private const int B50 = 0x0; private const int B75 = 0x1; private const int B110 = 0x2; private const int B134 = 0x3; private const int B150 = 0x4; private const int B300 = 0x5; private const int B600 = 0x6; private const int B1200 = 0x7; private const int B1800 = 0x8; private const int B2400 = 0x9; private const int B4800 = 0xA; private const int B7200 = 0xB; private const int B9600 = 0xC; private const int B19200 = 0xD; private const int B38400 = 0xE; private const int B57600 = 0xF; private const int B115200 = 0x10; private const int B230400 = 0x11; private const int B460800 = 0x12; private const int B921600 = 0x13; // Mode setting Data bits define private const int BIT_5 = 0x0; private const int BIT_6 = 0x1; private const int BIT_7 = 0x2; private const int BIT_8 = 0x3; // Mode setting Stop bits define private const int STOP_1 = 0x0; private const int STOP_2 = 0x4; // Mode setting Parity define private const int P_EVEN = 0x18; private const int P_ODD = 0x8; private const int P_SPC = 0x38; private const int P_MRK = 0x28; private const int P_NONE = 0x0; // Private Key name private const string KEY_PORT = "Port"; private const string KEY_BAUDRATE = "Baud_Rate"; private const string KEY_PARITY = "Parity"; private const string KEY_BYTESIZE = "Byte_Size"; private const string KEY_STOPBITS = "Stop_Bits"; private const string KEY_BEFOREDELAY = "Before_Delay"; private const string KEY_BYTEDELAY = "Byte_Delay"; private const string KEY_READINTERVALTIMEOUT = "Read_Interval_Timeout"; private const string KEY_AFTERDELAY = "After_Delay"; // Port param private int Gl_Int_Port=1; private int Gl_Int_Baudrate = B9600; private int Gl_Int_Parity = P_NONE; private int Gl_Int_ByteSize = BIT_8; private int Gl_Int_StopBits = STOP_1; // Delay param private int Gl_Int_BeforeDelay = 0; private int Gl_Int_ByteDelay = 0; private int Gl_Int_ReadIntervalTimeout = 50; private int Gl_Int_AfterDealy = 3000; /// <summary> /// 解析通讯参数 /// </summary> /// <param name="Hb_CommParam"></param> private void AnalyseCommParam(Hashtable Ht_CommParam) { //Port Gl_Int_Port=int.Parse(Ht_CommParam[KEY_PORT].ToString()); //Baud rate if (Ht_CommParam.Contains(KEY_BAUDRATE)) { switch (Ht_CommParam[KEY_BAUDRATE].ToString()) { case "50": Gl_Int_Baudrate = B50; break; case "75": Gl_Int_Baudrate = B75; break; case "110": Gl_Int_Baudrate = B110; break; case "134": Gl_Int_Baudrate = B134; break; case "150":Gl_Int_Baudrate = B150; break; case "300":Gl_Int_Baudrate = B300; break; case "600":Gl_Int_Baudrate = B600; break; case "1200":Gl_Int_Baudrate = B1200; break; case "1800":Gl_Int_Baudrate = B1800; break; case "2400":Gl_Int_Baudrate = B2400; break; case "4800":Gl_Int_Baudrate = B4800; break; case "7200":Gl_Int_Baudrate = B7200; break; case "9600":Gl_Int_Baudrate = B9600; break; case "19200": Gl_Int_Baudrate = B19200; break; case "38400": Gl_Int_Baudrate = B38400; break; case "57600": Gl_Int_Baudrate = B57600; break; case "115200": Gl_Int_Baudrate = B115200; break; case "230400": Gl_Int_Baudrate = B230400; break; case "460800": Gl_Int_Baudrate = B460800; break; case "921600": Gl_Int_Baudrate = B921600; break; default: Gl_Int_Baudrate = B9600; break; } } //Parity if (Ht_CommParam.Contains(KEY_PARITY)) { switch (Ht_CommParam[KEY_PARITY].ToString()) { case "Even": Gl_Int_Parity = P_EVEN; break; case "Odd": Gl_Int_Parity = P_ODD; break; case "Space": Gl_Int_Parity = P_SPC; break; case "Mark": Gl_Int_Parity = P_MRK; break; case "None": Gl_Int_Parity = P_NONE; break; default: Gl_Int_Parity = P_NONE; break; } } //Byte Size if (Ht_CommParam.Contains(KEY_BYTESIZE)) { switch (Ht_CommParam[KEY_BYTESIZE].ToString()) { case "5": Gl_Int_ByteSize = BIT_5; break; case "6": Gl_Int_ByteSize = BIT_6; break; case "7": Gl_Int_ByteSize = BIT_7; break; case "8": Gl_Int_ByteSize = BIT_8; break; default: Gl_Int_ByteSize = BIT_8; break; } } //Stop Bits if (Ht_CommParam.Contains(KEY_STOPBITS)) { switch (Ht_CommParam[KEY_STOPBITS].ToString()) { case "1": Gl_Int_StopBits = STOP_1; break; case "2": Gl_Int_StopBits = STOP_2; break; default: Gl_Int_StopBits = STOP_1; break; } } //Before Delay if (Ht_CommParam.Contains(KEY_BEFOREDELAY)) { int.TryParse(Ht_CommParam[KEY_BEFOREDELAY].ToString(),out Gl_Int_BeforeDelay); } //Byte Delay if (Ht_CommParam.Contains(KEY_BYTEDELAY)) { int.TryParse(Ht_CommParam[KEY_BYTEDELAY].ToString(), out Gl_Int_ByteDelay); } //Read Interval Timeout if (Ht_CommParam.Contains(KEY_READINTERVALTIMEOUT)) { int.TryParse(Ht_CommParam[KEY_READINTERVALTIMEOUT].ToString(), out Gl_Int_ReadIntervalTimeout); } //After Delay if (Ht_CommParam.Contains(KEY_AFTERDELAY)) { int.TryParse(Ht_CommParam[KEY_AFTERDELAY].ToString(),out Gl_Int_AfterDealy); } } /// <summary> /// 初始化串口通讯 /// </summary> /// <param name="Hb_CommParam"></param> /// <returns>错误码</returns> public int InitComm(Hashtable Ht_CommParam) { AnalyseCommParam(Ht_CommParam); //Open port int i_RtnCode = sio_open(Gl_Int_Port); if (i_RtnCode != SIO_OK) { return i_RtnCode; } //Configure communication parameters int mode=Gl_Int_Parity | Gl_Int_ByteSize | Gl_Int_StopBits; i_RtnCode = sio_ioctl(Gl_Int_Port,Gl_Int_Baudrate,mode); if (i_RtnCode != SIO_OK) { return i_RtnCode; } //Flow control i_RtnCode = sio_flowctrl(Gl_Int_Port, 0); if (i_RtnCode != SIO_OK) { return i_RtnCode; } //DTR i_RtnCode = sio_DTR(Gl_Int_Port, 1); if (i_RtnCode != SIO_OK) { return i_RtnCode; } //RTS i_RtnCode = sio_RTS(Gl_Int_Port, 1); if (i_RtnCode != SIO_OK) { return i_RtnCode; } //Set timeout values for sio_read sio_SetReadTimeouts(Gl_Int_Port,Gl_Int_AfterDealy,Gl_Int_ReadIntervalTimeout); return 0; } /// <summary> /// 发生十六进值字符串帧, /// </summary> /// <param name="Str_SendFrame">发送帧</param> /// <param name="Str_RecFrame">接受帧</param> /// <param name="i_NewBaudrate">新的波特率</param> /// <returns>错误码</returns> public int SendFrame(string Str_SendFrame, ref string Str_RecFrame, int i_NewBaudrate = 0) { int i_RtnCode; byte[] buffer=new byte[1024]; byte[] recbuffer = new byte[4096]; Str_SendFrame = Str_SendFrame.Replace(" ", ""); int i_FrameLen = Str_SendFrame.Length / 2; for (int i = 0; i <= i_FrameLen - 1; i++) { buffer[i]=Convert.ToByte(Str_SendFrame.Substring(i*2,2),16); } //Write data if (Gl_Int_ByteDelay == 0) { i_RtnCode = sio_write(Gl_Int_Port,ref buffer[0], i_FrameLen); if (i_RtnCode < 0) { return i_RtnCode; } } else { for (int i = 0; i <= i_FrameLen - 1; i++) { i_RtnCode = sio_write(Gl_Int_Port, ref buffer[i], 1); if (i_RtnCode < 0) { return i_RtnCode; } Thread.Sleep(Gl_Int_ByteDelay); } } //Change baudrate if (i_NewBaudrate < 0) //No need answer { return 0; } else if (i_NewBaudrate > 0) //Need change baudrate { int mode = sio_getmode(Gl_Int_Port); int baud = sio_getbaud(Gl_Int_Port); if (baud != i_NewBaudrate) { Thread.Sleep(180); sio_ioctl(Gl_Int_Port, i_NewBaudrate, mode); } } //Read data i_RtnCode = sio_read(Gl_Int_Port, ref recbuffer[0], 4096); if (i_RtnCode < 0) { return i_RtnCode; } else if (i_RtnCode == 0) { return ERR_NOANSWER; } int i_RecFrameLen = i_RtnCode; StringBuilder Sb_RecFrame = new StringBuilder(); for (int i = 0; i <= i_RecFrameLen - 1; i++) { Sb_RecFrame.Append(recbuffer[i].ToString("X")); Sb_RecFrame.Append(" "); } Str_RecFrame = Sb_RecFrame.ToString().Trim(); return 0; } /// <summary> /// 关闭串口通讯 /// </summary> /// <returns>错误码</returns> public int CloseComm() { int i_RtnCode=sio_close(Gl_Int_Port); if (i_RtnCode!=SIO_OK) { return i_RtnCode; } return 0; } /// <summary> /// 获取通讯错误消息 /// </summary> /// <param name="i_ErrCode">错误码</param> /// <returns>错误消息</returns> public string GetCommErrMsg(int i_ErrCode) { switch (i_ErrCode) { case SIO_OK: return "成功"; case SIO_BADPORT: return "串口号无效,检测串口号!"; case SIO_OUTCONTROL: return "主板不是MOXA兼容的智能主板!"; case SIO_NODATA: return "没有可读的数据!"; case SIO_OPENFAIL: return "打开串口失败,检查串口是否被占用!"; case SIO_RTS_BY_HW: return "不能控制串口因为已经通过sio_flowctrl设定为自动H/W流控制"; case SIO_BADPARAM: return "串口参数错误,检查串口参数!"; case SIO_WIN32FAIL: return "调用Win32函数失败!"; case SIO_BOARDNOTSUPPORT: return "串口不支持这个函数!"; case SIO_ABORT_WRITE:return "用户终止写数据块!"; case SIO_WRITETIMEOUT:return "写数据超时!"; case ERR_NOANSWER: return "无应答!"; default: return i_ErrCode.ToString(); } } }

}

示列代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Collections;

namespace PCommApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); }

private void btnSend_Click(object sender, EventArgs e) { btnSend.Enabled = false; try { Hashtable Ht = new Hashtable(); Ht.Add("Port", txbPort.Text.ToString()); Ht.Add("Baud_Rate", "9600"); Ht.Add("Parity", "None"); Ht.Add("Byte_Size", "8"); Ht.Add("Stop_Bits", "1"); Ht.Add("Before_Delay", "0"); Ht.Add("Byte_Delay", "50"); Ht.Add("Read_Interval_Timeout", "50"); Ht.Add("After_Delay", "3000"); string Str_SendFrame = txbSendFrame.Text.Trim(); string Str_RecFrame = string.Empty; PComm SP = new PComm(); //初始化串口 int i_RtnCode = SP.InitComm(Ht); if (i_RtnCode != 0) { MessageBox.Show(SP.GetCommErrMsg(i_RtnCode)); return; } try { //发送数据 ShowDebugMsg("发送: " + Str_SendFrame, true); i_RtnCode = SP.SendFrame(Str_SendFrame, ref Str_RecFrame, 0); if (i_RtnCode != 0) { ShowDebugMsg(SP.GetCommErrMsg(i_RtnCode), false); return; } ShowDebugMsg("接收: " + Str_RecFrame, true); } finally { //关闭串口 SP.CloseComm(); } } finally { btnSend.Enabled = true; } } /// <summary> /// 显示调试消息 /// </summary> /// <param name="Str_ShowMsg"></param> /// <param name="B_IsFrame"></param> private void ShowDebugMsg(string Str_ShowMsg,Boolean B_IsFrame) { if (B_IsFrame) { Str_ShowMsg = DateTime.Now.ToString()+ " " + Str_ShowMsg; } txtDebug.AppendText(Str_ShowMsg+"\r\n"); txtDebug.ScrollToCaret(); txtDebug.Refresh(); } }

}

完整代码资源链接: 这里写代码片http://download.csdn.net/detail/a295281315/9766510