日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

转 C# 串口编程遇到的问题以及解决方法

發(fā)布時(shí)間:2025/3/20 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 转 C# 串口编程遇到的问题以及解决方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
最近在做的項(xiàng)目中涉及到串口通信編程,隊(duì)友在做這一模 塊的時(shí)候遇到了一個(gè)相信很多人都可能遇到的問(wèn)題,那就是接受數(shù)據(jù)的沖突或者丟失。隊(duì)友讓我?guī)退{(diào)試的時(shí)候,足足花了近兩個(gè)小時(shí)才把問(wèn)題給解決了,現(xiàn)覺(jué)得有 必要總結(jié)一下以給遇到類似問(wèn)題的朋友一個(gè)思路吧~

?? ? ?問(wèn)題是這樣的,從相應(yīng)的硬件設(shè)備每隔2秒便發(fā)送一個(gè)大小為15的字節(jié)數(shù)據(jù),存的是16進(jìn)制數(shù)據(jù),每條數(shù)據(jù)以7E開(kāi)頭以7E結(jié)尾。例如:7E 09 01 1A ... 7E。但是PC端在接受顯示的時(shí)候卻出現(xiàn)了問(wèn)題,如前五個(gè)數(shù)據(jù)接受正常,接下來(lái)的都是以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/// ........

?? ? ?總之感覺(jué)錯(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)試的過(guò)程中,當(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ù)組填充完,而是分了兩次。但是在此過(guò)程中我使用的是SerialPort類的DataReceived事件,即沒(méi)收到一條 數(shù)據(jù)便會(huì)觸發(fā),而這兒的現(xiàn)象仿佛是事件被觸發(fā)了多次。后來(lái)自己在SerialPort類的屬性里面找了下,突然發(fā)現(xiàn)了有個(gè) ReceivedBytesThreshold屬性,從這個(gè)屬性可以看出我們可以控制接受多少個(gè)字節(jié)觸發(fā)一次DataReceived事件。于是,我便將 閥值設(shè)為15個(gè)字節(jié),滿以為問(wèn)題解決了,可是結(jié)果卻~

?? ? ? 囧啊,可是這個(gè)屬性也給了我們一些提示,也找到了問(wèn)題的癥結(jié)所在。那就是,DataRecevied事件觸發(fā)的閥值,即接受到多少個(gè)字節(jié)數(shù)觸發(fā)一次偏小, 結(jié)果導(dǎo)致了我們一條大小為15個(gè)字節(jié)的數(shù)據(jù)觸發(fā)了兩次DataReceived事件。要解決這個(gè)問(wèn)題,我們可以沿著這個(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)過(guò)上述的改動(dòng),便可以解決讀取串口數(shù)據(jù)沖突與丟失的問(wèn)題了~不周之處,還望各位斧正~

總結(jié)

以上是生活随笔為你收集整理的转 C# 串口编程遇到的问题以及解决方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。