Introduction
Whoever work with standard RS232 components from a .NET environment, and need real, embedded-like RS232 communication, realize in a short time that the component needs to be wrapped, or at least, additionally supported by custom software. I designed this tutorial because I couldn*t find something similar on the web. The code is an excerpt from a huge GPS tracking application, and it proved to work nicely. Just to mention, that there are other methods for RS232 communication such as using hand-shaking protocols, and hardware/software enabled pin control.
Background
I won*t go in to the details of basic RS232 communication, except that it is a point-to-point communication between two hosts, and they could be computers or embedded devices. My point here will be the software implementation part, using C# in a .NET 2.0 environment to be precise, but the principles are adoptable to any other language and IDE. Also, the type of data I*m going to send/read is string, but with little more effort, the code can be adopted to send/receive any type of serializable data. One more restriction, the demo code is adopted to receive a huge block of data and then process it. Another way is to continually append read data to some FIFO buffer, and do an online parsing of whatever data has arrived at the time (search for delimiters inside the arrived data before the reading ends), for continual receiving of data without any pause between two packets.
Methods used
We will need as few as the following four methods to do the job:
void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e);
private void ReadData(object s, EventArgs e);
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e);
private void AddRecieve(object s, EventArgs e);
Using the code
The first thing we need for an RS232 communication is a SerialPort component from the Components tab in the form editor's toolbox. The component itself supports both synchronous and asynchronous (event driven) communication. That means, for reading the port, we can use:
1. Blocking methods
Wait for the hardware to do the job, and then return to the app, so the read operation waits until the reading is finished (a few methods give us different ways of reading the port).
2. Non-blocking methods
We don*t wait in a loop for reading the port, we use interrupts, so when the port has something in an input buffer, the SerialPort component alarms us via delegate methods, such as DataRecieved.
Here, we will use event driven communication, because in my belief, this is the only true RS232 robust communication. So, lets begin. Let*s create some private members for our form, like:
Collapse Copy Code
private System.Timers.Timer timer1;
private StringBuilder recievedB = new StringBuilder();
private string recievedData;
Now, what we first need to do is a basic setup of the component we put on our form, meaning, set the component name (say, serialPort1), baudRate, parity, stopBits, etc. On the Events tab in Properties window, we create the delegate for DataRecieved (actually, the MVS will do that for us when we desire it), and name it serialPort1_DataReceived(). We will see later what we need the timer for. As for the recieveB, we use a StringBuilder class because it has a nice method Append, which doesn*t recreate the string every time we do a concatenation, rather it uses something like linking lists of strings (actually, you don*t have to know how it works). And finally, when all data has arrived, we will need a string to hold the received data needed for further parsing, recievedData. Next comes the coding of the delegate method we created. If we intend to update some controls in the form (as is the usual case), we need to call this.Invoke(some_delegate_method), because of the cross-thread operations. Check MSDN help for help on Invoke. We will create the method like this:
Collapse Copy Code
private void serialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(AddRecieve));
}
And next, we need to create and code the actual delegate to perform the reading:
Collapse Copy Code
private void AddRecieve(object s, EventArgs e)
{
string st = serialPort1.ReadExisting();
recievedB.Append(st);
timer1.Interval = 1000;
timer1.Start();
}
Let*s comment this code a bit. First, we call ReadExisting, which means reading anything that is in the SerialPorts input buffer. There can be a few bytes, or as many as a few kilobytes of data. Anyway, we read what*s arrived up to now, and Append that to our main holder for the received data 每 the recieveB (the StringBuilder class instance).
Now, the second part of this method. How do we know that the other side of the communication link finished sending data, so we can process it? Think logically for yourselves# For those who figured it out, yes, we know this when for some time (predefined time) there is nothing to read, meaning the event serialPort1_DataRecieved() isn*t firing for some time. This time can vary from 30ms (arguable) up to a minute, it's up to us to decide. In this case, we*ll be using a one second interval so called deadTimePeriod (there is a term for a similar thing, called readTimeout). What do we do with this timer? We crate the timer in the form's constructor, add the onElapsed method for firing up when the time has elapsed, and, I prefer the garbage collector not to destroy my timer. On every firing of the serialPort1_DataReceived() event, we restart the timer1 to the initial interval (in our case 1s), and start it again. Here is the form's construction:
Collapse Copy Code
public Form1()
{
InitializeComponent();
serialPort1.Open();
timer1 = new System.Timers.Timer(1000);
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);
GC.KeepAlive(timer1);
}
The method that will execute on the timer overflow is called timer1_Elapsed. Following that, we will code the method as:
Collapse Copy Code
void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Stop();
this.Invoke(new EventHandler(ReadData));
}
First, we stop the timer, and second, we do the final receiving of the data. And again, just in case, we call Invoke. The actual method for reading the received data and parsing it looks something like:
Collapse Copy Code
private void ReadData(object s, EventArgs e)
{
recievedData = recievedB.ToString();
int j = recievedB.Length;
if (recievedData.Contains("RMR0" /*some delimiting end*/))
{
labelCard.Text = "Read " + j.ToString() + " bytes...";
// finally we have the data, we need to process it
ProcessData();
}
else
{
DialogResult dr = MessageBox.Show("Bad card data detected!," +
" Read good data?", "Error!",
MessageBoxButtons.YesNo,
MessageBoxIcon.Error);
if (dr == DialogResult.Yes)
{
}
}
}
Of course, the method ProcessData() is open for you to code it. The send method is trivial, on buttonSend_Click, just send whatever you need - in this case, the text from textBoxSend. This could be done as an asynchronous method as well, using standard asynchronous method, invoking in .NET 2.0.
Points of Interest
Finally, I feel I need to explain the whole process again. The communication points are A and B. Both sides open their ports, and side B starts sending bytes over the comm. link. A serialPort1 component on side A is receiving data in almost a byte-by-byte basis, and is filling some sort of a buffer. The point here, was knowing when side B has sent us all data it wished to send in this transmission so side A can start examining the data in whole. Point A does this by using a timer which co
没有合适的资源?快使用搜索试试~ 我知道了~
c#串口调试程序+485多机通信

