····從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採用的是同步方式,它在處理完事務期間對其餘消息有阻塞,因此形成了死機。