C#串口通讯接收发送数据

串口连接有几个必须要设置的值:串口,波特率,校验位,数据位,停止位

目录

一、实例化串口通讯类

 二、打开串口/关闭串口

三、发送数据:hex十六进制发送或ascll发送

四、十六进制字符串转byte【】 

 五、接收数据:hex十六进制接收或ascll接收

六、定时发送 

七、将接收到的消息导出txt文件


简单串口通讯效果图

串口:获取串口

            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                CbCom.Items.Add(port);
            }

            CbCom.SelectedIndex = 0;

波特率: 波特率单位是bit/s,代表是每秒传递多少个bit,也就是多少个位。一般使用9600

                波特率代表串口的传输数据能力,波特率越高传输数据越快,但是太高会出现传输数据不稳定的问题;发送方与接收方波特率要保持一致。 CbBaudRate.SelectedIndex = 5;

校验位: C#中有Parity枚举类型设置校验位。一般使用None无校验,Odd奇校验,Even偶检验。

comboBox4.SelectedIndex = 0; 

 数据位:一般情况下使用8,其他的也可以设置  CbDataBits.SelectedIndex = 3;

停止位: C#中StopBits枚举类型设置停止位,默认值设置1 StopBits.One     CbStopBits.SelectedIndex = 1;

 

一、实例化串口通讯类

SerialPort sp = new SerialPort();//实例化串口通讯类

private System.Timers.Timer tmr = new System.Timers.Timer();//实例化定时发送定时器
private object obj = new object();//锁


           

页面初次加载时
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);//接收数据事件
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");//编码类型

tmr.Elapsed += new System.Timers.ElapsedEventHandler(OnTmrTrg);定时事件
tmr.Interval =(double)numericUpDown4.Value;//定时发送间隔时间
tmr.AutoReset = true; //true-一直循环 ,false-循环一次   
tmr.Enabled = false;

 二、打开串口/关闭串口

if (button1.Text == "打开串口")
            {
                sp.PortName = CbCom.Text;//串口
                sp.BaudRate =int.Parse(CbBaudRate.Text);//波特率
                sp.DataBits=int.Parse(CbDataBits.Text);//数据位
                sp.StopBits=(StopBits)int.Parse(CbStopBits.Text);//停止位
                if (sp.IsOpen)
                {
                    sp.Close();
                    sp.Open();
                }
                else
                {
                    sp.Open();
                }
                textBox2.AppendText("[" + DateTime.Now + "]串口已打开:" + CbCom.Text + "\r\n");
                comboBox4.Enabled = false;
                CbBaudRate.Enabled = false; 
                CbCom.Enabled = false; 
                CbDataBits.Enabled = false;
                CbStopBits.Enabled = false;
                button1.Text = "关闭串口";

            }
            else
            {
                if (sp.IsOpen)
                    sp.Close();
                textBox2.AppendText("[" + DateTime.Now + "]串口已关闭:" + CbCom.Text + "\r\n");
                button1.Text = "打开串口";
                comboBox4.Enabled = true;
                CbBaudRate.Enabled = true;
                CbCom.Enabled = true;
                CbDataBits.Enabled = true;
                CbStopBits.Enabled = true;
            }

三、发送数据:hex十六进制发送或ascll发送

 if (sp.IsOpen)
            {
                try
                {
                    if (radioSendHex.Checked)//十六进制发送数据
                    {
                        Byte[] strbyte = HexStringToBytes(textBox1.Text);
                        sp.Write(strbyte, 0, strbyte.Length);//发送数据
                    }
                    else//ascll发送数据
                    {
                        sp.Write(textBox1.Text);//发送数据
                    }
                    textBox2.AppendText("[" + DateTime.Now + "]发送→:" + textBox1.Text+ "\r\n");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("错误:" + ex.Message);
                }
            }
            else
            {
                MessageBox.Show("请先打开串口!");
            }

四、十六进制字符串转byte【】 

private  byte[] HexStringToBytes(string hs)//十六进制字符串转byte
        {
            string a = hs.Replace(" ", "");
            int bytelength = 0;
            if (a.Length % 2 == 0)
            {
                bytelength = a.Length / 2;
            }
            else
            {
                bytelength = a.Length / 2 + 1;
            }
            byte[] b = new byte[bytelength];
            //逐个字符变为16进制字节数据
            for (int i = 0; i < bytelength; i++)
            {
                if (i == bytelength - 1)
                {
                    b[i] = Convert.ToByte(a.Substring(i * 2), 16);
                }
                else
                {
                    b[i] = Convert.ToByte(a.Substring(i * 2, 2), 16);
                }
            }
            //按照指定编码将字节数组变为字符串
            return b;
        } 

 五、接收数据:hex十六进制接收或ascll接收

