串口通讯
一、DOS下的串口编程
当向串口写字符时(即当AH=1时),AL寄存器中的字符是需要写入的字符。
当向串口写字符时(即当AH=2时),AL寄存器中的字符是需要读取的字符。
#include
#include
#include
#define STR "author:sbh"
union REGS inregs,outregs;
main()
{
init_rs232();
write_rs232(STR,strlen(STR));
read_rs232();
return(0);
}
int init_rs232()
{
do{
inregs.h.ah=0;
inregs.h.al=0xe7;
inregs.x.dx=0;
int86(0x14,&inregs,&outregs);
}while(outregs.h.ah>=0x80);
return(0);
}
int write_rs232(char *string,int len)
{
int i;
do{
inregs.h.ah=1;
inregs.h.al=*string;
inregs.x.dx=0;
int86(0x14,&inregs,&outregs);
}while(outregs.h.al>=0x80);
for(i=1;i
inregs.h.ah=1;
inregs.h.al=*(string+i);
inregs.x.dx=0;
int86(0x14,&inregs,&outregs);
}
}
int read_rs232()
{
do{
inregs.h.ah=2;
inregs.x.dx=0;
int86(0x14,&inregs,&outregs);
}while(outregs.h.ah!=3||outregs.h.ah>=0x80);
return(0);
}
int _Cdecl int86(int intno, union REGS inregs, union REGS outregs)
其中intno为软中断号;
union REGS{
struct WORDREGS x;
struct BYTEREGS h;
};
struct WORDREGS{
unsigned int ax,bx,cx,dx,si,di,cflag,flag;
};
struct BYTEREGS{
unsigned char al,ah,bl,bh,cl,ch,dl,dh;
};
Int _Cdecl int86x(int intno,union REGS inregs, union REGS outregs, struct
SREGS segregs);
struct SREGS
{
unsigned int es;
unsigned int cs;
unsigned int ss;
unsigned int ds;
}
二、WIN32 API的串口编程
函数:HANDLE CreateFile(LPCTSTR lpFileName,//将要打开的串口逻辑名,如
COM1,COM2
DWORD dwAccess,//指定串口访问的类型,可以是读取、写入或两者并列
DWORD dwShareMode,//指定共享属性,由于串口不能共享,该参数必须置0
LPSECURITY_ATTRIBUTES lpsa,//引用安全性属性结构,缺省为NULL
DWORD dwCreate,//创建标志,对串口操作该参数必须置为OPEN_EXISTING
DWORD dwAttrsAndFlags,//属性描述,用于指定该串口是否可进行异步操作,
FILE_FLAG_OVERLAPPED:可使用异步的I/O
HANDLE hTemplateFile//指向模板文件的句柄,对串口而言该参数必须置为NULL
);
配置串口:
typedef struct _DCB{
DWORD DCBlength;
DWORD BaudRate;
DWORD fBinary:1;
DWORD fParity:1;
DWORD fOutxCtsFlow:1;
DWORD fOutxDsrFlow:1;
DWORD fDtrControl:2;
DWORD fDsrSensitivity:1;
DWORD fTXContinueOnXoff:1;
DWORD fOutX:1;
DWORD fInX:1;
DWORD fErrorChar:1;
DWORD fNull:1;
DWORD fRtsControl:2;
DWORD fAbortOnError:1;
DWORD fDummy2:17;
WORD wReserved;
WORD XonLim;
WORD XoffLim;
BYTE ByteSize;
BYTE StopBits;
char XonChar;
char XoffChar;
char ErrorChar;
char EofChar;
char EvtChar;
WORD wReserved1;
}DCB;
BOOL SetupComm( HANDLE hFile,//handle to communications device
DWORD dwInQueue, //size of input buffer
DWORD dwOutQueue //size of output buffer
);
设置超时:
typedef struct _COMMTIMEOUTS
{
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
}COMMTIMEOUTS,*LPCOMMTIMEOUTS;
BOOL SetCommTimeouts(HANDLE hFile,//handle to communications device
LPCOMMTIMEOUTS lpCommTimeouts// pointer to comm time-out structure
);
得到超时:
BOOL GetCommTimeouts(HANDLE hFile,//handle of communications device
LPCOMMTIMEOUTS lpCommTimeouts//pointer to com time-out structure
);
在读写串口之前,需要用SetCommMask()函数设置事件掩模来监视指定通讯端口上的
事件,其函数:
BOOL SetCommMask(
HANDLE hFile,//标识通讯端口的句柄
DWORD dwEvtMask//能够使能的通讯事件
);
有了Set当然还会有Get,与SetCommMask对应的GetCommMask()函数
BOOL GetCommMask(
HANDLE hFile;//标识通讯端口的句柄
LPDWORD lpEvtMask// address of vaariable to get event mask
);
串口上可以发生的事件可以是如下事件的一个或任意组合:EV_BREAK、EV_CTS、EV_DSR、EV_ERR、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。
我们可以用WaitCommEvent()函数来等待串口上我们利用SetCommMask()函数的事件:
BOOL WaitCommEvent(
HANDLE hFile,//标识通信端口的句柄
LPDWORD lpEvtMask,//address of variable for event that occurred
LPOVERLAPPED lpOverlapped// address of overlapped structure
);