串行通信单片机设计

2024-10-12

串行通信单片机设计(共8篇)

1.串行通信单片机设计 篇一

湖南大学(长沙410082) 于小亿 王 辉 张志学 摘 要 详细介绍了在Windows环境下应用VC++实现PC机与单片机的几种串行通信方法,给出了用Visual C++6.0编写的PC机程序和用C51编写的单片机通信程序,经实际应用系统运行稳定可靠。 关键词 Visual C++ 类 串行通

湖南大学(长沙410082) 于小亿 王 辉 张志学

摘 要 详细介绍了在Windows环境下应用VC++实现PC机与单片机的几种串行通信方法,给出了用Visual C++6.0编写的PC机程序和用C51编写的单片机通信程序。经实际应用系统运行稳定可靠。

关键词 Visual C++ 类 串行通信

工业控制领域(如DCS系统),经常涉及到串行通信问题。为了实现微机和单片机之间的数据交换,人们用各种不同方法实现串行通信,如DOS下采用汇编语言或C语言,但在Windows 环境下却存在一些困难和不足。在Windows操作系统已经占据统治地位的情况下(何况有些系统根本不支持DOS如Windows2000)开发Windows 环境下串行通信技术就显得日益重要。

VC++6.0是微软公司于1998年推出的一种开发环境,以其强大的功能,友好的界面,32位面向对象的程序设计及Active X的灵活性而受广大软件开发者的青睐,被广泛应用于各个领域。应用VC++开发串行通信目前通常有如下几种方法:一是利用Windows API通信函数;二是利用VC的标准通信函数_inp、_inpw、_inpd、_outp、_outpw、_outpd等直接对串口进行操作;三是使用Microsoft Visual C++的通信控件(MSComm);四是利用第三方编写的通信类。以上几种方法中第一种使用面较广,但由于比较复杂,专业化程度较高,使用较困难;第二种需要了解硬件电路结构原理;第三种方法看来较简单,只需要对串口进行简单配置,但是由于使用令人费解的VARIANT类,使用也不是很容易;第四种方法是利用一种用于串行通信的CSerial类(这种类是由第三方提供),只要理解这种类的几个成员函数,就能方便的使用。笔者利用CSerial类很方便地实现了在固定式EBM气溶胶灭火系统分区启动器(单片机系统)与上位机的通信。以下将结合实例,给出实现串行通信的几种方法。

1 Windows API通信函数方法

与通信有关的Windows API函数共有26个,但主要有关的有:

CreateFile() 用 “comn”(n为串口号)作为文件名就可以打开串口。

ReadFile() 读串口。

WriteFile() 写串口。

CloseHandle() 关闭串口句柄。初始化时应注意CreateFile()函数中串口共享方式应设为0,串口为不可共享设备,其它与一般文件读写类似。以下给出API实现的源代码。

1.1 发送的例程

//声明全局变量

HANDLE m_hIDComDev;

OVERLAPPED m_OverlappedRead, m_Over lappedWrite;

//初始化串口

void CSerialAPIView::OnInitialUpdate()

{

CView::OnInitialUpdate();

Char szComParams[50];

DCB dcb;

Memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED));

Memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED));

m_hIDComDev = NULL;

m_hIDComDev = CreateFile(“COM2”, GENERIC_READ│GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL│FILE_FLAG_OVERLAPPED, NULL);

if (m_hIDComDev == NULL)

{

AfxMessageBox(“Can not open serial port!”);

goto endd;

}

memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED));

memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED));

COMMTIMEOUTS CommTimeOuts;

CommTimeOuts. ReadIntervalTimeout=0×FFFFFFFF;

CommTimeOuts. ReadTotalTimeoutMultiplier = 0;

CommTimeOuts. ReadTotalTimeoutConstant= 0;

CommTimeOuts. WriteTotalTimeoutMultiplier = 0;

CommTimeOuts. WriteTotalTimeoutConstant = 5000;

SetCommTimeouts(m_hIDComDev, &CommTimeOuts);

Wsprintf(szComparams, “COM2:9600, n, 8, 1”);

m_OverlappedRead. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

m_OverlappedWrite. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

dcb. DCBlength = sizeof(DCB);

GetCommState(m_hIDComDev, &dcb);

dcb. BaudRate = 9600;

dcb. ByteSize= 8;

unsigned char ucSet;

ucSet = (unsigned char) ((FC_RTSCTS&FC_DTRDSR) != 0);

ucSet = (unsigned char) ((FC_RTSCTS&FC_RTSCTS) ! = 0);

ucSet = (unsigned char) ((FC_RTSCTS&FC_XONXOFF) ! = 0);

if (!SetCommState(m_hIDComDev, &dcb)‖

!SetupComm(m_hIDComDev,10000,10000)‖

m_OverlappedRead. hEvent ==NULL‖

m_OverlappedWrite. hEvent ==NULL)

{

DWORD dwError = GetLastError();

if (m_OverlappedRead. hEvent != NULL) CloseHandle(m_OverlappedRead. hEvent);

if (m_OverlappedWrite. hEvent != NULL) CloseHandle(m_OverlappedWrite. hEvent);

CloseHandle(m_hIDComDev);

}

endd:

;

}

//发送数据

void CSerialAPIView::OnSend()

