搜索
bottom↓
回复: 21

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

[复制链接]

出0入93汤圆

发表于 2011-6-21 14:30:06 | 显示全部楼层 |阅读模式
没学过上位机,新手。单片机里面很容易处理的问题,比如一个很长过程的函数,需要串口接收到特定指令后开始执行。
可以设置一个全局变量,然后在while(1)里面判断这个变量,当在串口中断中置位后,复位标志。开始执行这个过程函数。

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

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

出0入0汤圆

发表于 2011-6-21 14:33:03 | 显示全部楼层
C#里面叫while(true),但通常是不会这么用的,Winform里面有消息循环

出0入0汤圆

发表于 2011-6-21 14:40:23 | 显示全部楼层
上位机OS(以Windows为例)是消息驱动机制, 与裸奔的单片机的机制(顺序执行+中断)是不同的

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

出0入93汤圆

 楼主| 发表于 2011-6-21 14:46:33 | 显示全部楼层
现在是用timer,我在timer里面处理串口数据,接收到开始指令以后,开始一个大概30秒得测试过程,
这30秒得测试过程不能放在timer中断里面呀,因为还有一些其他需要处理的数据。

这种情况应该怎么处理?

出0入0汤圆

发表于 2011-6-21 14:51:27 | 显示全部楼层
c#中串口收数据是事件机制,其实也是while(1),你用datareceivecallback,即可

出0入93汤圆

 楼主| 发表于 2011-6-21 14:53:18 | 显示全部楼层
大概这样一个界面,没写过上位机,确实很纠结。界面中压力监控和电压监控,每秒刷新一次就行。timer里面通过串口读取下位机的数据刷新。
如果下位机上传一个开始指令的话,需要填充左侧的数据表。整个测试需要30秒。

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


(原文件名:QQ截图未命名.jpg)

出0入0汤圆

发表于 2011-6-21 14:55:13 | 显示全部楼层
第一次做上位机,界面还做得不错哟

出0入93汤圆

 楼主| 发表于 2011-6-21 15:05:31 | 显示全部楼层
仅仅是整齐,昨天摆到现在。处理串口数据之类的都OK,可是和windows相关的编程都不会实现。

出0入0汤圆

发表于 2011-6-21 15:07:05 | 显示全部楼层
在timer的回调函数里,给一个全局变量赋值或者新建一个线程来处理。

出0入93汤圆

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

出0入93汤圆

 楼主| 发表于 2011-6-21 15:15:39 | 显示全部楼层
看来速成不了了。去找个C#的书研究一下回调函数。

出0入0汤圆

发表于 2011-6-21 15:16:32 | 显示全部楼层
回复【9楼】friendljy  
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-6-21 15:18:05 | 显示全部楼层
楼主  可以使用4楼的方式

在上位机中最好不要使用While语句。。


(原文件名:1.jpg)


(原文件名:2.jpg)


(原文件名:3.jpg)


(原文件名:4.jpg)

出0入93汤圆

 楼主| 发表于 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[0, 0].Value = 0;
            System.Threading.Thread.Sleep(5000);
            dgvDianya[0, 1].Value = 1;
        }

出0入0汤圆

发表于 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[0, 0].Value = data;
            data++;//这个数据的变化可以放在外面,这里只是举例
        }
    }

出0入0汤圆

发表于 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)
{
//接受数据的过程
}

出0入0汤圆

发表于 2011-6-21 16:02:00 | 显示全部楼层
还有,不要使用while(1)或while(true)
消息机制本来就是在CPU的消息队列里面的,
这个winform本身就是一直在循环的

出0入0汤圆

发表于 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[0, 0].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 = 接受的数据//开始填充数据
            }
        }

出0入93汤圆

 楼主| 发表于 2011-6-21 16:15:17 | 显示全部楼层
谢谢楼上,我试试。

出0入0汤圆

发表于 2011-6-21 22:56:23 | 显示全部楼层
17楼的只是演示使用可以,但是用在工业或正式产品里,回调函数还要修改,需要做一下安全赋值,否则会出错的。。。

出0入12汤圆

发表于 2011-6-22 00:27:36 | 显示全部楼层
串口数据到达触发事件
同时 + 委托
否则你的界面很容易挂掉

出0入0汤圆

发表于 2012-1-17 22:01:56 | 显示全部楼层
学习了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-4 21:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表