您的位置:首页 > 编程语言

关于串口编程的(一)

2016-05-13 06:39 429 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。

所谓串口,也叫串行接口,即COM口,采用串行通讯方式(即数据一位一位的传送)的接口。也就是电脑后面D形9针插口。

最近做了两个都和串口编程有关的功能,一个是不间断电源,一个是RS232型串口打印机。因为是串口所以主要的用法都不难,难点是对设备的相应命令的理解和使用上。因为不同类型的、不同厂家的设备命令是不同的,因为也没法总一个总结。那就对于串口的简单用法做一些总结吧。

主要用到的类是SerialPort,在System.IO.Ports下。传设备的基本使用步骤如下:

1、设置串口的参数。因为不同的设备对串口的参数要求是不同的,最常见就是波特率,一般好像都是9600。

2、打开串口。也就是SerialPort的Open()方法。

3、想串口写命令或写文本内容。一般情况下,如果是数字类型的命令都是十六进制的,当然也有十进制的,不过如果有十六进制和十进制两种,我觉得最好用十六进制的,因为十六进制好转换为byte数组。

向串口写命令的方法是SerialPort的Write(byte[] buffer, int offset, int count)。比如一个命令,十六进制下:00 FF,十进制下:00 255;那么这段命令最终转为byte[]时,00和FF分别转换,但是对于00和255显然就不怎么方便了。看一下后面的一个例子就明白了。

4,接收返回值。向串口发送命令,有的是指示执行操作的,有的是查询状态的,因此需要读取返回值。

下面对于某一个串口设备的控制,写一个简单的例子。

1、字符操作类,因为串口写入的须要是byte数组型,读出又要将byte数组转为string,一般命令也是十六进制的。所以转换的方法需要用到。

[csharp] view
plain copy

print?

/// <summary>

/// 串口字符类

/// </summary>

public class CharOperated

{

public static string ByteArrayToHexString(byte[] byteData)

{

StringBuilder result = new StringBuilder(byteData.Length * 3);

foreach (byte b in byteData)

{

result.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));

}

return result.ToString().ToUpper();

}

/// <summary>

/// 十六进制的字符串转成byte数组

/// </summary>

/// <returns></returns>

public static byte[] HexStringToByteArray(string content)

{

content = content.Replace(" ", "");

byte[] buffer = new byte[content.Length / 2];

for (int i = 0; i < content.Length; i += 2)//因为十六进制命令一般都是两位十六进制一起。

{

buffer[i / 2] = (byte)Convert.ToByte(content.Substring(i, 2), 16);

}

return buffer;

}

/// <summary>

/// 16进制编码的字串解析成 ascii码

/// </summary>

/// <param name="statusCode"></param>

/// <returns></returns>

public static string DecodeHexToAsc(string statusCode)

{

string rtn = "";

statusCode = statusCode.Replace(" ", "");

for (int i = 0; i < (statusCode.Length / 2); i++)

{

string key = statusCode.Substring(2 * i, 2);

int asii = Convert.ToInt32(key, 16);//将16进制字符串转换成其ASCII码(实际是Unicode码)

rtn += Chr(asii);

}

return rtn;

}

/// <summary>

/// ascii码转字符

/// </summary>

/// <param name="asciiCode"></param>

/// <returns></returns>

public static string Chr(int asciiCode)

{

if (asciiCode >= 0 && asciiCode <= 255)

{

System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();

byte[] byteArray = new byte[] { (byte)asciiCode };

string strCharacter = asciiEncoding.GetString(byteArray);

return (strCharacter);

}

return string.Empty;

}

}

2、对串口的打开,发送命令,关闭等的类。

[csharp] view
plain copy

print?

public class ComManager

