friendljy 发表于 2011-6-21 14:30:06

c#上位机软件的while(1)在哪?

没学过上位机,新手。单片机里面很容易处理的问题,比如一个很长过程的函数,需要串口接收到特定指令后开始执行。
可以设置一个全局变量,然后在while(1)里面判断这个变量,当在串口中断中置位后,复位标志。开始执行这个过程函数。

这两天想写一个C#的函数,比如需要在timer里面查询某硬件的状态,查询到以后,开始执行过程函数,应该怎么调用?
直接写在timer里面,则除了过程函数,其他什么都干不了了。
跟踪了半天,找不到类似下位机while(1)这样的循环。这种情况应该怎么处理?

其实就是在正常的工作界面下,除了timer等中断函数,还有哪些函数是被执行的?过程函数不能放在中断里面。

MiniLight 发表于 2011-6-21 14:33:03

C#里面叫while(true),但通常是不会这么用的,Winform里面有消息循环

wowbanui 发表于 2011-6-21 14:40:23

上位机OS(以Windows为例)是消息驱动机制, 与裸奔的单片机的机制(顺序执行+中断)是不同的

楼主这种情况还是用 timer (定时器) 实现比较好

friendljy 发表于 2011-6-21 14:46:33

现在是用timer,我在timer里面处理串口数据,接收到开始指令以后,开始一个大概30秒得测试过程,
这30秒得测试过程不能放在timer中断里面呀,因为还有一些其他需要处理的数据。

这种情况应该怎么处理?

windboy 发表于 2011-6-21 14:51:27

c#中串口收数据是事件机制,其实也是while(1),你用datareceivecallback,即可

friendljy 发表于 2011-6-21 14:53:18

大概这样一个界面,没写过上位机,确实很纠结。界面中压力监控和电压监控,每秒刷新一次就行。timer里面通过串口读取下位机的数据刷新。
如果下位机上传一个开始指令的话,需要填充左侧的数据表。整个测试需要30秒。

现在比如30秒得测试过程写完了。放到哪儿执行?如果直接放在timer里面不行,这样电压压力就不能实时监控了。
如果能想下位机那样,判断一个标志位就好了。timer里面直接置位标志就好。可惜不知道怎么实现。

http://cache.amobbs.com/bbs_upload782111/files_41/ourdev_650831XVQD3W.jpg
(原文件名:QQ截图未命名.jpg)

windboy 发表于 2011-6-21 14:55:13

第一次做上位机,界面还做得不错哟

friendljy 发表于 2011-6-21 15:05:31

仅仅是整齐,昨天摆到现在。处理串口数据之类的都OK,可是和windows相关的编程都不会实现。

racede 发表于 2011-6-21 15:07:05

在timer的回调函数里,给一个全局变量赋值或者新建一个线程来处理。

friendljy 发表于 2011-6-21 15:10:15

还有个基础的问题,比如我向数据表写一个数据,然后sleep5秒,再写一个数据。
      private void toolStripButton1_Click(object sender, EventArgs e)
      {
            dgvDianya.Value = 0;
            System.Threading.Thread.Sleep(5000);
            dgvDianya.Value = 1;
      }
现象就是点一下按钮,卡5秒钟,然后两个一起出来。看函数好像这个现象也对。
怎么实现想我说的,写一个,停5秒,再写一个?
有没有强制刷新或显示Form的函数?

friendljy 发表于 2011-6-21 15:15:39

看来速成不了了。去找个C#的书研究一下回调函数。

racede 发表于 2011-6-21 15:16:32

回复【9楼】friendljy
-----------------------------------------------------------------------

还是用timer, 把sleep换成新建一个5秒的timer, sleep后面的放进回调里,在回调里杀掉自己的timer就ok了。

_yuming 发表于 2011-6-21 15:18:05

楼主可以使用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)

friendljy 发表于 2011-6-21 15:31:06

回复【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;
      }

lxlylm 发表于 2011-6-21 15:56:44

这个简单的:

      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++;//这个数据的变化可以放在外面,这里只是举例
      }
    }

lxlylm 发表于 2011-6-21 15:59:26

另外说明,如果是使用serialport控件的话,参照如下:

// serialPort1
//
this.serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);
//

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//接受数据的过程
}

lxlylm 发表于 2011-6-21 16:02:00

还有,不要使用while(1)或while(true)
消息机制本来就是在CPU的消息队列里面的,
这个winform本身就是一直在循环的

lxlylm 发表于 2011-6-21 16:14:21

你这个软件的大概结构是这样:

      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 = 接受的数据//开始填充数据
            }
      }

friendljy 发表于 2011-6-21 16:15:17

谢谢楼上,我试试。

_yuming 发表于 2011-6-21 22:56:23

17楼的只是演示使用可以,但是用在工业或正式产品里,回调函数还要修改,需要做一下安全赋值,否则会出错的。。。

skynet 发表于 2011-6-22 00:27:36

串口数据到达触发事件
同时 + 委托
否则你的界面很容易挂掉

wenfaxiang 发表于 2012-1-17 22:01:56

学习了
页: [1]
查看完整版本: c#上位机软件的while(1)在哪?