····从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采用的是同步方式,它在处理完事务期间对其他消息有阻塞,所以造成了死机。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。