{

private SerialPort comm = null;

private static string currentPortName = string.Empty;

private static object sendCommandLock = new object();

public ComManager(SerialPort comm)

{

if (this.comm == null)

{

this.comm = comm;

}

}

/// <summary>

/// 串口参数设定

/// </summary>

private void SetSerialPort()

{

//根据设备要求设置参数,比如某一设备要求参数如下:

comm.BaudRate = 9600;

comm.Encoding = System.Text.Encoding.GetEncoding("GB2312");

comm.RtsEnable = true;

}

/// <summary>

/// 打开串口设备

/// </summary>

private void SerialPortOpen()

{

try

{

if (comm.IsOpen)

{

comm.Close();

}

currentPortName = "COM1";//此处可指定串口,也可以实时读取设备到底连接在那个串口,实际情况根据设备情况而定。

//currentPortName = DoGetUPSPortName();以某一设备为例遍历所有串口,找到连接该设备的串口

SetSerialPort();

if (string.IsNullOrEmpty(currentPortName))

{

return;

}

comm.PortName = currentPortName;

comm.Open();

}

catch

{

}

}

/// <summary>

/// 向串口发送命令

/// </summary>

/// <param name="sendstring"></param>

public void SendDatastring(string sendstring)

{

lock (sendCommandLock)

{

//16进制转二进制

byte[] data = CharOperated.HexStringToByteArray(sendstring);

//打开口串口设备

SerialPortOpen();

//发送命令到串口设备

if (comm.IsOpen)

{

comm.DiscardInBuffer();

comm.Write(data, 0, data.Length);

}

}

}

/// <summary>

/// 向串口写字符串

/// </summary>

/// <param name="sendstring"></param>

public void WriteLingContent(string content)

{

lock (sendCommandLock)

{

//打开口串口设备

SerialPortOpen();

//发送报文到串口设备

if (comm.IsOpen)

{

comm.WriteLine(content);

comm.DiscardInBuffer();

}

}

}

/// <summary>

/// 读取端口返回值

/// </summary>

/// <returns></returns>

private string DoReadPortResult()

{

string resultString = string.Empty;

try

{

int bytes = comm.BytesToRead;

byte[] buffer = new byte[bytes];

comm.Read(buffer, 0, bytes);

string rtnStrPort = CharOperated.ByteArrayToHexString(buffer);

resultString = CharOperated.DecodeHexToAsc(rtnStrPort);

if (comm.IsOpen)

{

comm.DiscardInBuffer();

}

}

catch

{

}

return resultString;

}

/// <summary>

/// 获取某一设备的端口号

/// </summary>

/// <returns></returns>

private string DoGetUPSPortName()

{

string commName = string.Empty;

try

{

Computer localComputer = new Computer();

foreach (string portItem in localComputer.Ports.SerialPortNames)

{

try

{

if (string.IsNullOrEmpty(portItem))

{

continue;

}

commName = portItem;

byte[] data = CharOperated.HexStringToByteArray("发送的命令");

comm.Close();

SetSerialPort();

comm.PortName = portItem;

comm.Open();

//发送报文到串口设备

if (comm.IsOpen)

{

comm.DiscardInBuffer();

comm.Write(data, 0, data.Length);

}

Thread.Sleep(500);

//if (条件)

//{

//}

//else

//{

// commName = string.Empty;

//}

}

catch

{

}

finally

{

if (comm.IsOpen)

{

comm.Close();

}

}

}

}

catch

{

}

finally

{

if (comm.IsOpen)

{

comm.Close();

}

}

return commName;

}

}

使用

[csharp] view
plain copy

print?

class Program

{

private static SerialPort serialPortCom = new SerialPort();//串口定义 。

private static string receiveResult = string.Empty; //接收数据。

static void Main(string[] args)

{

ComManager cm = new ComManager(serialPortCom);

cm.SendDatastring("00FF");//命令

cm.WriteLingContent("内容");

Thread.Sleep(200);//停几百毫秒,然后读取

string result = SerialPortComDataReceived();

}

private static string SerialPortComDataReceived()

{

if (serialPortCom == null || !serialPortCom.IsOpen)

{

return string.Empty;

}

int bytes = serialPortCom.BytesToRead;

byte[] buffer = new byte[bytes];

serialPortCom.Read(buffer, 0, bytes);

receiveResult = string.Empty;

receiveResult = CharOperated.ByteArrayToHexString(buffer);

receiveResult = receiveResult.Trim();

return receiveResult;

}

}

详细代码下载:http://download.csdn.net/detail/yysyangyangyangshan/5516631
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: