4327|5

80

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

这个wince串口程序调不通啊!!!!愁! [复制链接]

winCE5.0下串口程序无法接收数据!,请高手帮忙!! SOS...
下面是我在VS2005下用C#编写的,用在winCE5.0下的一个串口程序, 编译可以成功,可以发送字符串,但是不能接收,会出现这样的提示"Control.Invoke必须用于与在独立线程上创建的控件交互"!请问哪位高手可以帮一下我吗?实在没办法了!!!SOS。。。。。。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace TestSerialPort
{
    public partial class frmTESTSerialPort : Form
    {
        //实例化串口对象(默认:COM1,9600,e,8,1)                          
        SerialPort myserialPort = new SerialPort();

        //串口控件初始化
        public frmTESTSerialPort()
        {
          //Form.CheckForIllegalCrossThreadCalls = false; //如果加上这句话,在编译时出现了以下错误,         //“System.Windows.Form.Form”并不包含“CheckForIllegalCrossThreadCalls”的定义
            InitializeComponent();
        }

        //窗口载入
        private void frmTESTSerialPort_Load(object sender, EventArgs e)
        {
            //更改参数
            myserialPort.PortName = "COM1 ";
            myserialPort.BaudRate = 9600;
            myserialPort.Parity = Parity.None;
            myserialPort.DataBits = 8;
            myserialPort.StopBits = StopBits.One;
            myserialPort.ReadBufferSize = 4096;
            //上述步骤可以用在实例化时调用SerialPort类的重载构造函数
            //SerialPort serialPort = new SerialPort("COM1 ", 9600, Parity.None, StopBits.One);  
        }

        //开启串口
        private void button1_Click(object sender, EventArgs e)
        {
            //打开串口(打开串口后不能修改端口名,波特率等参数,修改参数要在串口关闭后修改)  
            if (myserialPort.IsOpen == false)
            {
                myserialPort.Open();
                MessageBox.Show("串口开启成功");
            }
        }

        //发送数据
        private void button2_Click(object sender, EventArgs e)
        {
            //发送数据
            SendStringData(myserialPort);
        }

        //发送字符串数据
        private void SendStringData(SerialPort serialPort)
        {
            try
            {
                serialPort.Write(txtSend.Text);
            }
            catch
            {
                MessageBox.Show("请先打开串口");
            }
        }

        //发送二进制数据
        private void SendBytesData(SerialPort serialPort)
        {
            byte[] bytesSend = System.Text.Encoding.Default.GetBytes(txtSend.Text);
            serialPort.Write(bytesSend, 0, bytesSend.Length);
        }

        //接收\读取数据
        public void button3_Click(object sender, EventArgs e)
        {
            //同步阻塞接收数据线程
            Thread threadReceive = new Thread(new ThreadStart(SynReceiveData));//修改
            threadReceive.Start();
            //也可用异步接收数据线程
            //Thread  threadReceiveSub  =  new  Thread(new  ParameterizedThreadStart(AsyReceiveData));  
            //threadReceiveSub.Start(serialPort);  
        }

        //同步阻塞读取
        private  void SynReceiveData()
        {
            MessageBox.Show("同步阻塞读取线程启动");
            SerialPort serialPort = myserialPort;
            System.Threading.Thread.Sleep(0);
            try
            {
                //阻塞到读取数据或超时(这里为秒)
                serialPort.ReadTimeout = 6000;
                //下面代码要用同步的方式readtimeout起作用
                byte[] bufReceive=new byte[1024];
                int bytesRead = serialPort.Read(bufReceive, 0, bufReceive.Length);


                byte[] bytesData = new byte[bytesRead];
                for (int i = 0; i <= bytesRead - 1; i++)
                {
                    bytesData = bufReceive;
                }
              txtReceive.Text  =txtReceive.Text  + System.Text.Encoding.Default.GetString(bytesData, 0, bytesRead);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                //处理超时错误
            }
        }

         public delegate void SetText(string value);
        private void SetTextBox(string value)
        {
     txtReceive.Text=txtReceive.Text+value;
        }


    //异步读取
        private void AsyReceiveData(object serialPortobj)
        {
            SerialPort serialPort = (SerialPort)serialPortobj;
            System.Threading.Thread.Sleep(500);
            try
            {
                SetText set = new SetText(SetTextBox);
                txtReceive.Invoke(set,serialPort.ReadExisting());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                //处理错误
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (myserialPort.IsOpen == true)
            {
                myserialPort.Close();
                MessageBox.Show("串口关闭成功");
            }
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtSend_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtReceive_TextChanged(object sender, EventArgs e)
        {

        }

    }
  
}



问题补充:
        这个程序不是小弟本人写的,我对这个程序还不是很懂,请各位帮忙把解决方案写得稍祥细一些,谢谢了!!

最新回复

我这里有程序,vs2005C#   你要使用委托来收数据 ,发送跟其它的一样。  详情 回复 发表于 2008-7-3 15:51
点赞 关注

回复
举报

53

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
使用Form.Invoke可以解决线程之间安全传递数据的问题。
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
楼上的大哥可以再说的清楚一点吗
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

4
 

这个例子就使用了窗口的回调函数,得到 readThread 线程中变量值,再传递给控件;
标准示例可以在查一查。

  1.     public partial class MainForm : Form
  2.     {
  3.         private SerialPort com;
  4.         //this thread is listening serial port
  5.         private Thread readThread;
  6.         private delegate void SetTextCallback(string text);

  7.         public MainForm()
  8.         {
  9.             InitializeComponent();
  10.             
  11.             initcboCom();
  12.             this.readThread = new Thread(new ThreadStart(asynchronousRead));
  13.         }

  14.         private void btnSend1_Click(object sender, EventArgs e)
  15.         {
  16.             if (com != null)
  17.             {
  18.                 com.Write(txtSend.Text);
  19.             }
  20.         }

  21.         //attempt to open the serial port which is selected.
  22.         private void cboCom_SelectedIndexChanged(object sender, EventArgs e)
  23.         {
  24.             try
  25.             {
  26.                 if (com == null)
  27.                 {
  28.                     MessageBox.Show("Null serialPort Closed!");
  29.                 }
  30.                 else
  31.                 {
  32.                     if (com.IsOpen)
  33.                     {
  34.                         com.Close();
  35.                         com.Dispose();
  36.                         MessageBox.Show(com.PortName + ": Closed!");
  37.                     }
  38.                 }
  39.                 com = new SerialPort(this.cboCom.SelectedItem.ToString(), 9600, Parity.None, 8, StopBits.One);
  40.                 //the unit's size will be 1024,so the read buffer size must be n*1024.
  41.                 //it can prevent the data from losing.
  42.                 com.ReadBufferSize = 2048;  
  43.                 com.WriteBufferSize = 1024;
  44.                 com.Open();
  45.                 this.Text = "serialTest  " + com.PortName + " Is Open!";
  46.                 //add a event delegate method of serial data received
  47.                 com.DataReceived += new SerialDataReceivedEventHandler(this.serialDataReceived);
  48.             }
  49.             catch(Exception ex)
  50.             {
  51.                 this.Text = "serialTest";
  52.                 MessageBox.Show(ex.Message+ex.Source);               
  53.             }
  54.             finally
  55.             {
  56.                
  57.             }
  58.         }

  59.         //show local used serial ports,and open it.
  60.         private void initcboCom()
  61.         {
  62.             string[] coms;

  63.             coms = SerialPort.GetPortNames();

  64.             this.cboCom.Items.AddRange(coms);
  65.         }
  66.         
  67.         //serial data received event delegate method
  68.         private void serialDataReceived(object sender, SerialDataReceivedEventArgs e)
  69.         {
  70.             /*
  71.             we keep the read data thread always only one.when the property of "IsAlive" is false,create a readTread.
  72.             this lines of code is not secure,becuase of tow reasons.
  73.             the one is too much events of data received with more size of data.
  74.             the second is the readThread is exceptional stopped or busily unnormol.
  75.              */
  76.             Thread.Sleep(200);
  77.             switch (readThread.ThreadState)
  78.             {
  79.                 case ThreadState.Unstarted:
  80.                     readThread.Start();
  81.                     break;
  82.                 case ThreadState.Stopped:
  83.                     readThread = new Thread(new ThreadStart(asynchronousRead));
  84.                     readThread.Start();
  85.                     break;
  86.                 default:
  87.                     MessageBox.Show(readThread.ThreadState.ToString());
  88.                     break;
  89.             }
  90.             
  91.         }

  92.         //asynchronous data read method and ThreadStart delegate method
  93.         private void asynchronousRead()
  94.         {
  95.             setReceiveText(com.ReadExisting().ToString());           
  96.         }

  97.         //use delegate for form,form can invoke the delegate and with parameters for controls.
  98.         private void setReceiveText(string text)
  99.         {
  100.             // InvokeRequired required compares the thread ID of the
  101.             // calling thread to the thread ID of the creating thread.
  102.             // If these threads are different, it returns true.
  103.             if (this.txtReceive.InvokeRequired)
  104.             {
  105.                 SetTextCallback d = new SetTextCallback(setReceiveText);
  106.                 this.Invoke(d, new object[] { text });
  107.             }
  108.             else
  109.             {
  110.                 this.txtReceive.Text = this.txtReceive.Text+text;
  111.             }
  112.         }

  113.     }
复制代码
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

5
 
在2005下是无法跨线程交互数据的,在pc机上的winform程序也是一样。
可以用委托解决。如楼上所示。
你可以先在pc上调通,在放到wince下。
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

6
 
我这里有程序,vs2005C#   你要使用委托来收数据 ,发送跟其它的一样。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表