private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)//接收数据
        {
            int len = sp.BytesToRead;//获取可以读取的字节数

            byte[] buff = new byte[len];//创建缓存数据数组

            sp.Read(buff, 0, len);//把数据读取到buff数组

            Invoke((new Action(() => {//C# 3.0以后代替委托的新方法
                if (radioRecvHex.Checked)//hex接收数据
                {
                    textBox2.AppendText("[" + DateTime.Now + "]接收←:" + BitConverter.ToString(buff, 0, buff.Length).Replace("-", " ") + "\r\n");
                }
                else
                {
                   textBox2.AppendText("[" + DateTime.Now + "]接收←:" + Encoding.Default.GetString(buff)+"\r\n");//对话框追加显示数据
                }

            })));

        }

六、定时发送 

private void OnTmrTrg(object sender, System.Timers.ElapsedEventArgs e)
        {
            lock (obj)
            {
                if (textBox1.Text.Length > 0)
                {
                    if (sp.IsOpen)
                    {
                        Invoke((new Action(() => {//C# 3.0以后代替委托的新方法
                            if (radioSendHex.Checked)//十六进制发送数据
                            {
                                Byte[] strbyte = HexStringToBytes(textBox1.Text);
                                sp.Write(strbyte, 0, strbyte.Length);//发送数据
                            }
                            else//ascll发送数据
                            {
                                sp.Write(textBox1.Text);//发送数据
                            }
                            textBox2.AppendText("[" + DateTime.Now + "]定时发送→:" + textBox1.Text + "\r\n");
                        })));
                       
                    }
                }
            }
        } 

private void checkBox1_CheckedChanged(object sender, EventArgs e)//定时发送复选框改变
        {
            if(checkBox1.Checked)
            {
                tmr.Interval = (double)numericUpDown4.Value;
                tmr.Enabled = true;
            }
            else
            {
                tmr.Enabled = false;
            }
        }

七、将接收到的消息导出txt文件

SaveFileDialog saveFileDialog = new SaveFileDialog();
            //设置文件标题
            saveFileDialog.Title = "导出CSV文件";
            //设置文件类型
            saveFileDialog.Filter = "txt文件(*.txt)|*.txt";
            //设置默认文件类型显示顺序
            saveFileDialog.FilterIndex = 1;
            //是否自动在文件名中添加扩展名
            saveFileDialog.AddExtension = true;
            //是否记忆上次打开的目录
            saveFileDialog.RestoreDirectory = true;
            //设置默认文件名
            saveFileDialog.FileName = "";
            //按下确定选择的按钮
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                FileStream fs = new FileStream(saveFileDialog.FileName.ToString(), FileMode.Append);
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                sw.Write(textBox2.Text);
                //释放资源
                sw.Close();
                fs.Close();
                MessageBox.Show("导出成功");
            }

  • 11
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Linux系统中,使用C语言编程进行串口通信可以通过相关的系统调用函数来实现。 首先,需要打开串口设备文件,可以使用open()函数来实现。例如,打开串口1的设备文件可以使用以下代码: ```c int fd; fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("无法打开串口"); return -1; } ``` 接下来,需要对串口进行一些初始化设置,可以使用tcgetattr()函数获取原来的串口参数,然后根据需求进行修改,再使用tcsetattr()函数将修改后的参数设置回去。例如,将波特率设置为9600,数据位设置为8位,奇偶校验位设置为无校验,停止位设置为1位的代码如下: ```c struct termios options; tcgetattr(fd, &options); cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd, TCSANOW, &options); ``` 然后,可以使用read()函数从串口读取数据,使用write()函数向串口发送数据。例如,从串口读取一个字节的数据并打印出来的代码如下: ```c char buffer; if (read(fd, &buffer, 1) > 0) { printf("%c\n", buffer); } ``` ```c char data[] = "Hello, Serial!"; write(fd, data, sizeof(data)); ``` 最后,使用close()函数关闭串口设备文件。 需要注意的是,串口通信的相关设置可能受到系统和硬件的影响,具体设置时可能需要进一步了解和调试。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值