转 C# 串口编程遇到的问题以及解决方法
?? ? ?問題是這樣的,從相應(yīng)的硬件設(shè)備每隔2秒便發(fā)送一個(gè)大小為15的字節(jié)數(shù)據(jù),存的是16進(jìn)制數(shù)據(jù),每條數(shù)據(jù)以7E開頭以7E結(jié)尾。例如:7E 09 01 1A ... 7E。但是PC端在接受顯示的時(shí)候卻出現(xiàn)了問題,如前五個(gè)數(shù)據(jù)接受正常,接下來的都是以00填充,而剩下的10個(gè)數(shù)據(jù)卻出現(xiàn)在下條數(shù)據(jù)顯示的位置。如下所 示:?
?? ? ?7E 09 01 1A 5C 00 00 00 00 00 00 00 00 00 00 /// 03 06 1A 2C 3D 09 6C 32 12 7E 00 00 00 00 00 00/// ........
?? ? ?總之感覺錯(cuò)位了,對(duì)了,先把PC端代碼貼一下吧: ? ? ?
?? ??
public?partial?class?Form1?:?Form
????{
????????///?<summary>
????????///?接受數(shù)據(jù)的串口類?
????????///?</summary>
????????SerialPort?spReceive;
????????delegate?void?ReceivData(byte[]?bytes);
????????public?Form1()
????????{
????????????Form1.CheckForIllegalCrossThreadCalls?=?false;
????????????InitializeComponent();
??????????
????????????spReceive?=new?SerialPort("COM5",?57600,?Parity.None,?8,?StopBits.One);?????????????
????????????spReceive.Open();
????????????
????????????//設(shè)置觸發(fā) DataReceived事件的閥值,在調(diào)試中發(fā)現(xiàn)這個(gè)不起作用,不解~??????
????????????spReceive.ReceivedBytesThreshold?=15;????????????
????????????spReceive.DataReceived?+=new?System.IO.Ports.SerialDataReceivedEventHandler(spReceive_DataReceived);????????????
????????}
????????///?<summary>
????????///?更新接受到得數(shù)據(jù)到UI 界面顯示
????????///?</summary>
????????///?<param?name="bytes"></param>
????????public?void?UpdateReceiveToUI(byte[]?bytes)
????????{
????????????if?(txtReceive.InvokeRequired)
????????????{
????????????????ReceivData?dl?=?new?ReceivData(UpdateReceiveToUI);
????????????????object?arg?=?bytes;
????????????????txtReceive.Invoke(dl,?arg);
????????????}
????????????else
????????????????txtReceive.Text?+=?"/"?+?BitConverter.ToString(bytes);
????????}
????????///?<summary>
????????///?接收到串口數(shù)據(jù)觸發(fā)的事 件
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????public?void?spReceive_DataReceived(object?sender,?System.IO.Ports.SerialDataReceivedEventArgs?e)
????????{
????????????byte[]?recevied?=?new?byte[15];
????????????int?size?=?spReceive.Read(recevied,?0,?recevied.Length);
?? ? ? ? ? ?if?(size?>0)
?? ? ? ? ? ? ? ?UpdateReceiveToUI(recevied);
?? ? ? ? ? ?
????????}
?? ?}
?? ? ? 在調(diào)試的過程中,當(dāng)我spReceive_DataReceived函數(shù)中的byte[]?recevied?=?new?byte[15];?后面在加上個(gè)初始化,如下:
?? ? ? for( int i=0; i<recevied.Lengthl;i++)
?? ? ? ? ? ? recevied[i]=11;
?? ?
?? ? ? 這個(gè)時(shí)候界面顯示的時(shí)候,凡是以00顯示的地方都被11替換了。這肯定了這些00是由于傳送的15個(gè)字節(jié)數(shù)組未被完全填充到我們定義的字節(jié)數(shù)組中,即 Read(byte [] bytes,int offset,int size)函數(shù)未一次性將字節(jié)數(shù)組填充完,而是分了兩次。但是在此過程中我使用的是SerialPort類的DataReceived事件,即沒收到一條 數(shù)據(jù)便會(huì)觸發(fā),而這兒的現(xiàn)象仿佛是事件被觸發(fā)了多次。后來自己在SerialPort類的屬性里面找了下,突然發(fā)現(xiàn)了有個(gè) ReceivedBytesThreshold屬性,從這個(gè)屬性可以看出我們可以控制接受多少個(gè)字節(jié)觸發(fā)一次DataReceived事件。于是,我便將 閥值設(shè)為15個(gè)字節(jié),滿以為問題解決了,可是結(jié)果卻~
?? ? ? 囧啊,可是這個(gè)屬性也給了我們一些提示,也找到了問題的癥結(jié)所在。那就是,DataRecevied事件觸發(fā)的閥值,即接受到多少個(gè)字節(jié)數(shù)觸發(fā)一次偏小, 結(jié)果導(dǎo)致了我們一條大小為15個(gè)字節(jié)的數(shù)據(jù)觸發(fā)了兩次DataReceived事件。要解決這個(gè)問題,我們可以沿著這個(gè)思路走下去,那就是延遲 DataRecevied事件的觸發(fā)直到我們一條數(shù)據(jù)接受完畢。
?? ? ? 所以在spReceive_DataReceived事件函數(shù)中,我們做如下修改:
?? ? ? byte[] ?receiveBuffer=new byte[15]; ?
?? ? ? public void spReceive_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
?? ? ? {
?? ? ? ? ? ? ?int bytesRead = 0; ?
?? ? ? ? ? ? ?spReceive.ReceivedBytesThreshold = 100000; ? ? //延遲DataRecevied事件的再次觸發(fā)
?? ? ? ? ? ? ?
?? ? ? ? ? ? while (true)
?? ? ? ? ? ? {?
?? ? ? ? ? ? ? ? ??if (bytesRead >= 15) ? ? ?//這兒的15是我一條數(shù)據(jù)的大小
?? ? ? ? ? ? ? ? ?{?
?? ? ? ? ? ? ? ? ? ? ? ?byte[] bytes = new byte[bytesRead];?
?? ? ? ? ? ? ? ? ? ? ? ?Array.Copy(receiveBuffer, 0, bytes, 0, bytesRead); ? ? ??
?? ? ? ? ? ? ? ? ? ? ? ?Array.Clear(receiveBuffer, 0, bytesRead);?
?? ? ? ? ? ? ? ? ? ? ? ?UpdateReceiveToUI(bytes);
?? ? ? ? ? ? ? ? ? ? ? ?bytesRead = 0;?
?? ? ? ? ? ? ? ? ? ? ? ?break;?
?? ? ? ? ? ? ? ? ?}?
?? ? ? ? ? ? ? ? ?try
?? ? ? ? ? ? ? ? {
?? ? ? ? ? ? ? ? ? ?receiveBuffer[bytesRead] = (byte)spReceive.ReadByte();
?? ? ? ? ? ? ? ? ? ?++bytesRead;
?? ? ? ? ? ? ? ? }
?? ? ? ? ? ? ? ?catch (Exception ex1)
?? ? ? ? ? ? ? ?{
?? ? ? ? ? ? ? ? ? ?MessageBox.Show(ex1.Message);
?? ? ? ? ? ? ? ? ? ?break;
?? ? ? ? ? ? ? ?}?
?
?? ? ? ? ? ? ? ?bytesRead = 0;
?? ? ? ? ? ? ? ?spReceive.ReceivedBytesThreshold = 1; ??? ? ? ? ?//將延遲改回正常
?? ? ? ? ? ? }?
?? ? ? }?
?? ??
?? ? ? 經(jīng)過上述的改動(dòng),便可以解決讀取串口數(shù)據(jù)沖突與丟失的問題了~不周之處,還望各位斧正~
總結(jié)
以上是生活随笔為你收集整理的转 C# 串口编程遇到的问题以及解决方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入Android 【六】 —— 界面构
- 下一篇: Office无法打开超链接地址问题