日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

c#串口通訊類 基于C#實現(xiàn)串口通訊

工控機通常都帶有很多串口(10個),而且可以通過Moxa卡擴展串口. 但Moxa的串口和電腦自帶的串口還是有點區(qū)別 C#里面沒區(qū)別, 但之前VB6的MSComm控件有時就會有不一樣的地方.
支持串口通訊的儀表,通常通訊指令分2種,一種是文本格式的,另一種是16進制格式的.
文本格式的,比如說有些儀器,查版本號發(fā) *IDN? 就會返回文本格式的結(jié)果,例如 XXX 8905,502-H19-1449,V1.38.02.18A2
16進制通訊的,比如青智的電流表,查詢電流用的命令格式 01是儀表地址, 03是讀取的命令.1000是寄存器開始地址,000A是讀取長度, C10D是CRC校驗碼(多數(shù)使用CRC,也有儀器使用和校驗的)

c#串口通訊類 基于C#實現(xiàn)串口通訊


青智
還有一種儀器是自帶MCU,就是一打開串口就自動上傳數(shù)據(jù)給上位機, 這種就不需要命令了.只需要定時讀取串口緩沖區(qū)的內(nèi)容,按照報文的格式,分析出哪一段數(shù)據(jù)才是你需要的.
我常用的串口通訊工具有下面2個
在Github下載一個ComDBG的工具,這個是C#寫的,可以自己根據(jù)代碼擴展需要的功能,比如歷史發(fā)送記錄
c#串口通訊類 基于C#實現(xiàn)串口通訊


另外可以用一個監(jiān)控工具,串口監(jiān)控精靈, 這個對于那些沒有代碼的exe(比如一些儀表自帶有一些小軟件), 我們直接監(jiān)控某個串口的收發(fā)信息.就知道對應(yīng)的命令是什么了.
c#串口通訊類 基于C#實現(xiàn)串口通訊


我通常把串口通訊做成一個基類, 把打開/關(guān)閉串口,文本命令,16進制命令,CRC校驗,和校驗都寫到基類了,方便調(diào)用
c#串口通訊類 基于C#實現(xiàn)串口通訊


下面是部分方法的代碼
public bool InitCom(int portNum,int BaudRate =9600)
{
//端口打開時無法設(shè)置“PortName”
if (!sp.IsOpen)
sp.PortName = \"COM\" + portNum.ToString();
else
{
if (sp.PortName != \"COM\" + portNum.ToString())
{
sp.Close();
sp.PortName = \"COM\" + portNum.ToString();
}

}
sp.BaudRate = BaudRate;//波特率
sp.Parity = Parity.None;//無奇偶校驗位
sp.StopBits = StopBits.One;//兩個停止位
sp.Handshake = Handshake.None;//控制協(xié)議
sp.WriteTimeout = 1000; /*Write time out*/
sp.ReceivedBytesThreshold = 1;//設(shè)置 DataReceived 事件發(fā)生前內(nèi)部輸入緩沖區(qū)中的字節(jié)數(shù)
return true;
}

//把一串命令,默認(rèn)是文本string命令, 也可能是十六進制的數(shù)(空格分開),發(fā)到串口
protected bool SerialPortCmd(string command,ref string recvMsg,
int iDelay = 100, int RecvMsgLenParm= 2,bool IsCmdText =true)
{

DelaySec = iDelay;
RecvMsgLen = RecvMsgLenParm;

if (!openCom())
return false;
try
{
byte[] bytes;
if (IsCmdText)
bytes = Encoding.Default.GetBytes(command);
else
bytes = HexStringToBytes(command);
sp.Write(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
Debug.Write(ex.ToString());
return false; //write failed
}

return DataReceived(IsCmdText, ref recvMsg);
}
private bool DataReceived(bool IsResultText,ref string result)
{
//Thread Safety explain in MSDN:
// Any public static (Shared in Visual Basic) members of this type are thread safe.
// Any instance members are not guaranteed to be thread safe.
// So, we need to synchronize I/O

lock (thisLock)
{

string RecvMsgBuffer;
int len = sp.BytesToRead;

if (len >= RecvMsgLen) //返回長度足夠了.
{

Byte[] data = https://www.jinnalai.com/fenxiang/new Byte[len];
try
{
sp.Read(data, 0, len);

推薦閱讀