{

char szMessage[20] = “thank you very much”;

DWORD dwBytesWritten;

for (int i=0; i

{

WriteFile(m_hIDComDev, (LPSTR)&szMessage[i], 1, &dwBytesWritten, &m_OverlappedWrite);

if (WaitForSingleObject(m_OverlapperWrite, hEvent, 1000))dwBytesWritten = 0;

else{

GentOverlappedResult(m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE);

m_OverlappedWrite. Offset += dwBytesWritten;

}

dwBytesWritten++;

}

}

1.2 接收例程

DCB ComDcb; //设备控制块

HANDLE hCom; //global handle

hCom = CreateFile (“COM1”,GENERIC_READ| GENERIC_WRITE,0,

NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (hCom==INVALID_HANDLE_VALUE)

{

AfxMessageBox(“无法打开串行口”);

}

else

{

COMMTIMEOUTS CommTimeOuts ;

SetCommMask(hCom, EV_RXCHAR ) ;

SetupComm(hCom, 4096, 4096 ) ; /*设置收发缓冲区 尺寸为4K */

PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT |

PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区

//以下初始化结构变量CommTimeOuts, 设置超时参数 CommTimeOuts.ReadIntervalTimeout = 0×FFFFFFFF ;

CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;

CommTimeOuts.ReadTotalTimeoutConstant = 4000 ;

CommTimeOuts.WriteTotalTimeoutMultiplier = 0;

CommTimeOuts.WriteTotalTimeoutConstant = 4000 ;

SetCommTimeouts(hCom, &CommTimeOuts ); //设置超时参数

ComDcb.DCBlength = sizeof( DCB ) ;

GetCommState( hCom, &ComDcb ) ; //获取当前参数

ComDcb.BaudRate =9600; //波特率

ComDcb.ByteSize = 8; //数据位

ComDcb.Parity = 0; /*校验 0~4=no, odd, even, mark, space */

SetCommState(hCom, &ComDcb ) ;

} //设置新的通信参数

接收可用定时器或线程等

DWORD dRead,dReadNum;

unsigned char buff [200];

dRead=ReadFile(hCom, buff, 100, &dReadNum, NULL); //接收100个字符,

//dReadNum为实际接收字节数

2 利用端口函数直接操作

这种方式主要是采用两个端口函数_inp(), _outp()实现对串口的读写,其中读端口函数的原型为:

int _inp(unsigned shot port)

该函数从端口读取一个字节,端口号为0~65535。

写端口的函数原型为:

int _outp(unsigned shot port, int databyte)

该函数向指定端口写入一个字节。

不同的计算机串口地址可能不一样,通过向串口的控制及收发寄存器进行读写,可以实现灵活的串口通信功能,由于涉及具体的硬件电路讨论比较复杂,在此不加赘述,

3 MSComm控件

MSComm控件是微软开发的专用通信控件,封装了串口的所有功能,使用很方便,但在实际应用中要小心对其属性进行配置。下面详细说明该类应用方法。

3.1 MSComm控件的属性

CommPort:设置串口号,类型 short :1-comm1 2-comm2.

Settings:设置串口通信参数,类型 CString :B波特率,P奇偶性(N无校验,E偶校验,O奇校验),D字节有效位数,S停止位。

PortOpen:设置或返回串口状态,类型 BOOL:TURE打开,FALSE关闭。

InputMode:设置从接收缓冲区读取数据的格式,类型 long: 0-Text 1-Bin。

Input:从接收缓冲区读取数据,类型 VARIANT。

InBufferCount:接收缓冲区中的字节数,类型:short。

InBufferSize:接收缓冲区的大小,类型:short。

Output:向发送缓冲区写入数据,类型:VARIANT。

OutBufferCount:发送缓冲区中的字节数,类型:short。

OutBufferSize:发送缓冲区的大小,类型:short。

InputLen:设置或返回Input读出的字节数,类型:short。

CommEvent:串口事件,类型:short。

3.2 程序示例

串口初始化

if (!m_comm.GetPortOpen())

m_comm.SetPortOpen(TURE); /*打开串口*/

m_comm.SetSettings(“4800,n,8,1”); /*串口参数设置*/

m_comm.SetInputMode(0); /*设置TEXT缓冲区输入方式*/

m_comm.SetRthresHold(1); /*每接收一个字符则激发OnComm()事件*/

接收数据

m_comm.SetInputLen(1); /*每次读取一个字符

VARINAT V1=m_comm.GetInput();

/*读入字符*/

m_V1=V1.bstrval;

发送字符 m_comm.SetOutput(Colevariant (“Hello”); /*发送 “Hello” */

3.3 注意

SetOutput方法可以传输文本数据或二进制数据。用SetOutput方法传输文本数据,必须定义一个包含一个字符串的 Variant。发送二进制数据,必须传递一个包含字节数组的Variant 到 Output 属性。正常情况下,如果发送一个 ANSI 字符串到应用程序,可以以文本数据的形式发送。如果发送包含嵌入控制字符、Null 字符等的数据,要以二进制形式发送。此处望引起读者注意,笔者曾经在此犯错。

4 VC++类CSerial

4.1 串行通信类CSerial简介

Cserial 是由MuMega Technologies公司提供的一个免费的VC++类,可方便地实现串行通信。以下为该类定义的说明部分。

class CSerial

{

public:

CSerial();

~CSerial();

BOOL Open( int nPort = 2, int nBaud = 9600 );

BOOL Close( void );

int ReadData( void *, int );

int SendData( const char *, int );

int ReadDataWaiting( void );

BOOL IsOpened( void ){ return( m_bOpened ); }

protected:

BOOL WriteCommByte( unsigned char );

HANDLE m_hIDComDev;

OVERLAPPED m_OverlappedRead, m_OverlappedWrite;

BOOL m_bOpened;

}

4.2 串行通信类Cserial 成员函数简介

1. CSerial::Cserial是类构造函数,不带参数,负责初始化所有类成员变量。

2. CSerial:: Open这个成员函数打开通信端口。带两个参数,第一个是埠号,有效值是1到4,第二个参数是波特率,返回一个布尔量。

3. CSerial:: Close函数关闭通信端口。类析构函数调用这个函数,所以可不用显式调用这个函数。

4. CSerial:: SendData函数把数据从一个缓冲区写到串行端口。它所带的第一个参数是缓冲区指针,其中包含要被发送的资料;这个函数返回已写到端口的实际字节数。

5. CSerial:: ReadDataWaiting函数返回等待在通信端口缓冲区中的数据,不带参数。

6. CSerial:: ReadData函数从端口接收缓冲区读入数据。第一个参数是void*缓冲区指针,资料将被放入该缓冲区;第二个参数是个整数值,给出缓冲区的大小。

4.3 应用VC类的一个实例

1. 固定式EBM气溶胶灭火系统简介

固定式EBM气溶胶灭火装置分区启动器是专为EBM灭火装置设计的自动控制设备。可与两线制感温、感烟探测器配套使用,当监测部位发生火情时,探测器发出电信号给分区启动器,经逻辑判断后发出声、光报警,延时后自动启动EBM灭火装置。为了便于火灾事故的事后分析,需对重要的火警事件和关键性操作进行记录,记录应能从PC机读出来;PC机能控制、协调整个系统的工作,这些都涉及通信。本例中启动器采用RS-485通信接口,系统为主从式网络,PC机为上位机。具体的通信协议为:(1)下位机定时向上传送记录的事件;(2)应答发送,即PC机要得到最新事件记录,而传送时间未到时,PC机发送命令,下位机接收命令后,把最新记录传给上位机;(3)上位机发送其它命令如校时、启动、停止、手/自动等。

2. 通信程序设计

部分上位机程序

(1)发送命令字程序,代码如下

voidCCommDlg::OnSend()

{

CSerial Serial;

//构造串口类,初始化串行口

if (Serial.Open(2,9600)) //if-1

//打开串行口2,波特率为9600bps

{

static char szMessage[]=“0”;

//命令码(可定义各种命令码)

int nBytesSent;

int count=0;

resend:

nBytesSent=Serial.SendData(szMessage,strlen(szMessage));

//发送命令码

char rdMessage [20];

if (Serial.ReadDataWaiting()) //if-2

{

Serial.ReadData(rdMessage,88);

//rdMessage 定义接收字节存储区,为全局变量//

if ((rdMessage[0]!=0x7f)&&(count<3))

{

count++;

goto resend

}

if(count>=3)

MessageBox(“发送命令字失败”);

}

else //if-2

MessageBox(“接收数据错误”);

}

else //if-1

MessageBox(“串行口打开失败”);

}

下位机通信程序:

#include

#include

#include

#define count 9

#define com_code 0x00

#define com_code1 0xff

unsigned char buffer[count];

int po,year,month,date,hour;

int minute,second,recordID ;

int sum;

main()

{

/*初始化串口和定时器*/

TMOD=0×20;

TH1=0×fd;

TR1=0×01;

ET1=0×00;

ES=1;

EA=1;

/*待发送数据送缓冲区*/

buffer[0]=0×ff; //数据特征码

buffer[1]=count+1; //数据长度

buffer[2]=year; //年

buffer[3]=month; //月

buffer[4]=date; //日

buffer[5]=hour; //时

buffer[6]=minute; //分

buffer[7]=second; //秒

buffer[8]=recordID; //事件号

for(po=0;po

sum+=buffer[po];

buffer[9]=sum; //校验和

}

/*发送中断服务程序*/

void send(void) interrupt 4 using 1

{

int i;

RI=0;

EA=0;

do

{

for(i=0;i<=count;i++)

{

SBUF=buffer[i]; //发送数据和校验和//

while(TI==0);

TI=0;

}

while(RI==0);

RI=0;

}while(SBUF!=0); //主机接收不正确,重新发送//

EA=1;

Return;

}

5 应用总结

根据不同需要,选择合适的方法。我们选用的用VC++类实现的上位机和下位机的串行通信方法具有使用简单、编写程序方便的特点。经过半年多应用于EBM灭火系统的情况来看,该方法实现的系统运行稳定可靠,是一种值得推广的简单易行的通信方法。

参 考 文 献

1 Kate Gregory Visual C++6开发使用手册.北京:机械工业出版社,1999

2 何立民.单片机的C语言应用程序设计.北京:北京航空航天大学出版社,1997

3 马风格.VC控件与串行通讯.1999现代计算机,2000(4)

原文转自:www.ltesting.net

2.串行通信单片机设计 篇二

电子密码锁是密码锁的一种, 它是通过对锁的芯片或是电路进行控制, 来达到开锁和闭锁目的的电子产品。随着密码锁的应用领域不断拓宽, 其种类日益增多, 有的密码锁是简易的电路控制, 有的密码锁则是复杂的芯片控制, 后者由于加入了智能芯片 (单片机) , 从而使其价格要更高昂一些, 安全性能也相对较高。大体上可将电子密码锁的功能特点归纳为以下几个方面:保密性好是电子密码锁最为突出的特点之一, 与机械密码锁相比, 其编码量要大很多, 相关研究结果表明, 电子密码锁随机开锁的成功率约等于零;密码可随意更换, 用户可以对电子密码锁的密码进行经常性更换, 有助于防止密码被盗取;当电子密码锁输入密码达到一定的错误次数时, 会自动发出报警信号, 如某型号的电子密码锁连续输入4次错误的密码后, 锁会自动断电3min;有的电子密码锁还具备入侵感应、火灾报警、双重锁定、自动上锁、外部显示等功能。

2 单片机与串行通信在电子密码锁设计中的应用

想要使电子密码锁具备各种功能, 就必须将单片机作为它的核心, 同时采用串行通信的方式, 实现信号的传输。下面以单片机中性能较高的AT89系列单片机作为电子密码锁的主控单元, 对电子密码锁的硬件和软件设计进行分析。

2.1 总体设计方案的确定

本次设计选用AT89系列单片机作为电子密码锁的核心控制器, 将键盘设定为电子密码锁的主要输入单元, 采用矩阵形式对键盘进行排列, 不同的按键对应相应的功能, 由单片机负责实现密码的输入与上传, 并由上位PC机负责对相关数据进行分析整理后存储至数据库当中, 进而构成一个计算机网络。为了进一步增长电子密码锁的传输距离, 设计中运用了串行通信的方式, 基于串行通信的连接更加简单, 便于操作, 有助于数据传输可靠性的提升。

2.2 软硬件的选择

在对以单片机为核心, 以串行通信为信号传输方式的电子密码锁进行系统设计的过程中, 软件与硬件的选择是整个设计的关键环节, 直接关系到电子密码锁相关功能的正常使用。为了使所选的软硬件更加合理, 应当充分考虑电子密码锁的具体需求, 经过研究后, 软件决定选用51系列的C编译器, 硬件设备选用89C52, 软硬件以嵌入式的方式进行组合。

2.2.1 软件程序设计

软件与密码锁的安全性有着密切的关系, 为使电子密码锁达到较高的安全性, 在软件设计的过程中, 必须对安全性能予以重视。基于这一前提, 可以引入相关的约束条件和安全指导原则, 为密码锁提供安全服务和安全机制, 前者主要包括鉴别、访问控制、信息保密与完整;后者则包括访问控制机制、机密信息的完整性等等。大体上可将密码锁的软件程序设计分为以下两个部分, 一部分是控制程序, 另一部部分是管理程序。其中控制程序的设计主要包括主程序、延时控制、密码修改、键盘扫描及报警等子程序。网络管理程序则包括穿行通信和信息查询程序等。在密码输入正确性的判断上, 运用了二级权限加密技术, 密码输入正确电子密码锁便会打开, 若是密码输入错误次数超过3次后, 报警装置会自行启动, 发出报警信息并存储。当需要对电子密码锁设定好的密码进行修改时, 需要正确输入高级权限密码, 系统确认后, 方可进行修改, 由此使密码锁的安全性获得了有效保障。

2.2.2 硬件设计

在对电子密码锁的硬件进行设计时, 键盘采用4×4的矩阵排列, 并在每一行与每一列相交的位置处设置功能按键, 其中行线设置为低压电平, 由其负责对列线的实际输入进行检测, 进而确认该相交位置处的按键是否被按下。出于经济性和功能性等方面的考虑, 最终决定电路的显示模块采用液晶显示屏, 型号为SMC1602A, 之所以选择该显示屏, 主要是因为的性能较为完善, 功耗低、使用寿命长、人机交互界面良好, 与单片机之间的数据通信可以借助RS232接口来实现, 主从式全双工通信网络如图1所示。

2.3 串行通信

2.3.1 多主机通信

对于总线通信的控制设备而言, 其需要在通电复位之后才能正式进入运行状态, 故此可以利用中断的方法等待串行通信现象的出现, 并借助全双工互锁的模式, 对电子密码锁系统图1:主从式全双工通信网络框架结构示意图的正常通信进行控制。同时, 利用通用型的串行通信总线控制分担至相应的通信主机上。可将管理电子密码锁的装置设置在串行通信的数据链路上, 由此便可形成一个主从形式的总线型网络架构。

2.3.2 下位PC机与服务器的通信方式

电子密码锁系统中所有的数据帧均必须经由串行通信总线的接口进行传输, 外接在通信总线上的机械设备接收到数据帧后, 可对数据帧头的地址与本机的地址进行比较, 或是根据数据帧的结束标志对其结尾进行判断, 进而决定是否对该数据进行接收。单片机通信模块的首层通信协议采用的是串口通信的方式, 如果发送信息时, 串口为发送状态, 则会先将数据写入至串口缓冲区域当中, 当数据读取到该区域内时, 便可实现同口式通信, 并在明确转义字符的处理数据帧后, 将本机数据写入到通信缓冲区当中, 同时对这些数据进行解析, 然后以C语言进行编译。

3 结论

综上所述, 电子密码锁以自身较高的安全性和多种功能被广泛应用于各个领域当中。本文在简要阐述电子密码锁功能特点的基础上, 对单片机和串行通信在电子密码锁设计中的运用进行了分析研究, 并对电子密码锁系统的设计过程进行了论述。在未来一段时期, 应当重点加大对电子密码锁相关技术的研究力度, 从而使设计出来的电子密码锁功能更加强大、性能更加稳定、安全系数更高。

摘要:近年来, 随着微电子技术和通信技术的不断进步, 推动了与之相关领域的发展。传统的机械密码锁由于安全性较低, 已经逐步被市场淘汰, 而电子密码锁以自身较高的安全性和诸多功能获得了用户的一致认可。基于此点, 本文利用微电子技术中的单片机和通信技术中的串行通信对电子密码锁的设计展开分析研究。

关键词:电子密码锁,单片机,串行通信

参考文献

[1]张力.基于单片机与串行通信的电子密码锁设计[J].电子技术与软件工程, 2015 (16) :162-162.

3.串行通信单片机设计 篇三

关键词:相控阵 发射机 监控设计 单片机 串行轮询

中图分类号:TN911 文献标识码:A 文章编号:1674-098X(2016)06(b)-0074-02

Abstract:Ageing of the power amplifier modules or cables will make accuracy of the phased array radar reduced. The paper demonstrates the theory of the phased array radar transmitter,analyzes the merits of the PIC microcontroller serial alternation communication and the process of communication,actualizes the monitor of phased array radar transmitter reliably in a low-cost method.

Key Words:Phased array; Transmitter; Design of monitor; Microcontroller;Alternation communication

1 相控阵雷达发射原理

相控阵雷达即相位控制电子扫描阵列雷达,其快速而精确转换波束的能力使雷达能够在1 min内完成全空域的扫描。所谓相控阵雷达是由大量相同的辐射单元组成的雷达面阵,每个辐射单元在相位和幅度上独立受波控和移相器控制,能得到精确可预测的辐射方向图和波束指向。雷达工作时发射机通过馈线网络将功率分配到每个天线单元,通过大量独立的天线单元将能量辐射出去并在空间进行功率合成,形成需要的波束指向。

相控阵雷达的发射系统由数十至上百块功率放大模块组成,通过相控阵天线采用集中式发射,集中向天线面阵馈电并通过移相控制波束方向,发射馈线损耗较大,同时放大模块故障率较高。相控阵发射机长时间工作后,经常出现个别功率放大模块和线缆老化情况,虽然不会使雷达整体停止工作,但辐射方向图和波束指向均会发生偏移,进而对雷达精度和探测范围产生影响,亟需低成本的有效、可靠方法实现发射机全部功率放大模块的有效实时监控,从而降低相控阵雷达检修维护的难度。

2 PIC单片机与传感器串行组网

发射机功率放大模块内置传感器,可以直接监控是否在发射端口实际产生了电磁脉冲。发射模块传感器通信信号简单,除故障信号电平外只提供脉冲是否达到门限值的0/1信号。传感器具有RS232C电平串行数字通信功能,免去了传统模拟量监测时大量的模/数转换器件。由于传感器数量众多,串行轮询通信网络又极大地减少了线缆铺设数量,数字信号的传输同时可避免模拟信号的线缆内部衰减和干扰问题。

3 PIC单片机串行轮询通信

PIC单片机网络采用串行轮询通信主从通信模式,波特率9 600bit,8位数据位,1位起始位,1位停止位,无校验。PIC单片机设计为主站,包含发送请求信号、接收信号、逻辑判断和非正常状态字上传工控机的功能。全部内置传感器为从站,只在接收到主站通信请求后发送状态数据。PIC单片机主站可通过设计程序响应中断,进而通过中断程序控制整个串行轮询通信过程。对不同编号的内置传感器产生的中断赋予不同编号,利用PIC单片机与非逻辑程序语句完成感应器传回的状态字判读工作,并将非正常状态字上传工控计算机,最终实现雷达发射机的整体监控。

4 PIC单片机与工控机的通信

将PIC单片机其中一个通用串行通信接口设置为全双工异步串行通信模式。为了把单片机的RC6和RC7分别设置为串行接口发送/时钟线和接收/数据线,首先应当把SPEN位和方向存储器TRISC的D7:D6置1。[1]向波特率寄存器写入预定的数值并同时产生单片机定时器复位清零的效果,单片机初始化时对该非同步通信端口执行初始化程序:

BSF STATUS,RP1;程序指针指向数据存储器

MOVWF SPBRG;设置传输波特率

CLRF RCSTA;接收控制和状态寄存器清零

BSF RCSTA,SPEN;允许使用串口

CLRF PIR1;清除中断标志

CLRF TXSTA;发送控制和状态寄存器清零

BSF TXSTA,BRGH;设置为异步传输

BSF TXSTA,TXEN;发送允许开始

BSF RCSTA,CREN;接收允许开始

当工控机与单片机系统通信时,单片机数据存储器内的数据格式是十六进制,[1]向工控机传输的是十六进制数的ASCII码的二进制形式。雷达工控机使用windows系统,串口接收使用ANSI码,而ANSI码仅前126个与ASCII码相同。所以,设计中断编码时,必须考虑编码规则使字符长度满足要求。

5 结语

由于不同型号雷达发射模块出厂内置的传感器不尽相同,在监控设计过程中必须充分考虑传感器的通信性能,尤其要注意传感器对传输速率、信息位个数、校验位的要求。[2]在单片机中断响应设计时,也要对传感器的通信响应时间进行充分实验,否则容易引起轮询冲突,使监控系统不定期失效。另外,RS232C通信协议要求传输距离最好不超过20m,如确实需要较长通信传输距离,建议设计RS485接口的监控系统。[3]

参考文献

[1]周杰,张银胜,刘金涛,等.PIC单片机原理及系统设计[M].气象出版社,2008:227-229.

[2]赵雅兴.PSpice与电子器件模型[M].北京邮电大学出版社,2006:315-317.

4.串行通信单片机设计 篇四

摘要:简要从硬件和软件两方面介绍一种嵌入式的多协议串行通信设计方案。该设计方案采用多协议串行通信控制器Z85C30及外围电路开发,通过软件编程,可满足各种串行通信要求,如异步、按字节同步、按位同步等通信格式。

关键词:嵌入式系统串行通信控制器(SCC)Z85C30

引言

我们在嵌入式系统的开发过程中,经常需要设计串行通信口,用以同其它设备或计算机网络交换数据。针对不同的应用场合及不同的通信格式,在硬件设计方面有许多不同的芯片可供选择,如Intel8251A、Intel8274、Intel82530等。采用ZILOG公司的串行通信控制器Z85C30进行设计,和其它器件相比,具有功能强、速度快、外部逻辑少等优点。

1串行通信控制器Z85C30介绍

Z85C30是ZILOG公司推出的一种串行通信控制器(SCC)。它具有双通道,适用于8位、16位处理器的系统,能够完成串行到并行、并行到串行的转换。Z85C30能够处理诸如异步格式、面向字节的同步规程(如IBM双同步规程)、面向比特的同步规程(如HDLC、SDLC);能够产生、检查CRC循环冗余检验码。

Z85C30每个通道有14个写寄存器、7个读寄存器。通过对其编程,可将通信控制器配置满足各种格式,如数据长度、停止位的位数、有无奇偶检验等。

1.1Z850C30主要性能

①同步速率。16MHz时钟下,传输速率达4Mb/s;使用16MHz时钟,传输速率达1Mb/s(FM编码);使用16MHz时钟,传输速率达500Kb/s(NRZI编码)。

②异步性能。每个字符5、6、7或8位;1/2或2位停止位;奇或偶校验;1、16、32、64倍时钟格式;断点产生和测试;奇偶、超载和帧出错测试。

③按字节同步性能。内同步或外同步;1或2个同步字符;自动CRC产生、测试。

④SDLC/HDLC性能。异常中止序列的产生和检测;“0”的自动插入和删除,报文间标志的自动插入,地址段的识别,信息段剩余管理,CRC产生、测试;具有EOP识别/循不入口和出口的SDLC方式;可选NRZ、NRZI、曼彻斯特或FM编/解码;具有时钟恢复能力的数字锁相环;具有自动回波和局部回送的诊断能力。

另外,Z85C30能在SDLC/HDLC方式下更高效地工作,如果有10×19位SDLC/HDLC帧状态FIFO,14位SDLC/HDLC帧计数器,自动SDLC/HDLC标志发送,自动复位SDLC/HDLCUnderrun/EOM标志,自动预置SDLC/HDLCCRC等。

1.2Z85C30主要引脚简介

Z85C30引脚按功能分为7组:数据地址总线、总线时序和复位、控制引脚、中断控制、串行数据、通道控制引脚和时钟引脚,如图1所示。Z85C30引脚定义如图2所示。

D7~D0:数据地址总线,用于传送命令和数据。

RD、WR:读、写信号,用于对Z85C30的寄存器操作,低电平有效。

CE:片选信号。

A/B:A、B通道选择,低电平表示选择B通道,高电平选择A通道。

D/C:数据/控制选择,高电平表示与85C30之间传输的是数据,低电平表示与85C30间传输的是命令信号。

INT:中断请求,低电平有效,当SCC需要申请中断时,该信号有效。

INTACK:中断响应,低电平有效。

IEI:中断允许输入。输入,高电平有效。当有多个中断源时,IEI和IEO一起组成中断顺序链优先级排队电路。

IEO:中断允许输出。输出,高电平有效。

PCLK:时钟输入,用来同步内部信号,是标准的TTL电平信号。

TxD、RxD:发送、接收数据,分A、B两个通道。

TRxC、RTxC:通道时钟,它们能被编程为几种不同的操作械。RTxC能提供接收时钟或传送时钟(在输入方式),能提供传输时钟计数器输出(数据锁相器)、晶体振荡器输出、波特率发生器输出和输入时钟输出(它们都是在输出方式)。RTxC能提供接收时钟、传送时钟、波特率发生器时钟、数字锁相环时钟。

1.3Z85C30的接口时序

RD和WR是总线传输的两个控制信号。CE、D/C、A/B和INTACK用于控制总线传输的类型。总线上传输的地址在有效后,RD和WR才变低。CE、WR和CE、RD锁存地址的时序是一致的`。

(1)读周期时序

在RD和CE有效时,A/B和D/C上的地址被锁存。在此周期内CE必须保持低,并且INTACK必须保持高。Z85X30的总线驱动设备只有在RD和CE都有效地才使能。在读操作用D/C为高时,不会影响指针的状态。当D/C为低且在内部操作完成后,指针复位到0。

(2)写周期时序

在CE和WR有效时,A/B、D/C和数据D7~D0同时被锁存。在此周期内CE必须保持低,并且INTACK必须保持高。在写操作且D/C为高时,不会影响指针的状态。当D/C为低且在内部操作完毕后,指针复位到0。

(3)中断响应周期

当INTACK为低时,进入中断响应周期。这个A/B、D/C、CE、WR信号都被忽略。

1.4Z85X30寄存器访问

访问寄存器有两个步骤,是使用寄存器指针来完成寻址的。为寻址一个指定的寄存器,先通过写入WR0的指针位来指定寄存器。因为Z85X30只有唯一的寄存器设置存在,因此,可以从两个通道中的任意一个将指针写入。当指针写入后,再次的读或写周期(当D/C为低时)将存取刚才指定的寄存器。在读和写周期结束时,指针被复位到0。

对RR8(接收数据缓冲FIFO)的读及对WR8(传送数据缓冲FIFO)的写操作,可以按以上方法进行,也可以在D/C为高时进行存取。当D/C为高时,可以直接对相应的数据寄存器进行存取,并且指针的状态为独立的。这样,允许在一个周期内寻址数据寄存器,并且不影响指针的状态。

2Z85C30与CPU的接口

以下介绍以8051作CPU与Z85C30的接口电路,如图3所示。

Z85C30的时钟选用7.0728MHz。54LS373用来锁存片选信号和Z85C30的地址(用来区分命令、数据寄存器)。因为Z85C30的写时序在数据有效后,才应出现WR的下降沿;在数据无效之前,应出现WR上升沿。用1片D触发器54LS74和2个反相器件来延迟送到Z85C30的WR。由于电路设计为TTL电路,在实际的应用,还需加入TTL-RS232转换电路芯片。

3软件设计

3.1Z85Z30的I/O操作

X85C30有三种基本的I/O操作形式:查询、中断、块操作。这三种I/O操作在初始化和数据传送时涉及到寄存器操作。

查询方式依靠软件查询串行控制器,从而决定什么时候数据应从串行控制器输入或输出。在此模式中,主中断使能位和WAIT/DMA请求位都应编程为0,从而清除任何中断或DMA请求。查询是通过对RR0的状态检测进行的。在此模式中,中断功能失效。在转入数据处理前,必须对RR0读分析,以决定进入怎样的例程。

中断方式中,串行控制器的每一个通道包括三个中断源:接收器中断、发送器中断和外部/状态中断。

块操作方式可将W/REQ输出与WR1中的就绪/请求位配合。通过编程,W/REQ输出在块操作方式中能被定义为WAIT信号,在DMA方式中可作为REQ信号。

3.2软件的编写

不同的应用场合,对Z85C30的初始化流程不同,这就需要对Z85C30的写寄存器赋予相应的初值。

图38051与Z85C30的接口电路

在SCC初始化完成后,即可进行通信。传送缓冲区和接收缓冲区全部为空。软件把第1个传送字符写到传送缓冲器,中断才会产生。第1个传送字符到了SCC的移位寄存器,传送中断产生。然后,SCC继续判断中断,直到报文结束。报文结束时,应执行复位发送中断赋值命令,用来禁止发送请求中断。SCC检测到最后一个字符,中断将停止,直到另外的报文写到传送缓冲器。

寄存器RR2用来说明中断矢量和状态,它从B信道读取。RR3是中断赋值寄存器,用来指示中断的类型,它从A信道读取。

外部/状态中断源包括:断点/异常中断、发送欠载/报文结束中断、CTS中断、同步/搜索中断、DCD中断、零计数中断。它由WR1和WR15设置,只有WR1中外部/状态中断允许位置和WR15中的相应控制位置位后,外部/状态条件才会产生中断。

结语

采用该设计方案,能够满足不同通信格式的要求,软件编程可根据实际情况选用查

5.串行通信的工作方式 篇五

①从通信距离上看:并行通信适宜于近距离的数据传送,通常小于30米。而串行通信适宜于远距离传送,可以从几米到数千公里。

②从通信速率上看:在短距离内,并行接口的数据传输速率显然比串行接口的传输速率高得多,但远距离串行数据传送速率比并行数据传送速率易于提高。由于串行通信的通信时钟频率较并行通信容易提高,因此许多高速外部设备如数字摄像机与计算机之间的通信也往往使用串行通信方式。

③从抗干扰性能上看:串行通信由于只有少数几根信号线,信号间的互相干扰比较小。

6.串行通信单片机设计 篇六

一、实验目的及要求

1、了解掌握RS-232接口标准以及 DB9的主要引脚功能;

2、了解掌握串口通信的基本原理;

3、学习掌握RS-232电缆的制作和测试方法;

4、学习掌握使用串口调试程序进行串口之间的通信实验。

二、实验原理

1、异步串行通信原理

在计算机系统中,每个字符一般使用一个 8 位二进制代码表示。在数据通信中,通常将 传送的每个字符的二进制代码按照由低位到高位的顺序依次发送的方式称为串行通信。图 2-1 是串行通信的示意图。由于串行通信只需在发送方和接收方之间建立一条通信信道,因 此可以减小通信系统的造价。在远程通信中,一般采用串行通信方式。

图 1-1 串行通信示意图

同步是数据通信中必须解决的一个重要问题。所谓同步就是要求通信的收发双方在时间基准上保持一致。在串行通信中,“异步”是同步收发双方通信的重要方式。在异步串行通信中,每个字符作为一个独立的整体进行发送,字符之间的时间间隔可以是任意的。为了实现同步,需要在每个字符的第一位前加 1 位起始符(逻辑 1),并在字符的最后一位后加 1位、1.5 位或 2 位停止位(逻辑 0)。异步串行传输的比特流结构如图 2-2所示。

图 1-2 异步串行传输的比特流结构

常用的串行通信接口标准包括RS-232、RS-449、V.24、V.35等。其中,RS-232是最常 用的串行通信标准之一。个人计算机及终端系统中配备的串行接口几乎都符合 RS-232 标准。

2、RS-232 接口标准

串行口是一种最基本的通信接口,基本上所有的个人计算机及通信终端设备都配有这种接口。RS-232 的主要内容就 是定义数据终端设备DTE(data terminal equipment)和数据通信设备DCE(data circuit equipment)之间的接口标准。RS-232 是美国电子工业协会 EIA 推荐使用的串行通信标准。其初衷是为了促进利用电话网进行数据通信应用的发展,现在也普遍应用于各类计算机或终端设备之间的短距离连接。

RS-232 使用的连接器包括 DB-

25、DB-15 和 DB-9 等几种类型,不同类型连接器使用的引脚定义也各不相同。

计算机 RS-232 串行通信的基本过程。图 1-4 异步串行通信实验总体结构示意图

三、实验过程与实验步骤

1、使用制作的 RS-232电缆将 2台计算机的可用 COM 口连接起来。

2、复制串口调试助手到硬盘上。

3、直接双击 “串口调试助手 3.0”运行软件。检查串口线是否连接到计算机和设备上。确定串口(本机为com1)。在串口调试助手中打开串口:com1。

4、使用字符串收发

5、使用文件传输功能

使用文件传输功能,在 2 台电脑上传输文件,这对于某些特定场合可以用到该功能。首先由接收一端在打开串口后,按下接收文件按钮。

之后会弹出一个对话框,等待对方发送文件。

发送一端在打开串口后,先选择发送文件(如下图)

选择文件后,按下发送按钮,文件开始传输中,这时 2 端都可以看到发送的进度条。发送完毕后,软件会提示!

四、实验结果与分析:串口(com1)

1、正常发送:

(1)A机:波特率相同(9600)、校验位相同(none)、数据位相同(8)、停止位相同(1)

B机:波特率相同(9600)、校验位相同(none)、数据位相同(8)、停止位相同(1)结果:A机发“你好”,B机收“你好”,(图1); B机发“哈哈”,A机收“哈哈”,(图2);

图1

图2(2)、A机:波特率相同(19200)、校验位相同(ODD)、数据位相同(8)、停止位相同(2)

B机:波特率相同(19200)、校验位相同(ODD)、数据位相同(8)、停止位相同(2)结果:A机发“我很好”,B机收“我很好”;图3); B机发“你呢”,A机收“你呢”;图4);

图3

图4

2、波特率不同

A机:波特率相同(4800)、校验位相同(ODD)、数据位相同(8)、停止位相同(1)B机:波特率相同(9600)、校验位相同(ODD)、数据位相同(8)、停止位相同(1)结果:A机发“01 02 03”,B机收“胉”;(图5); B机发“yjw”,A机收“?”;(图6); 分析: 图6

图5 波特率控制采样时间间隔,波特率不相同,收发双方在 相等时间内接收和发送数据 不一致。

3、数据位不同

A机:波特率相同(9600)、校验位相同(ODD)、数据位相同(6)、停止位相同(1)B机:波特率相同(9600)、校验位相同(ODD)、数据位相同(8)、停止位相同(1)结果:A机发“040506”,B机收“?”,(图7); B机发“lys”,A机收“,9>”,(图8); 分析:数据位不相同,收发双方在相等时间内接收和发送数据不一致,所以结果不相同

图7

图8

4、奇偶校检不同

(1)A机:波特率相同(9600)、校验位相同(EVE)、数据位相同(8)、停止位相同(1)

B机:波特率相同(9600)、校验位相同(ODD)、数据位相同(8)、停止位相同(1)结果:A机发“54 85 96 75”,B机收“54 85 96 75”;(图9)B机发“第五种”,A机收“第五种”;(图10)分析:因为校验位用于检验 接收和发送的数据的正确性的,在最终转换时会去除校验位,所以接收到的有效数据和发送的有效数据相同,发送与接收结果一样。

图9

图10(2)A机:波特率相同(9600)、校验位相同(NONE)、数据位相同(8)、停止位相同(1)

B机:波特率相同(9600)、校验位相同(ODD)、数据位相同(8)、停止位相同(1)结果:A机发“54 85 96 75”,B机收“

”;(图11)

B机发“第六种”,A机收“第六种”;(图12)

分析:由于A机无校验位,B机有校验位,所以B机在收到数据并校检,后会自动去除校检位以致发双方的有校数据不一致,结果不一样。

相反的。当A机为接收方时,虽然A机无检验位,但是因为A机已接收到8位数据故不接收B机发送的校检位。结果一样。

图11

图12

5、停止位不同

A机:波特率相同(9600)、校验位相同(ODD)、数据位相同(8)、停止位不同(1)B机:波特率相同(9600)、校验位相同(ODD)、数据位相同(8)、停止位不同(2)

图13

结果:A机发“B机收“B机发“

”,A机收“

”,”;(图13)”;(图14)

图14 分析:

5、发送文件

A机:波特率相同(9600)、校验位相同(NONE)、数据位相同(8)、停止位相同(2)B机:波特率相同(9600)、校验位相同(NONE)、数据位相同(8)、停止位相同(2)结果分析:

当有校检位时,不可以接收文件;波特率不同、校验位不同、数据位同或停止位不同时,文件无法接收;即唯有当波特率相同、数据位相同、停止位相同且无校检位时,方可以正确接收文件。

五、思考并回答以下问题:

(1)在本实验中,RS—232 串口电缆处于 OSI 参考模型的什么位置?它的作用是什么?

答:处于OSI 参考模型的物理层,其作用是作为传输介质,连接通信的网络节点,实现比特流的透明传输,为数据链路层提供数据传输服务。

(2)在本实验中,数据和信号分别体现在 OSI参考模型的什么位置?两者之间有何区别?

答:数据体现在数据链路层,信号体现在物理层。两者区别在:数据链路层:为网络层提供服务的,解决两个相邻结点之间的通信问题,传送的协议数据单元称为数据帧。物理层:OSI模型的最底层。它提出了网络的物理特性,比如连接的电缆类型。这里是二进制值0和1的世界,也就是数据以信号的电特性(高低电平)来表示。

(3)什么是波特率?为何两台 PC 的波特率不同就不能正常通信?

答:波特率又称调制速率、传码速率,记为Nbd,是指在数据通信系统中,每秒钟传输信号码元个数,单位是波特。

7.AVR单片机的串行通信 篇七

AVR单片机是由美国ATM EL公司1997年开始逐步设计的一个单片机系列,有几十个品种,它的特点是运算速度快,每秒执行16M条指令;功能强,片内用集成Flash、PWM脉宽调制器、几个定时器计时器、A/D转换器、多个IO口、异步串行口、SRAM、EPROM、SP I同步串行口等。目前AVR系列单片机得到了较为广泛的应用。主要研究其SPI接口。

2 SPI

SPI是AVR单片机的一种串行通信形式。它是一个同步的串行通信总线,这种形式允许MCU与各种外围设备以串行方式进行通信、数据交换;它具有电路简单、速度快、通信可靠等优点。串行外设接口SPI允许AT90系列AVR单片机和外设之间,或几个AVR单片机之间以标准SPI接口协议兼容的方式进行高速的同步数据传输。AVR单片机这种串行接口也同样允许在ATmega系列单片机和外设或其他AVR系列单片机之间高速同步数据传输。AT90系列SPI特征如下:

(1)采用全双工模式,3线同步进行数据传输。

(2)可以当作主机或从机工作。

(3)可配置为MSB方式或LSB方式。

(4)提供7钟频率可编程时钟。

(5)传输结束后发送结束中断标志。

(6)写冲突保护。

(7)可从闲置模式状态下唤醒。

(8)作为主机具有倍速模式。

(9)总线竞争保护等。

SPI通信采用主从模式(Master—Slave)架构,支持多个从端(SPI Slave)模式应用,一般仅支持单个主端(API Master)。Master和Slave都可以同时发送或接收数据,但Master主要负责提供数据传送时的同步时钟。通过时钟的设置Master可以控制数据传输的速度,从而控制了数据的传送。SPI既可以工作在主模式下,也可以工作在从模式下。当工作在主模式下时,每发送或接收一位数据,都需要一次时钟作用;而当工作在从模式下时,每次接收到时钟信号之后才进行一位数据的发送或接收。SPI主机———从机的互联如图1所示,系统包括两个移位寄存器和一个主机时钟发生器。将需要的从机的SS引脚拉低,从而使主机启动一次通信过程。主机和从机将需要发送的数据放入相应的移位寄存器。主机在SCK引脚上产生时钟脉冲以交换数据。SCK引脚是主机模式时的时钟输出以及从机模式的时钟输入。主机数据从主机的MOSI移出,由从机的MOSI移入;从机数据由从机MISO移出,由主机的MISO移入。主机通过将从机的SS拉高实现与从机的同步。这样主机和从机的两个移位寄存器就可以被认为是一个分开的16位环形移位寄存器。

这个系统的发送方向只有一个缓冲器,而在接收方向有两个缓冲器。这就意味着,在发送时,要等到移位过程全部结束后才能对SPI数据寄存器执行写操作。而在数据接收时,在下一个字符移位过程结束前已经收到的数据必须从SPI数据寄存器中读走,否则第一个字节将丢失。当SPI接口被使能时,MOSI、MISO、SCK、SS引脚的控制与数据方向,按表1来配置。

SPI数据寄存器是读/写寄存器,可以用来在寄存器文件和SPI移位寄存器之间传输数据。写寄存器时将初始化数据传送;读寄存器时将读取移位寄存器接收缓冲区的值。

3 实例分析

现将AT90S8535与AT90S4434两个系统相连来进行数据交换。图2所示为SPI演示系统的硬件。数据块首地址分别为BLOCK0和BLOCK1,长度分别为LENGTH0和LENGTH1,所用晶振频率均为8MHz。将AT90S8535设定为主控方式,AT90S4434为从控方式。

主从机软件部分如下:

值得注意的有以下两点:(1)SPI同步串行数据传送是主机和从机互相来交换数据,而不是单纯的主机向从机发送数据;(2)当使用中断方式处理主机的数据传输,并且SS可能被拉低时,中断服务程序检查MSTR是否为“1”,若被置“0”,必须将其置位,以保证SPI为主机模式。

4 结语

介绍AVR单片机的SPI串口通信,AVR单片机作为一种高性能、低功耗的嵌入式微控制器,它的片内资源更为丰富,接口也更为强大,同时由于其价格低等优势,在很多场合可以替代51系列单片机。

摘要:AVR单片机是目前最新单片机系列之一,它以速度高、片内硬件资源丰富著称的微控制器系列。主要研究它的同步串口通信,介绍了AVR单片机SPI接口的工作原理,给出了在实际应用中的几点体会。

关键词:AVR单片机,SPI,串口通信

参考文献

[1]李勋,耿德根.AVR单片机应用技术.北京:北京航空航天大学出版社,2000.

[2]丁化成,耿德根,李君凯.AVR单片机应用设计.北京:北京航空航天大学出版社,2002.

[3]Larry O’Cull,Sarah C.嵌入式C编程与Atmel AVR.周俊杰,等,译.北京:清华大学出版社,2003.

[4]金春林,邱惠芳,张皆喜.AVR系列单片机C语言编程与应用实例.北京:清华大学出版社,2003.

8.串行通信与重叠I/O 篇八

关键词:串行通信;RS232;重叠;I/O;Win API

中图分类号:TN914文献标识码:A文章编号:1007-9599 (2010) 06-0000-02

Serial Communication and Overlapping I/O

Yu Lu,Li Qing

(PLA 91550 Troop,Dalian116023,China)

Abstract:The serial communication to facilitate easy,widely used in both military and civilian.In combination with the hardware described in detail in the Windows environment,use the Win API for asynchronous serial communication method.

Keywords:Serial communication;RS232;Overlap;I/O;Win API

一、前言

串行通讯在通讯领域被广泛应用,标准的RS232接口已成为计算机、计算机外设、交换机和许多通讯设备的标准接口。微机与微机、微机与外设、微机与程控交换机等都可以通过RS232接口进行方便的连接,以实现控制外设和传输数据等目的。

在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。笔者在实际工作中积累了一些经验,现结合硬件、软件,及需要注意的要点作一番探讨。希望对各位需要编写串口通信程序的朋友有一些帮助。

二、RS232串口标准

EIA-RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串行接口标准。该标准规定:直接连接的最大物理距离为15m,通讯速率低于20kbps。

由于RS232并未定义连接器的物理特性,因此,出现了DB-25、DB-15和DB-9各种类型的连接器,其引脚的定义也各不相同。表1介绍了其中两种连接器(DB-25,DB-9)。

RS232标准接口有25条线,4条数据线、11条控制线、3条定时线、7条备用和未定义线,但常用的只有9根。

目前较为常用9针串口和25针串口,当通信距离较近时,可以用电缆线直接连接,若距离较远,须附加Modem。最为简单且常用的是三线制接法,即地、接收数据和发送数据三脚相连。表2列举了RS232串口通信接线方法。

EIA-RS-232对电气特性、逻辑电平和各种信号线功能都作了规定。

在TxD和RxD上:

逻辑1(MARK)=-3V~-15V。

逻辑0(SPACE)=+3V~+15V。

在RTS、CTS、DSR、DTR和DCD等控制线上:

信号有效:(接通,ON状态,正电压)=+3V~+15V。

信号无效:(断开,OFF状态,负电压)=-3V~-15V。

三、Win32串口应用程序

(一)打开串口

Win32系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。该函数的声明为:HANDLE CreateFile(LPCTSTR lpFileName,//文件名DWORD dwDesiredAccess,//访问模式DWORD dwShareMode,//共享模式LPSECURITY_ATTRIBUTES lpSecurityAttributes,//通常为NULL

DWORD dwCreationDistribution,//创建方式

DWORD dwFlagsAndAttributes,//文件属性和标志

HANDLE hTemplateFile // 临时文件的句柄,通常为NULL

);

如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。

(二)串口配置和串口属性

在打开通信设备句柄后,常常需要对串口进行一些初始化工作。这需要通过一个DCB结构来进行。DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。

调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。一般在用CreateFile打开串口后,可以调用GetCommState函数来获取串口的初始配置。要修改串口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB结构来设置串口。

除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。Windows用I/O缓冲区来暂存串口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串口的输入和输出缓冲区的大小。

(三)串口读写

在用ReadFile和WriteFile读写串口时,既可以同步执行,也可以重叠(异步)执行。在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。“重叠”一词的含义就在于此。

ReadFile函数只要在串口输入缓冲区中读入指定数量的字符,就算完成操作。而WriteFile函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串口送出去后才算完成操作。

ReadFile和WriteFile函数是否为执行重叠操作是由CreateFile函数决定的。如果在调用CreateFile创建句柄时指定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进行的读写操作就是重叠的,如果未指定重叠标志,则读写操作是同步的。

函数ReadFile和WriteFile的参数和返回值很相似。这里仅列出ReadFile函数的声明:

BOOL ReadFile(

HANDLE hFile,//文件句柄

LPVOID lpBuffer,//读缓冲区

DWORD nNumberOfBytesToRead,//要求读入的字节数

LPDWORD lpNumberOfBytesRead,//实际读入的字节数

LPOVERLAPPED lpOverlapped//指向一个OVERLAPPED结构

);//若返回TRUE则表明操作成功

需要注意的是如果该函数因为超时而返回,那么返回值是TRUE。参数lpOverlapped在重叠操作时应该指向一个OVERLAPPED结构,如果该参数为NULL,那么函数将进行同步操作,而不管句柄是否是由FILE_FLAG_OVERLAPPED标志建立的。

当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING。

在使用重叠I/O时,线程需要创建OVERLAPPED结构以供读写函数使用。OVERLAPPED结构最重要的成员是hEvent,hEvent是一个事件对象句柄,线程应该用CreateEvent函数为hEvent成员创建一个手工重置事件,hEvent成员将作为线程的同步对象使用。如果读写函数未完成操作就返回,就那么把hEvent成员设置成无信号的。操作完成后(包括超时),hEvent会变成有信号的。

如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还为完成,线程可以等待操作完成。有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult。另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent事件。GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果。

如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。因此,在超时发生后,WaitForSingleObject和GetOverlappedResult都会结束等待。WaitForSingleObject的dwMilliseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去。

在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。

调用PurgeComm函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。

(四)超时设置

在用ReadFile和WriteFile读写串口时,需要考虑超时问题。如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFile或WriteFile的操作就会结束。要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。

有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:

typedef struct_COMMTIMEOUTS {

DWORD ReadIntervalTimeout;//读间隔超时

DWORD ReadTotalTimeoutMultiplier;//读时间系数

DWORD ReadTotalTimeoutConstant;//读时间常量

DWORD WriteTotalTimeoutMultiplier;//写时间系数

DWORD WriteTotalTimeoutConstant;//写时间常量

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

COMMTIMEOUTS结构的成员都以毫秒为单位。总超时的计算公式是:总超时=时间系数×要求读/写的字符数+时间常量

例如,如果要读入10个字符,那么读操作的总超时的计算公式为:读总超时=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant

可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。

如果所有写超时参数均为0,那么就不使用写超时。如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0,则不使用读总超时。如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。

在用重叠方式读写串口时,虽然ReadFile和WriteFile在完成操作以前就可能返回,但超时仍然是起作用的。在这种情况下,超时规定的是操作的完成时间,而不是ReadFile和WriteFile的返回时间。

四、结束语

以上给出了用Win32 API设计串行通信的基本思路,这个重叠(异步)I/O操作的串行通信程序,曾多次应用于大型任务,表现出良好的性能。在实际应用中,可以以此为模型稍加改造,设计出满足需要的各种串行通信程序。

参考文献:

[1]李现勇.Visual C++串口通信技术与工程实践[M].人民邮电出版社,2004,7

上一篇:农村教师下一篇:幼儿心理健康指导策略