C#环境下与单片机串行通信的实践
1 引言
windows日照中考分数线环境下,主机和单片机之间实现串行通信可以利用api函数编写,但需要调用api函数,编写起来也比较复杂。但用户利用c# 中的serialport控件中的标准事件处理函数、事件和方法,就不必了解通信过程中的底层操作和记住相应api函数,从而能比较容易和高效地实现与单片机的串口通信。
1 引言
windows日照中考分数线环境下,主机和单片机之间实现串行通信可以利用api函数编写,但需要调用api函数,编写起来也比较复杂。但用户利用c# 中的serialport控件中的标准事件处理函数、事件和方法,就不必了解通信过程中的底层操作和记住相应api函数,从而能比较容易和高效地实现与单片机的串口通信。
2 c#主机和at89c51的连接
单片机有一个全双工的串行通讯口,所以单片机和电脑(ibm-pc机)之间可以方便地进行串口通讯。由于ibm-pc机串行口输出的是rs232电平,而单片机串口输出的是ttl电平,两者之间应有一个电平转换电路。本系统采用了专用芯片max232进行转换,如图1所示。
单片机有一个全双工的串行通讯口,所以单片机和电脑(ibm-pc机)之间可以方便地进行串口通讯。由于ibm-pc机串行口输出的是rs232电平,而单片机串口输出的是ttl电平,两者之间应有一个电平转换电路。本系统采用了专用芯片max232进行转换,如图1所示。
图中,imp-pc机的下传命令和数据由ibm-pc机的txd端(rs-232电平)发送,经max232转换为ttl电平被at89c51串行口所接收。同样,at89c51的上传代码(ttl电平)由max232转换rs-232电平加以发送,经过ibm-pc机的rxd端,并由其内部的串行口变换为ttl电平。
图1 c#主机和单片机的接口电路
以一个简单的实例加以分析。假设单片机采集到的一个数据(开关量)已放在发送缓冲区,pc机在每次通信时向单片机发送8位二进制数据;单片机接收到后据此数据点亮相应氖灯,同时将发送缓冲区中的8位开关量发送给pc机(全双工通信)。本串行通信程序分pc机主机通程序和单片机串行通信程序两部分。
3 pc机主机的串行通信程序
pc机c#下的程序窗体控件如附表所列,表中列出了本文所用到的5个控键。其中,serialport用于设置串口名称、串行通信波特率和提供编制串行通信程序方法。label和button用于编制数据在屏幕上的显示界面,maskedtextbox用于输入发送给单片机的控制命令。
图2 pc机与单片机的串行通信界面图
pc机在c#下窗口的设计界面如图2所示。图中,“发送的命令”栏中用于在键盘上输入需
要发送的数据,“接受到的数据”栏用于显示由单片机发送来的开关量。例如:在该栏中输入10101010数据后点击发送按纽,读者一方面可以在“接受到的数据”栏中看到单片机发送过来的开关量,另一方面也可以在单片机的对应氖灯上观察到从c#主机端接收到的数据10101010。
3.1 serialport控件常用属性
serialport控件位于工具箱的“组件”选项卡中。使用时直接在设计窗口中拖放实例,它的常用属性如下:
(1) portname用于设置串行口名称,一般pc机上有com1、com2等多个串口,该属性用于设定使用哪个串行口进行通信。
(2) baudrate用于设定串行通信所用的通信波特率,一般为2400,4800,9600等。
为了实现pc机在c#下与单片机的串行通信,可采用如下方法:
(1) 使用open()打开串行口,因为每次通信前先要打开串行口。
(2) write(byte[] buffer,int offset,int count):将字节型数组buffer中的数据发送到串口,offset为数组起始索引,count表示发送数据的数目,如write(buffer,1,3)则表示将buffer[1],buffer[2],buffer[3],三个字节型数据发送到缓冲区。林正英的鬼片
3.1 serialport控件常用属性
serialport控件位于工具箱的“组件”选项卡中。使用时直接在设计窗口中拖放实例,它的常用属性如下:
(1) portname用于设置串行口名称,一般pc机上有com1、com2等多个串口,该属性用于设定使用哪个串行口进行通信。
(2) baudrate用于设定串行通信所用的通信波特率,一般为2400,4800,9600等。
为了实现pc机在c#下与单片机的串行通信,可采用如下方法:
(1) 使用open()打开串行口,因为每次通信前先要打开串行口。
(2) write(byte[] buffer,int offset,int count):将字节型数组buffer中的数据发送到串口,offset为数组起始索引,count表示发送数据的数目,如write(buffer,1,3)则表示将buffer[1],buffer[2],buffer[3],三个字节型数据发送到缓冲区。林正英的鬼片
(3) read(char[] buffer,int offset,int count)用法同write,表示将数据从缓冲区读出。
(4) 使用close()关闭串口。
serialport控件所提供的发送和接受缓冲区可自行设置大小,默认情况下接收缓冲区为4096字节,发送缓冲区为2048字节,每次发送的数据都要先送入发送缓冲区,再由系统自动将数据逐个发送到串行口;每次接收数据时,串行口先将接收数据存入缓冲器队列,再由用户读取。
3.2 通讯程序
相应程序如下:
using system;
ic;
using systemponentmodel;
using system.data;
using system.drawing;
;
using system.windows.forms;
(4) 使用close()关闭串口。
serialport控件所提供的发送和接受缓冲区可自行设置大小,默认情况下接收缓冲区为4096字节,发送缓冲区为2048字节,每次发送的数据都要先送入发送缓冲区,再由系统自动将数据逐个发送到串行口;每次接收数据时,串行口先将接收数据存入缓冲器队列,再由用户读取。
3.2 通讯程序
相应程序如下:
using system;
ic;
using systemponentmodel;
using system.data;
using system.drawing;
;
using system.windows.forms;
namespace com
{
public partial class form1 : form
{
public form1()
initializecomponent();
}
private void form1_load(object sender, eventargs e)
{
setcomconfig();
}
private void button1_click(object sender, eventargs e)
{
);
}
{
public partial class form1 : form
{
public form1()
initializecomponent();
}
private void form1_load(object sender, eventargs e)
{
setcomconfig();
}
private void button1_click(object sender, eventargs e)
{
);
}
//设置串口初始化信息
private void setcomconfig()
{ //设置串口名为com1
serialport1.portname = "com1";
//设置波特率为2400
serialport1.baudrate = 2400;
//打开串口
serialport1.open();
}
//发送信息
private void senddata(string data)
{
byte[] senddata = new byte[1];//定义字节型数组用于暂存数据
senddata[0] = byte(data, 2);//将输入的数据转换为字节型数据
serialport1.write(senddata, 0, 1);//将数据发送到串口
private void setcomconfig()
{ //设置串口名为com1
serialport1.portname = "com1";
//设置波特率为2400
serialport1.baudrate = 2400;
//打开串口
serialport1.open();
}
//发送信息
private void senddata(string data)
{
byte[] senddata = new byte[1];//定义字节型数组用于暂存数据
senddata[0] = byte(data, 2);//将输入的数据转换为字节型数据
serialport1.write(senddata, 0, 1);//将数据发送到串口
}
//接受信息
private void receivedata()
{
byte[] sbufdata = new byte[1];//定义字节型数组用于暂存数据
ad(sbufdata, 0, 1);//从串口读取数据
receive.invoke(new eventhandler(delegate
海里的动植物 {
= string(sbufdata[0], 2);//将数据转换为二进制8位字符并返回该值
}));
}
private void serialport1_datare -ceived(object sender, system.io.ports.serialdatareceivedeventargs e)
{
//接受信息
private void receivedata()
{
byte[] sbufdata = new byte[1];//定义字节型数组用于暂存数据
ad(sbufdata, 0, 1);//从串口读取数据
receive.invoke(new eventhandler(delegate
海里的动植物 {
= string(sbufdata[0], 2);//将数据转换为二进制8位字符并返回该值
}));
}
private void serialport1_datare -ceived(object sender, system.io.ports.serialdatareceivedeventargs e)
{
receivedata();//每次串口接受到数据时触发执行
}
}
}
3.3 串行通信程序中的数据转换和显示
串行通信实验程序中,不仅要有进行串行通信的具体程序,还需要将所传数进行转换和显示。从上述串行通信程序可以明显看到:程序中使用了convert类中的tobyte(string value,int frombase)方法将输入的string型数据转换为byte型数据并存入相应的数组中,以便串行口进行发送。对于接收到的数据,主机程序也使用了covert类中的tostring(long value,int tobase)方法将byte型数据转换为string型二进制数,以便在通信程序的显示界面上加以显示。
本程序中采用调用invoke方法,通过声明一个委托实现把转换后的字符数据在label控件上加以显示。这是因为若从另外一个线程操作windows窗体上的控件,就会和主线程产生竞争,造成不可预料的结果,甚至死锁。因此windows gui编程有一个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产生不可预料的结果。
}
}
}
3.3 串行通信程序中的数据转换和显示
串行通信实验程序中,不仅要有进行串行通信的具体程序,还需要将所传数进行转换和显示。从上述串行通信程序可以明显看到:程序中使用了convert类中的tobyte(string value,int frombase)方法将输入的string型数据转换为byte型数据并存入相应的数组中,以便串行口进行发送。对于接收到的数据,主机程序也使用了covert类中的tostring(long value,int tobase)方法将byte型数据转换为string型二进制数,以便在通信程序的显示界面上加以显示。
本程序中采用调用invoke方法,通过声明一个委托实现把转换后的字符数据在label控件上加以显示。这是因为若从另外一个线程操作windows窗体上的控件,就会和主线程产生竞争,造成不可预料的结果,甚至死锁。因此windows gui编程有一个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产生不可预料的结果。
4 单片机的串行通信程序
4.1 原理设计
单片机串行通信程序应当安装在at89c51的flash存储器中,以实现和ibm-pc国庆 放假主机间的通信,并把从串行口接收到的数据在氖灯上加以显示。相应硬件接线如图3所示。
学习方法的名言4.1 原理设计
单片机串行通信程序应当安装在at89c51的flash存储器中,以实现和ibm-pc国庆 放假主机间的通信,并把从串行口接收到的数据在氖灯上加以显示。相应硬件接线如图3所示。
图3 单片机系统的电路原理图
图中可见,单片机通过p0口分别和8个氖灯相连,用于显示接收到的数据,p1口分别接8个开关,用于输入开关量。max232为电平变换器,它一方面与单片机的txd和rxd相连,用于将txd上的ttl电平转换为rs232电平以及把接收信号的rs232电平转换为ttl电平;另一方面它还通过一个rs232电缆和ibm-pc串行口相接。max232插头(座)上的电容用于内部耦合升压,max232内部有一组dc-dc的电源转换电路,只需在外部加上4个电容就能发挥电压转换功能。
4.2 流程设计
单片机的串行通信程序有串行口初始化、接收、发送和显示等部分组成,见图4。图中,系统先进行串行口初始化(启动一次发送),然后等待串行口接收中断,系统响应该中断后就执行串行口接收中断服务程序,并将接收到的数据送到p0口和点亮氖灯;其次是从p1口读取开关量送到发送缓冲区,并把发送缓冲区中的发送数据送到串行口以完成一次通信。
4.2 流程设计
单片机的串行通信程序有串行口初始化、接收、发送和显示等部分组成,见图4。图中,系统先进行串行口初始化(启动一次发送),然后等待串行口接收中断,系统响应该中断后就执行串行口接收中断服务程序,并将接收到的数据送到p0口和点亮氖灯;其次是从p1口读取开关量送到发送缓冲区,并把发送缓冲区中的发送数据送到串行口以完成一次通信。
图4 单片机的发送/接收程序
4.3 串行通信波特率的计算
在pc机上,串行通信波特率可以直接设置为2400,4800,9600等。在单片机上,串行通信波特率需要在程序中加以设置。但在实现串行通信双方的通信时,串行通信双方所设置的通信波特率必须一致。单片机的波特率设置和串行口工作状态、定时器t1的溢出率和
在pc机上,串行通信波特率可以直接设置为2400,4800,9600等。在单片机上,串行通信波特率需要在程序中加以设置。但在实现串行通信双方的通信时,串行通信双方所设置的通信波特率必须一致。单片机的波特率设置和串行口工作状态、定时器t1的溢出率和
波特率选择位smod等有关。单片机的波特率计算公式如下:
本串行通信中,由于单片机主频为6mhz和smod设置为1,故定时器t1的初值应设定为f3h。根据上式计算出的波特率约为2403.85,因此pc机的波特率应设置为2400。
4.4 程序设计续贷声明200字范文
单片机串行通信程序清单如下:
org 0000h
ljmp main
org 0023h
ljmp sintsbv
org 0030h
sintsbv:
clr ri;清接受标志
mov a, sbuf;串口接受的数据送a
4.4 程序设计续贷声明200字范文
单片机串行通信程序清单如下:
org 0000h
ljmp main
org 0023h
ljmp sintsbv
org 0030h
sintsbv:
clr ri;清接受标志
mov a, sbuf;串口接受的数据送a
mov p0, a;将数据送p0显示
mov p1, #0ffh;准备读取p1引脚
mov a, p1;读取p1数据到a
mov sbuf, a;将数据送到串口
reti
org 0100h
main:mov tmod, #20h;t1为方式2
mov th0, #0f3h ;设定波特率为2400b/s
mov tl0, #0f3h
mov scon, #0f8h;串行口为方式3,允许接受, tb8=1
mov pcon, #80h
mov ie, #90h;开串口中断
setb ea
setb tr1;启t1工作
sjmp $
end
mov p1, #0ffh;准备读取p1引脚
mov a, p1;读取p1数据到a
mov sbuf, a;将数据送到串口
reti
org 0100h
main:mov tmod, #20h;t1为方式2
mov th0, #0f3h ;设定波特率为2400b/s
mov tl0, #0f3h
mov scon, #0f8h;串行口为方式3,允许接受, tb8=1
mov pcon, #80h
mov ie, #90h;开串口中断
setb ea
setb tr1;启t1工作
sjmp $
end
发布评论