一個簡單的串口程序

····從2015年到如今,將近4年沒有寫程序了,此次是一個朋友要我作物聯網的項目,要學習一些新東西,作起來再說。數據庫

····基於STM32的通信調試起來仍是不方便,用C#寫了一個簡單的收發程序,先模擬鏈式收發,主要是測試流程是否正常無誤。後面用C寫好這部分處理程序再下載到單片機上就OK了,多是剛開始接觸STM32的單片機不習慣,仍是以爲這樣省事。數組

····在用C#寫的時候,發現關閉端口出現死機現象,到網上百度也沒有找到好的處理辦法,最終仍是用委託註銷的方式解決了。異步

····主要代碼:ide

        private void sp_DataReceived(object sender,SerialDataReceivedEventArgs e)
        {學習

            System.Threading.Thread.Sleep(500);//延時500ms等待接收完數據
            Application.DoEvents();
            this.BeginInvoke((EventHandler)(delegate
            {
                if (IsOpen)
                {
                    textBox2.Text += "\r\n新接收到的數據:"+Convert.ToString(DateTime.Now);
                    if (IsFormatHex == false)
                    {
                        byte[] ReceiveData = new byte[sp.BytesToRead];//建立接收字節數組
                        sp.Read(ReceiveData, 0, ReceiveData.Length);//讀取接收到的數據
                        receiveDatas.Clear();
                        receiveDatas.AddRange(ReceiveData);測試

                        textBox2.Text += Encoding.Default.GetString(receiveDatas.ToArray());
                        //textBox2.Text += sp.ReadLine().ToString();this

                        //存入本地數據庫
                        FFDWTable SaveFFDW = new FFDWTable();
                        SaveFFDW.sCommType = "WS";
                        SaveFFDW.sCommPara = "命令參數";
                        SaveFFDW.sSend = "01";
                        SaveFFDW.dtSendTime = DateTime.Now;
                        SaveFFDW.sRece = "02";
                        SaveFFDW.sData = Encoding.Default.GetString(receiveDatas.ToArray());
                        //SaveData(SaveFFDW);
                        調試

                    }
                    else
                    {orm

                        Byte[] ReceivedData = new Byte[sp.BytesToRead];//建立接收字節數組
                        sp.Read(ReceivedData, 0, ReceivedData.Length);//讀取接收的數據
                        String ReceDataText = null;
                        for (int i = 0; i < ReceivedData.Length - 1; i++)
                        {
                            ReceDataText += ("0x" + ReceivedData[i].ToString("X2" + " "));
                        }
                        textBox2.Text += ReceDataText;
                    }
                    sp.DiscardInBuffer();//丟棄接收緩衝區數據事件

                }

            }));

        }

····上面是接收事件,主要處理接收到的數據。

····在打開串口設置屬性的時候,要註冊事件:

            //定義DataReceived事件,當串口收到數據後觸發事件
           sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
····在關閉串口的時候,避免死機的方法:

                    try
                    {
                        // 消除委託
                        if (IsOpen == false)
                        {
                            sp.DataReceived -= sp_DataReceived;
                        }
                        sp.Close();
                        IsSetProperty = false;
                        btOpenComPort.Text = "打開串口";
                        CBCommPort.Enabled = true;
                        CBBaudRate.Enabled = true;
                        CBDataBit.Enabled = true;
                        CBParitv.Enabled = true;
                        CBStopBit.Enabled = true;
                        rbChar.Enabled = true;
                        rbHex.Enabled = true;
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("關閉串口時發生錯誤!", "錯誤提示");
                    }
  通過試驗,若是是BeginInvoke則不會死機,換成Invoke則死機,在網上查了資料,原來BeginInvoke是採用異步方式來處理裏面的委託,而Invoke採用的是同步方式,它在處理完事務期間對其餘消息有阻塞,因此形成了死機。
一個簡單的串口程序

相關文章
相關標籤/搜索