c#上位机软件的while(1)在哪?
没学过上位机,新手。单片机里面很容易处理的问题,比如一个很长过程的函数,需要串口接收到特定指令后开始执行。可以设置一个全局变量,然后在while(1)里面判断这个变量,当在串口中断中置位后,复位标志。开始执行这个过程函数。
这两天想写一个C#的函数,比如需要在timer里面查询某硬件的状态,查询到以后,开始执行过程函数,应该怎么调用?
直接写在timer里面,则除了过程函数,其他什么都干不了了。
跟踪了半天,找不到类似下位机while(1)这样的循环。这种情况应该怎么处理?
其实就是在正常的工作界面下,除了timer等中断函数,还有哪些函数是被执行的?过程函数不能放在中断里面。 C#里面叫while(true),但通常是不会这么用的,Winform里面有消息循环 上位机OS(以Windows为例)是消息驱动机制, 与裸奔的单片机的机制(顺序执行+中断)是不同的
楼主这种情况还是用 timer (定时器) 实现比较好 现在是用timer,我在timer里面处理串口数据,接收到开始指令以后,开始一个大概30秒得测试过程,
这30秒得测试过程不能放在timer中断里面呀,因为还有一些其他需要处理的数据。
这种情况应该怎么处理? c#中串口收数据是事件机制,其实也是while(1),你用datareceivecallback,即可 大概这样一个界面,没写过上位机,确实很纠结。界面中压力监控和电压监控,每秒刷新一次就行。timer里面通过串口读取下位机的数据刷新。
如果下位机上传一个开始指令的话,需要填充左侧的数据表。整个测试需要30秒。
现在比如30秒得测试过程写完了。放到哪儿执行?如果直接放在timer里面不行,这样电压压力就不能实时监控了。
如果能想下位机那样,判断一个标志位就好了。timer里面直接置位标志就好。可惜不知道怎么实现。
http://cache.amobbs.com/bbs_upload782111/files_41/ourdev_650831XVQD3W.jpg
(原文件名:QQ截图未命名.jpg) 第一次做上位机,界面还做得不错哟 仅仅是整齐,昨天摆到现在。处理串口数据之类的都OK,可是和windows相关的编程都不会实现。 在timer的回调函数里,给一个全局变量赋值或者新建一个线程来处理。 还有个基础的问题,比如我向数据表写一个数据,然后sleep5秒,再写一个数据。
private void toolStripButton1_Click(object sender, EventArgs e)
{
dgvDianya.Value = 0;
System.Threading.Thread.Sleep(5000);
dgvDianya.Value = 1;
}
现象就是点一下按钮,卡5秒钟,然后两个一起出来。看函数好像这个现象也对。
怎么实现想我说的,写一个,停5秒,再写一个?
有没有强制刷新或显示Form的函数? 看来速成不了了。去找个C#的书研究一下回调函数。 回复【9楼】friendljy
-----------------------------------------------------------------------
还是用timer, 把sleep换成新建一个5秒的timer, sleep后面的放进回调里,在回调里杀掉自己的timer就ok了。 楼主可以使用4楼的方式
在上位机中最好不要使用While语句。。
http://cache.amobbs.com/bbs_upload782111/files_41/ourdev_650838K8OCEW.jpg
(原文件名:1.jpg)
http://cache.amobbs.com/bbs_upload782111/files_41/ourdev_650839LZ96RG.jpg
(原文件名:2.jpg)
http://cache.amobbs.com/bbs_upload782111/files_41/ourdev_650840S9OMYR.jpg
(原文件名:3.jpg)
http://cache.amobbs.com/bbs_upload782111/files_41/ourdev_650841WBP6GF.jpg
(原文件名:4.jpg) 回复【11楼】racede 吖
回复【9楼】friendljy
-----------------------------------------------------------------------
还是用timer, 把sleep换成新建一个5秒的timer, sleep后面的放进回调里,在回调里杀掉自己的timer就ok了。
-----------------------------------------------------------------------
回调函数不会写,就这个函数,谁帮忙敲个回调函数。
private void toolStripButton1_Click(object sender, EventArgs e)
{
dgvDianya.Value = 0;
System.Threading.Thread.Sleep(5000);
dgvDianya.Value = 1;
} 这个简单的:
int data = 0;//你的数据
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
dgvDianya.Value = data;
data++;//这个数据的变化可以放在外面,这里只是举例
}
} 另外说明,如果是使用serialport控件的话,参照如下:
// serialPort1
//
this.serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);
//
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//接受数据的过程
} 还有,不要使用while(1)或while(true)
消息机制本来就是在CPU的消息队列里面的,
这个winform本身就是一直在循环的 你这个软件的大概结构是这样:
int data = 0;//你的数据
bool dataReceiveStart = false;//判断是否开始监控
int seconds = 0;//判断30秒后结束
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Enabled = false;
serialPort1.Open();
}
private void timer1_Tick(object sender, EventArgs e)
{
dgvDianya.Value = data;
data++;//这个数据的变化可以放在外面,这里只是举例
seconds += 5;
if (seconds >= 30)
{
seconds = 0;
timer1.Enabled = false;
MessageBox.Show("结束监控");
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if(//下位传送的是开始信号)
{
timer1.Enabled = true;//开始5秒一次填充数据
dataReceiveStart = true;
}
if(dataReceiveStart)//判断下位机是否发送了开始信号
{
data = 接受的数据//开始填充数据
}
} 谢谢楼上,我试试。 17楼的只是演示使用可以,但是用在工业或正式产品里,回调函数还要修改,需要做一下安全赋值,否则会出错的。。。 串口数据到达触发事件
同时 + 委托
否则你的界面很容易挂掉 学习了
页:
[1]