C#下传感器和PC之间的串口通信问题
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 HeartVoice
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private System.IO.Ports.SerialPort com;
private void Form1_Load(object sender, EventArgs e)
{
com = new System.IO.Ports.SerialPort();
//获取所有的串口
this.com.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.IOrecieve);
Microsoft.VisualBasic.Devices.Computer pc = new Microsoft.VisualBasic.Devices.Computer();
foreach (string s in pc.Ports.SerialPortNames)
{
this.Comcombox.Items.Add(s);
}
}
private void IOrecieve(object sender, SerialDataReceivedEventArgs e)
{
byte[] readbuffer = new byte[com.ReadBufferSize];
com.Read(readbuffer, 0, com.BytesToRead);
for (int i = 0; i < com.BytesToRead; i++)
{
int temp = (int)readbuffer[i];
Data.Items.Add(temp.ToString());
}
}
private void OpenCOM_Click(object sender, EventArgs e)
{
if (Comcombox.SelectedItem != null)
{
com.Close();
com.PortName = Comcombox.SelectedItem.ToString();
com.BaudRate = 115200;
com.ReadBufferSize = 1024;
com.WriteBufferSize = 1024;
com.DataBits = 8;
com.StopBits = System.IO.Ports.StopBits.One;
com.Open();
com.DiscardInBuffer();
com.DiscardOutBuffer();
if (com.IsOpen)
{
OpenCOM.Enabled = false;
MessageBox.Show("串口已经打开!");
}
else
{
MessageBox.Show("串口打来失败!");
}
}
else
{
MessageBox.Show("请选择串口!");
}
for (int i = 1; i < 5; i++)
{
string num = i.ToString() + "K";
this.COMHZ.Items.Add(num);
}
this.COMHZ.DropDownStyle = ComboBoxStyle.DropDownList;
this.COMHZ.SelectedIndex = 0;
this.Enhance.Minimum = 1;
this.Enhance.Maximum = 10;
this.Enhance.Increment = 1;
}
private void CloseCOM_Click(object sender, EventArgs e)
{
com.Close();
OpenCOM.Enabled = true;
MessageBox.Show("串口已关闭!");
}
private void Start_Click(object sender, EventArgs e)
{
if (!com.IsOpen)
{
MessageBox.Show("请选择串口并打开!");
}
else
{
byte[] command = new byte[2];
command[0] = 0x20;
command[1] = 0x32;//开始采样命令
string comstring = Encoding.UTF8.GetString(command);
com.Write(comstring);
}
}
private void Close_Click(object sender, EventArgs e)
{
if (!com.IsOpen)
{
MessageBox.Show("请选择串口并打开!");
}
else
{
byte[] command = new byte[2];
command[0] = 0x20;
command[1] = 0x33;//停止采样命令
string comstring = Encoding.UTF8.GetString(command);
com.Write(comstring);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (com.IsOpen)
{
byte[] command = new byte[2];
command[0] = 0x20;
command[1] = 0x33;//停止采样命令
string comstring = Encoding.UTF8.GetString(command);
com.Write(comstring);
com.DiscardInBuffer();
com.DiscardOutBuffer();
com.Close();
}
}
private void COMHZ_SelectedIndexChanged(object sender, EventArgs e)
{
byte[] command1 = new byte[3];//调节采样频率命令
byte[] command2 = new byte[3];
byte[] command3 = new byte[3];
byte[] command4 = new byte[3];
command1[0] = command2[0] = command3[0] = command4[0] = 0x20;
command1[1] = command2[1] = command3[1] = command4[1] = 0x37;
command1[2] = 0x0;
command2[2] = 0x1;
command3[2] = 0x2;
command4[2] = 0x3;
string comstring;
switch (this.COMHZ.SelectedIndex)
{
case 0:
comstring = Encoding.UTF8.GetString(command1);
com.Write(comstring);
break;
case 1:
comstring = Encoding.UTF8.GetString(command2);
com.Write(comstring);
break;
case 2:
comstring = Encoding.UTF8.GetString(command3);
com.Write(comstring);
break;
case 3:
comstring = Encoding.UTF8.GetString(command4);
com.Write(comstring);
break;
default:
break;
}
}
private void Enhance_ValueChanged(object sender, EventArgs e)
{
byte[] command1 = new byte[] { 0x20, 0x34, 0x00 };
byte[] command2 = new byte[] { 0x20, 0x34, 0x01 };
byte[] command3 = new byte[] { 0x20, 0x34, 0x02 };
byte[] command4 = new byte[] { 0x20, 0x34, 0x03 };
byte[] command5 = new byte[] { 0x20, 0x34, 0x04 };
byte[] command6 = new byte[] { 0x20, 0x34, 0x05 };
byte[] command7 = new byte[] { 0x20, 0x34, 0x06 };
byte[] command8 = new byte[] { 0x20, 0x34, 0x07 };
byte[] command9 = new byte[] { 0x20, 0x34, 0x08 };
byte[] command10 = new byte[] { 0x20, 0x34, 0x09 };//设置放大倍数命令
string comstring;
int num = Convert.ToInt32(this.Enhance.Value.ToString());
switch (num)
{
case 1:
comstring = Encoding.UTF8.GetString(command1);
com.Write(comstring);
break;
case 2:
comstring = Encoding.UTF8.GetString(command2);
com.Write(comstring);
break;
case 3:
comstring = Encoding.UTF8.GetString(command3);
com.Write(comstring);
break;
case 4:
comstring = Encoding.UTF8.GetString(command4);
com.Write(comstring);
break;
case 5:
comstring = Encoding.UTF8.GetString(command5);
com.Write(comstring);
break;
case 6:
comstring = Encoding.UTF8.GetString(command6);
com.Write(comstring);
break;
case 7:
comstring = Encoding.UTF8.GetString(command7);
com.Write(comstring);
break;
case 8:
comstring = Encoding.UTF8.GetString(command8);
com.Write(comstring);
break;
case 9:
comstring = Encoding.UTF8.GetString(command9);
com.Write(comstring);
break;
case 10:
comstring = Encoding.UTF8.GetString(command10);
com.Write(comstring);
break;
}
}
}
}
哪位高手大侠给看看这段程序到底哪儿错了?为什么读出的数据中有那么多0啊???? --------------------编程问答-------------------- 程序没看出问题,你说的那么多0是连续的吗,还是间隔的?
如果是间隔的那说明你接收到的数据,不是使用ASCII编码的,你试试UNICODE编码,另外将它转成string看看是否有你想要的效果 --------------------编程问答-------------------- 是断续的,一段是0,一段是数据。而且用端口测试程序显示是没0的是正确的 --------------------编程问答-------------------- private void IOrecieve(object sender, SerialDataReceivedEventArgs e)
{
string readbuffer = "";
readbuffer =com.ReadExisting();
Data.Items.Add(readbuffer);
}
如果readbuffer 有乱码的话,可能就要进行编码格式的转换了,再与端口测试程序进行比较看看 --------------------编程问答-------------------- 感觉应该对照传感器的通讯手册,严格按照格式向com口传送字串和分析收到的字串。 --------------------编程问答-------------------- [Quote=引用 3 楼 xingyuebuyu 的回复:]
private void IOrecieve(object sender, SerialDataReceivedEventArgs e)
{
string readbuffer = "";
readbuffer =com.ReadExisting();
Data.Items.Add(readbuffer);
}
如果readbuffer 有乱码的话,可能就要进行编码格式的转换了,再与端口测试程序进行比较看看
[/Quote
大哥。我改过之后没有什么乱码。是h,i,j之类的字符。是不是他们对应的ASCII码对应的值是100多啊?还怎么改啊? --------------------编程问答-------------------- list框中出现的是这种样式的:
2kj
iiiijiii
h
f
g
i
…… --------------------编程问答-------------------- 那端口测试程序收到的内容是什么样的?
两者有相同的吗? --------------------编程问答-------------------- 现在我把 private void IOrecieve(object sender, SerialDataReceivedEventArgs e)
{
int temp=com.readbyte();
data.items.add(temp.tostring());
}
这样的话数据读取是正确的。
但是现在又有新的问题
传感器协议如下:
(2)、启动采样:
接收(2字节): 20h(开始符) 32h(命令字)
发送(2字节): 20h(开始符) 32h
(3)、停止采样:
接收(2字节): 20h(开始符) 33h(命令字)
发送(2字节): 20h(开始符) 33h
(4)、设置放大级别:
接收(3字节): 20h(开始符) 34h(命令字) xxh(放大级别0h-9h)
发送(2字节): 20h(开始符) 34h
(5)、设置基线位置:
接收(3字节): 20h(开始符) 35h(命令字) xxh(基线位置0h-4h)
发送(2字节): 20h(开始符) 35h
(6)、设置采样频率:
接收(3字节): 20h(开始符) 37h(命令字) xxh(采样频率0h-3h)
发送(2字节): 20h(开始符) 37h
现在要在读取数据时可以调节放大基数和采样频率。但是向传感器发送命令时,会返回数据,那么不就会混入到采样数据中么?请问有什么办法解决。
--------------------编程问答-------------------- good good study ,day day up --------------------编程问答-------------------- 要调节放大基数和采样频率时,先停止采样,调节完毕后,确认设置成功后,再重新开始采样. --------------------编程问答-------------------- 它要求的是在采样过程中调节采样频率。有什么可以解决的办法么? --------------------编程问答-------------------- 这个不是很明白,需要多多学习! --------------------编程问答-------------------- 你可以在采样的过程中下command,只要你在收到的内容中能查找到判断command成功的内容,只是必顶command成功后返回的内容和采样的数据不相同才可以.
比如你发送 20h(开始符) 35h ,要接收到20h(开始符) 35h(命令字) xxh(基线位置0h-4h) 才能判断 command下成功了,不然就还是之前的设定,但是如果此时采样返回的数据和你判断成功的内容一样或相似就可能区分不出command是成功了还是只是采样的数据,除非采样返回的数据格式和这个完全不一样,不然就可以在采样的过程中直接下command调节放大基数和采样频率
补充:.NET技术 , C#