C# 编程实现串口通信
http://blog.sina.com.cn/s/blog_6c67dab30101p3vn.html
-------------------------------------------------------------------------------
public partial class Form1 : Form
{
int k = 0;
int[] crc_data1 = { 0, 0 };
int[] crc_data2 = { 0, 0, 0, 0, 0 };
int[] crc_data3 = { 0, 0, 0, 0, 0 };
int x = 0;
short qtemp;
byte[] new_byte1 = { 0, 0, 0, 0, 0, 0, 0 };
SolidBrush bush1 = new SolidBrush(Color.Red);
SolidBrush bush2 = new SolidBrush(Color.Green);
public Form1()
{
InitializeComponent();
} //串口初始化
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.Open();
}
//向水浸传感器发送读指令
private void timer1_Tick(object sender, EventArgs e)
{
byte[] boutdata1 = { 0x01, 0x04, 0x01, 0xE3 };
serialPort1.Write(boutdata1, 0, 4);
} //触发事件,读取温度传感器返回数据
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(100);
int byte_num1 = serialPort1.Read(new_byte1, 0, 7);
this.Invoke(new EventHandler(DisplayText));
} private void DisplayText(object sender, EventArgs e)
{
if (new_byte1[0] == 1) //水浸传感器
{
for (int i = 0; i < 2; i++)
crc_data1[i] = (int)new_byte1[i];
int[] crc1 = crc16(crc_data1);
if (crc1[0] == new_byte1[2] && crc1[1] == new_byte1[3]) //校验CRC
alarm1(); //显示,红灯报警,绿灯正常
else
MessageBox.Show("校验码错误,数据无效!", "");
byte[] boutdata2 = { 0x02, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xF9 }; //发送温度传感器数据
serialPort1.Write(boutdata2, 0, 8);
}
if (new_byte1[0] == 2 && new_byte1[1] == 3) //温度传感器
{
for (int i = 0; i < 5; i++)
crc_data2[i] = (int)new_byte1[i];
int[] crc2 = crc16(crc_data2);
if (crc2[0] == new_byte1[5] && crc2[1] == new_byte1[6])
DisplayText2(); //显示温度并画出温度曲线
else
MessageBox.Show("校验码错误,数据无效!", "");
byte[] boutdata3 = { 0x50, 0x03, 0x00, 0x03, 0x00, 0x01, 0x79, 0x8B }; //发送烟感传感器数据
serialPort1.Write(boutdata3, 0, 8);
}
if (new_byte1[0] == 80 && new_byte1[1] == 3) //烟感传感器
{
for (int i = 0; i < 5; i++)
crc_data3[i] = (int)new_byte1[i];
int[] crc3 = crc16(crc_data3);
if (crc3[0] == new_byte1[5] && crc3[1] == new_byte1[6])
alarm3(); //显示,红灯报警,绿灯正常
else
MessageBox.Show("校验码错误,数据无效!", "");
}
} //关闭串口,退出程序
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Close();
Close();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
}
}
-----------------------------------------------------------------------------------
其实这是很简单的工作,只是我初次接触而已,做做笔记,方便以后使用时调用~
.PortName 串口名称,COM1, COM2等。
.BaudRate 波特率,也就是串口通讯的速度,进行串口通讯的双方其波特率需要相同,如果用PC连接其他非PC系统,一般地,波特率由非PC系统决定。
.Parity 奇偶校验。可以选取枚举Parity中的值
.DataBits 数据位
.StopBits 停止位,可以选取枚举StopBits中的值
.Handshake 握手方式,也就是数据流控制方式,可以选取枚举Handshake中的值。
|
Close |
关闭端口连接,将 IsOpen 属性设置为False,并释放内部 Stream 对象 |
|
Open |
打开一个新的串行端口连接 |
|
Read |
从 SerialPort 输入缓冲区中读取数据字节数 |
|
ReadByte |
从 SerialPort 输入缓冲区中同步读取一个字节 |
|
ReadChar |
从 SerialPort 输入缓冲区中同步读取一个字符 |
|
ReadLine |
一直读取到输入缓冲区中的 NewLine 值 |
|
ReadTo |
一直读取到输入缓冲区中指定 value 的字符串 |
|
Write |
已重载。将数据写入串行端口输出缓冲区 |
|
WriteLine |
将指定的字符串和 NewLine 值写入输出缓冲区 |
|
DiscardInBuffer DiscardOutBuffer |
清空接收缓冲区数据 清空输出缓冲去数据 |
属性说明
|
名 称 |
说 明 |
|
BaseStream |
获取 SerialPort 对象的基础 Stream 对象 |
|
BaudRate |
获取或设置串行波特率 |
|
BreakState |
获取或设置中断信号状态 |
|
BytesToRead |
获取接收缓冲区中数据的字节数 |
|
BytesToWrite |
获取发送缓冲区中数据的字节数 |
|
CDHolding |
获取端口的载波检测行的状态 |
|
CtsHolding |
获取“可以发送”行的状态 |
|
DataBits |
获取或设置每个字节的标准数据位长度 |
|
DiscardNull |
获取或设置一个值,该值指示 Null 字节在端口和接收缓冲区之间传输时是否被忽略 |
|
DsrHolding |
获取数据设置就绪 (DSR) 信号的状态 |
|
DtrEnable |
获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号 |
|
Encoding |
获取或设置传输前后文本转换的字节编码 |
|
Handshake |
获取或设置串行端口数据传输的握手协议 |
|
IsOpen |
获取一个值,该值指示 SerialPort 对象的打开或关闭状态 |
|
NewLine |
获取或设置用于解释 ReadLine( )和WriteLine( )方法调用结束的值 |
|
Parity |
获取或设置奇偶校验检查协议 |
|
ParityReplace |
获取或设置一个字节,该字节在发生奇偶校验错误时替换数据流中的无效字节 |
|
PortName |
获取或设置通信端口,包括但不限于所有可用的 COM 端口 |
|
ReadBufferSize |
获取或设置 SerialPort 输入缓冲区的大小 |
|
ReadTimeout |
获取或设置读取操作未完成时发生超时之前的毫秒数 |
|
ReceivedBytesThreshold |
获取或设置 DataReceived 事件发生前内部输入缓冲区中的字节数 |
|
RtsEnable |
获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号 |
|
StopBits |
获取或设置每个字节的标准停止位数 |
|
WriteBufferSize |
获取或设置串行端口输出缓冲区的大小 |
|
WriteTimeout |
获取或设置写入操作未完成时发生超时之前的毫秒数 |
双方通讯时,一般都需要定义通讯协议,即使最简单的通过串口发送文本聊天的程序。
通常是在当一方按下回车时,将其所数据的文本连同换行符发给另一方。在这个通讯事例中,协议桢是通过换行符界定的,每一桢数据都被换行符隔开,这样就很容易识别出通讯双发发送的信息。
在以上的例子中,可以用WriteLine()来发送数据,用ReadLine()来读取数据。WriteLine发送完数据后,会将换行符作为数据也发送给对方。ReadLine()读取数据时,直至遇到一个换行符,然后返回一个字符串代表一行信息。换行符可以通过SerialPort 的属性NewLine来设置。一般地,Windows将CrLn作为换行符,而在Linux下,换行符则只用一个Ln表示。
ReadLine()方法是阻塞的,直至遇到一个换行符后返回。在读取数据时,如果一直没有遇到换行符,那么在等待ReadTimeout时间后,抛出一个TimeoutException。默认情况下,ReadTimeout为InfiniteTimeout。这样,ReadLine一直处于阻塞状态,直至有新一行数据到达。
WriteLine()方法也是阻塞的,如果另一方不能及时接收数据,就会引起TimeoutException异常。
由于ReadLine()和WriteLine()方法都是阻塞式的,在程序使用SerialPort 进行串口通讯时,一般应该把读写操作交由其他线程处理,避免因为阻塞而导致程序不响应。
读写字节或字符数据
对于字节或字符数据,用Read()方法来读数据,该方法需要一个字节或字符数组作为参数来保存读取的数据,结果返回实际读取的字节或字符数。写数据使用Write()方法,该方法可以将字节数组、字符数据或字符串发送给另一方。
如果通讯双方交换的数据位字节流数据,要构建一个使用的串口通讯程序,那么双方应该定义数据桢格式。通常数据桢由桢头和桢尾来界定。
发送数据比较简单,只需要将构造好的数据用Write()方法发送出去即可。
接收数据则比较复杂,通讯是以字节流的形式到达的,通过调用一次Read()方法并不能确保所读取的数据就是完整一桢。因此需要将每次读取的数据整合在一起,对整合后的数据进行分析,按照定义的桢格式,通过桢头和桢尾,将桢信息从字节流中抽取出来,这样才能获取有意义的信息。
除了利用Read()方法来读数据,还可以使用ReadExisting()方法来读取数据。该方法读取当前所能读到的数据,以字符串的形式返回。
C# 编程实现串口通信的更多相关文章
- VS2015 编写C++的DLL,并防止DLL导出的函数名出现乱码(以串口通信为例,实现串口通信)
参考链接:https://blog.csdn.net/songyi160/article/details/50754705 1.新建项目 建立好的项目界面如下: 接着在解决方案中找到[头文件]然后右击 ...
- Python编程实现USB转RS485串口通信
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:Python编程 ...
- QT串口通信编程
QT串口编程 文件夹目录结构如下图所示 设计的示例界面如下图所示 首先在项目文件里面添加一句 QT += serialport SerialPortDemo.pro文件如下: #----------- ...
- C\C++串口通信编程的一点技术记录
新工作接的第一个活,要写一个配合设备调试的上位机程序. 除了MFC界面的部分,就是要处理几条命令. 串口通信部分代码借鉴的是这一篇文章:http://blog.sina.com.cn/s/blog_a ...
- .NET 串口通信中断接收,包含0X1A(作为EOF)
.NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...
- mfc 调用Windows的API函数实现同步异步串口通信(源码)
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...
- 【C51】UART串口通信
我们常需要单片机和其他模块进行通信,数据传输,常用的方式就是串口通信技术. 常用来 单片机<-->电脑, 单片机<-->单片机之间通信. 串行通信 versus 并行通信 并 ...
- LabVIEW串口通信
Instrument I/O 利用LabVIEW内置的驱动程序库和具有工业标准的设备驱动软件,可对 GPIB(通用接口总线).Ethernet(以太网)接口.RS-232(标准串行接口总线)/RS-4 ...
- C#初入串口通信(串行通信)总结
使用WinFrom来实现: 首先要知道串口通信协议以及原理 原理大概提一下:要自己翻阅看.(http://book.51cto.com/art/200911/162532.htm或者http://hi ...
随机推荐
- Git_撤销修改
自然,你是不会犯错的.不过现在是凌晨两点,你正在赶一份工作报告,你在readme.txt中添加了一行: $ cat readme.txt Git is a distributed version co ...
- jquery 图片预加载
/图片无序预加载 (function($){ function Preload(imgs,fns){ this.imgs=(typeof imgs==="string")?[img ...
- [置顶] iOS中让省略号垂直居中
在显示等待框时,一般要求在提示信息后面加个省略号,但中文输入法下输入的省略号是在底部对齐,但中 文的习惯是省略号垂直居中对齐,最后找到下面这个方法来显示垂直居中的省略号: 中文和英文输入法下一样: o ...
- Backup your Android without root or custom recovery -- adb backup
ecently discovered a neat new way to back up apps on my Android without having to use Titanium Backu ...
- Selenium2+python自动化41-绕过验证码(add_cookie)
前言 验证码这种问题是比较头疼的,对于验证码的处理,不要去想破解方法,这个验证码本来就是为了防止别人自动化登录的.如果你能破解,说明你们公司的验证码吗安全级别不高,那就需要提高级别了. 对于验证码,要 ...
- Google浏览器Chrome安装失败,错误代码0xa0430721解决办法
谷歌浏览器安装失败错误代码0xa0430721 的解决办法 这个是因为我们删除的时候没有删除干净.然后又重装了谷歌浏览器.所以就出现这个问题了. 1.删除旧的配置文件,比如C:\Documents a ...
- maven生命周期(lifecycle)—— maven权威指南学习笔记(四)
定义: 生命周期是包含在一个项目构建中的一系列有序的阶段 举个例子来说就是maven 对一个工程进行: 验证(validate) …… 编译源码(compile) …… 编译测试源码(test-com ...
- hdu1166 敌兵布阵(线段树 求区间和 更新点)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- russian-doll-envelopes
https://leetcode.com/problems/russian-doll-envelopes/ // Use map (Russian doll number -> vector o ...
- Informatica 常用组件Lookup之二 已连接和未连接的查找
可以配置一个已连接的查找转换,以从映射管道中直接接收输入:您也可以配置一个未连接的查找转换,以从其它转换的表达式结果中接收输入. 已连接的查找 未连接的查找 直接从管道接收输入值. 从其它转换的 :L ...