C#实现PC机与单片机(89C51)的串行通讯
摘要:本文主要论述PC机与单片机之间实现异步串行通讯需要解决的问题以及如何利用C#提供的串行通讯SerialPort类来实现PC机与51单片机的通讯。
关键词: SerialPort;串行通讯;波特率
1 引言
PC机具有强大的监控和管理功能,而单片机则具有快速及灵活的控制特点,通过PC机的RS-232串行接口与外部设备进行通讯,是许多测控系统中常用的一种通信解决方案。
在Microsoft.Net技术广泛应用的今天人们采用了许多方法在Visual Studio.Net中来编写串口通讯程序:第一种方法是通过采用Visual Studio 6.0中原来的MSComm控件,这是最简单、最方便的方法,但需要注册;第二种方法是自己用API写串口通信;第三种方法是采用微软推出的最新版本Visual Studio 2005开发工具,NET Framework 2.0类库中包含的SerialPort类,方便地实现了所需要串口通讯的多种功能。本文着重讨论了Visual Studio 2005开发工具中SerialPort类的设计方法。
2 SerialPort类常用属性、方法和事件
2.1 命名空间
System.IO.Ports命名空间包含了控制串口重要的SerialPort类,该类提供了同步I/O 和事件驱动的I/O、对管脚和中断状态的访问以及对串行驱动程序属性的访问。
2.2 串口的通讯参数
①通讯端口号:
[PortName]属性获取或设置通信端口,包括但不限于所有可用的COM端口,该属性返回类型为String。
②通讯格式:
SerialPort类分别用[BaudRate]、[Parity]、[DataBits]、[StopBits]属性设置通讯格式中的波特率、校验位、数据位和停止位。
2.3 串口的打开和关闭
SerialPort类中打开关闭串口相应的是调用类的Open()和Close()方法。
2.4 数据的发送和读取
SerialPort类调用重载的Write和WriteLine方法发送数据,其中WriteLine可发送字符串并在字符串末尾加入换行符。读取串口缓冲区的方法有许多,其中除了ReadExisting和ReadTo,其余的方法都是同步调用,线程被阻塞直到缓冲区有相应的数据或大于ReadTimeOut属性设定的时间值后,引发ReadExisting异常。
2.5 DataReceived事件
DataReceived事件在接收到了[ReceivedBytesThreshold]设置的字符个数或接收到了文件结束字符并将其放入了输入缓冲区时被触发。
3 PC机与8051实现串行通讯需要解决的问题
3.1 TTL电平与RS232电平的转换
89C51单片机采用的是TTL电平且采用正逻辑[1],而PC机采用RS232与外部设备进行通讯,RS232采用负逻辑,因此MCS51单片机串行口与PC机的RS232接口相连进行通讯时必须进行电平的转换。通常采用MAX232电平转换芯片。
3.2 单片机与PC机通讯时波特率的设定
PC机与51单片机双方进行通讯时必须采用相同的波特率,PC机的波特率默认为9600b/s, 51系列单片机有两个定时/计数器,四种工作方式,一般用定时器工作于方式2(可重新装载的8位定时器/计数器)作为定时波特率发生器。因此单片机与PC机进行异步通讯时的波特率可由公式3.1得出:
其中SMOD是单片机电源控制寄存器(PCON)中的位7,开机(RESET)时,SMOD的设定值为0,亦可用指令“ANL PCON,#7FH”清除为0。fosc为单片机的晶振频率。根据需要的波特率即可得计数初值TH1。
4 单片机与PC机通讯时通讯协议的约定及部分初始化程序
在单片机与PC机的通讯中,单片机一般作为下位机负责从控制对象采集数据(如压力、流量等),上位机则进行现场可视化检测。传输数据采用二进制数据,上位机与下位机之间采用主从式通讯。以下给出单片机和VC# 环境下部分的通讯程序。
4.1 串口通讯协议约定
波特率为9600b/s,无奇偶校验位,传输的数据位为8位,停止位为1位,用串行口工作于方式1。单片机的晶振频率fosc=11.059MHz,定时器T1工作于方式2作为波特率发生器,根据计数初值的计算公式(3.1)可得计数初值TH1为0FDH 。
4.2 单片机的串行通讯程序
单片机串行通讯程序,给出了初始化程序:
ORG0000H
AJMP START;转到初始化程序
ORG0023H
AJMP PGUART ;转到串行中断服务子程序
START: MOVSP,#60H ;堆栈指针初始化
MOVP0,#0FFH ;端口初始化
MOVP1,#0FFH
MOVP2,#0FFH
MOVP3,#0FFH
MOVTMOD,#20H;定时器T1工作于模式2,自动重装载
MOVTH1,#0FDH;TH1、TL1初值为"0FDH",9600bps
MOVTL1,#0FDH
MOVSCON,#50H;串行口工作于方式1,允许接收
SETB TR1 ;启动定时器T1
SETB ES ;允许串行口中断
SETB EA ;开总中断
MAIN:...... ;主程序处理其他任务,等待串口中断
AJMP MAIN
PAUSE:...... ;串口中断服务子程序,接收处理数据
RETI
END
4.3 上位机的串行通讯程序
例:发送及接收数据的程序:
private void button1_Click(object sender, EventArgs e)
{
string a;
SerialPort Ser1 = new SerialPort("com1", 9600, Parity.None, 8, StopBits.One);
Try
{
Ser1.Open();
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.ToString());
}
if (textBox1.Text == "")
{
MessageBox.Show("Err");
Ser1.Close();
}
else
{
a=textBox1.Text;
try
{
//p.WriteLine(a);
p.Write(a);
}
catch(InvalidOperationException ex)
{
MessageBox.Show(ex.ToString());
}
textBox2.Text = Ser1.ReadByte().ToString();
Ser1.Close();
}
}
5 结束语
单片机与上位机的通讯在工业现场中应用的比较广泛,本文对C#提供的串行通讯SerialPort类来实现PC机与51单片机的通讯进行了探讨。实践证明,这种方案是可行的,能保证双方通讯正常。
参考文献
[1]蔡朝洋.单片机控制实习与专题制作.北京航空航天大学出版社.
[2]张洪润,易涛.单片机应用技术教程.清华大学出版社.