共151个文件
dll:33个
cs:12个
bak:11个


温馨提示
1.c#串口调试软件(带原程序)。 2.压缩文件里包括c#串口调试软件,KEIL程序(计数器),proteus仿真485多机通信。 3.使用上位机软件读取485网的计数器数据,非常好的整套系统程序(适用初学c#,单片机)。 4.需要安装虚拟串口,framework3.5,proteus7.7,keil等。 5.如有问题请回复,我会尽量答复的。
资源推荐
资源详情
资源评论






















格式:x-rar 资源大小:3.0MB

格式:pdf 资源大小:121.2KB 页数:2







收起资源包目录





































































































共 151 条
- 1
- 2

UnityWind
- 粉丝: 11
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 单片机温度控制系统设计方案.doc
- 数字技术与网络传播背景下的广告生存形态最新年文档.doc
- 浅析电气工程及其自动化的发展创新.docx
- C5单片机电子台历的设计与制作.ppt
- (源码)基于C语言汇编的EulixOS训练营在线作业.zip
- 套筒零件加工工艺分析研究编程.doc
- 企业IT建设与项目管理思想.docx
- 株洲服装产业物联网项目市场风险识别与衡量.doc
- 电子商务-本科专业审核评估自评分析报告模板.doc
- 信息与通信技术进展:计算理论与实践研讨会
- 全国计算机等级历年考试四级网络工程师过关练习711章.doc
- JSPSmart题库及试卷管理模块的与开发.doc
- 计算机网络技术在电子信息工程中的应用(1).docx
- 计算机网络安全论文(乱凑的).doc
- 我国P2P网络信贷信用风险影响因素分析.docx
- 基于简单神经网络模型实现图片分类的方法
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制

- 1
- 2
- 3
- 4
- 5
- 6
前往页