本文共 2165 字,大约阅读时间需要 7 分钟。
····从2015年到现在,将近4年没有写程序了,这次是一个朋友要我做物联网的项目,要学习一些新东西,做起来再说。
····基于STM32的通讯调试起来还是不方便,用C#写了一个简单的收发程序,先模拟链式收发,主要是测试流程是否正常无误。后面用C写好这部分处理程序再下载到单片机上就OK了,可能是刚开始接触STM32的单片机不习惯,还是觉得这样省事。
····在用C#写的时候,发现关闭端口出现死机现象,到网上百度也没有找到好的处理办法,最终还是用委托注销的方式解决了。
····主要代码:
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();//存入本地数据库
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 {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采用的是同步方式,它在处理完事务期间对其他消息有阻塞,所以造成了死机。转载于:https://blog.51cto.com/dawn0919/2342403