文档库 最新最全的文档下载
当前位置:文档库 › VC实现串口通信例程

VC实现串口通信例程

VC实现串口通信例程
VC实现串口通信例程

VC实现串口通信例程

作者:阮帮秋(2001.4)

摘要:WIN95界面下的VC++串口通讯程序在WIN32下是不建议对端口进行操作的,在WIN32中所有的设备都被看成是文件,串行口也不例外也是作为文件来进行处理的。

关键词串行口,DWORD,缓冲区

WIN95界面下的VC++串口通讯程序在WIN32下是不建议对端口进行操作的,在WIN32中所有的设备都被看成是文件,串行口也不例外也是作为文件来进行处理的。这是我的一份关于串口编程的读书笔记,对于使用VC进行编程的同行应该有一定的帮助。

1.打开串口:

在Window 95下串行口作为文件处理,使用文件操作对串行口进行处理。使用CreateFile()打开串口,CreateFile()将返回串口的句柄。

HANDLE CreateFile(

LPCTSTR lpFileName, // pointer to name of the file

DWORD dwDesiredAccess, // access (read-write) mode

DWORD dwShareMode, // share mode

LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes

DWORD dwCreationDistribution, // how to create

DWORD dwFlagsAndAttributes, // file attributes

HANDLE hTemplateFile // handle to file with attributes to copy

);

lpFileName: 指明串口制备,例:COM1,COM2

dwDesiredAccess: 指明串口存取方式,例:GENERIC_READ|GENERIC_WRITE

dwShareMode: 指明串口共享方式

lpSecurityAttributes: 指明串口的安全属性结构,NULL为缺省安全属性

dwCreateionDistribution: 必须为OPEN_EXISTIN

dwFlagAndAttributes: 对串口唯一有意义的是FILE_FLAG_OVERLAPPED

hTemplateFile: 必须为NULL

2.关闭串口:

CloseHandle(hCommDev);

3.设置缓冲区长度:

BOOL SetupComm(

HANDLE hFile, // handle of communications device

DWORD dwInQueue, // size of input buffer

DWORD dwOutQueue // size of output buffer

);

https://www.wendangku.net/doc/8214316451.html,MPROP结构:

可使用GetCommProperties()取得COMMPROP结构,COMMPROP结构中记载了系统支持的各项设置。

typedef struct _COMMPROP { // cmmp

WORD wPacketLength; // packet size, in bytes

WORD wPacketVersion; // packet version

DWORD dwServiceMask; // services implemented

DWORD dwReserved1; // reserved

DWORD dwMaxTxQueue; // max Tx bufsize, in bytes

DWORD dwMaxRxQueue; // max Rx bufsize, in bytes

DWORD dwMaxBaud; // max baud rate, in bps

DWORD dwProvSubType; // specific provider type

DWORD dwProvCapabilities; // capabilities supported

DWORD dwSettableParams; // changeable parameters

DWORD dwSettableBaud; // allowable baud rates

WORD wSettableData; // allowable byte sizes

WORD wSettableStopParity; // stop bits/parity allowed

DWORD dwCurrentTxQueue; // Tx buffer size, in bytes

DWORD dwCurrentRxQueue; // Rx buffer size, in bytes

DWORD dwProvSpec1; // provider-specific data

DWORD dwProvSpec2; // provider-specific data

WCHAR wcProvChar[1]; // provider-specific data

} COMMPROP;

dwMaxBaud:

BAUD_075 75 bps

BAUD_110 110 bps

BAUD_134_5 134.5 bps

BAUD_150 150 bps

BAUD_300 300 bps

BAUD_600 600 bps

BAUD_1200 1200 bps

BAUD_1800 1800 bps

BAUD_2400 2400 bps

BAUD_4800 4800 bps

BAUD_7200 7200 bps

BAUD_9600 9600 bps

BAUD_14400 14400 bps

BAUD_19200 19200 bps

BAUD_38400 38400 bps

BAUD_56K 56K bps

BAUD_57600 57600 bps

BAUD_115200 115200 bps

BAUD_128K 128K bps

BAUD_USER Programmable baud rates available

dwProvSubType:

PST_FAX 传真设备

PST_LAT LAT协议

PST_MODEM 调制解调器设备

PST_NETWORK_BRIDGE 未指定的网桥

PST_PARALLELPORT 并口

PST_RS232 RS-232口

PST_RS422 RS-422口

PST_RS423 RS-432口

PST_RS449 RS-449口

PST_SCANNER 扫描仪设备

PST_TCPIP_TELNET TCP/IP Telnet协议

PST_UNSPECIFIED 未指定

PST_X25 X.25标准

dwProvCapabilities

PCF_16BITMODE 支持特殊的16位模式

PCF_DTRDSR 支持DTR(数据终端就绪)/DSR(数据设备就绪)

PCF_INTTIMEOUTS 支持区间超时

PCF_PARITY_CHECK 支持奇偶校验

PCF_RLSD 支持RLSD(接收线信号检测)

PCF_RTSCTS 支持RTS(请求发送)/CTS(清除发送)

PCF_SETXCHAR 支持可设置的XON/XOFF

PCF_SPECIALCHARS 支持特殊字符

PCF_TOTALTIMEOUTS 支持总(占用时间)超时

PCF_XONXOFF 支持XON/XOFF流控制

标准RS-232和WINDOW支持除PCF_16BITMODE和PCF_SPECIALCHAR外的所有功能dwSettableParams

SP_BAUD 可配置波特率

SP_DATABITS 可配置数据位个数

SP_HANDSHAKING 可配置握手(流控制)

SP_PARITY 可配置奇偶校验模式

SP_PARITY_CHECK 可配置奇偶校验允许/禁止

SP_RLSD 可配置RLSD(接收信号检测)

SP_STOPBITS 可配置停止位个数

标准RS-232和WINDOW支持以上所有功能

wSettableData

DATABITS_5 5个数据位

DATABITS_6 6个数据位

DATABITS_7 7个数据位

DATABITS_8 8个数据位

DATABITS_16 16个数据位

DATABITS_16X 通过串行硬件线路的特殊宽度路径

WINDOWS 95支持16的所有设置

5.DCB结构:

typedef struct _DCB {// dcb

DWORD DCBlength; // sizeof(DCB)

DWORD BaudRate; // current baud rate

指定当前的波特率

DWORD fBinary: 1; // binary mode, no EOF check

指定是否允许二进制模式,

WINDOWS 95中必须为TRUE

DWORD fParity: 1; // enable parity checking

指定奇偶校验是否允许

DWORD fOutxCtsFlow:1; // CTS output flow control

指定CTS是否用于检测发送控制。

当为TRUE是CTS为OFF,发送将被挂起。

DWORD fOutxDsrFlow:1; // DSR output flow control

指定CTS是否用于检测发送控制。

当为TRUE是CTS为OFF,发送将被挂起。

DWORD fDtrControl:2; // DTR flow control type

DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON,

DTR_CONTROL_HANDSHAKE允许DTR"握手",DWORD fDsrSensitivity:1; // DSR sensitivity 当该值为TRUE 时DSR为OFF时接收的字节被忽略

DWORD fTXContinueOnXoff:1; // XOFF continues Tx

指定当接收缓冲区已满,并且驱动程序已经发

送出XoffChar字符时发送是否停止。

TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。

FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。

DWORD fOutX: 1; // XON/XOFF out flow control

TRUE时,接收到XoffChar之后便停止发送

接收到XonChar之后将重新开始

DWORD fInX: 1; // XON/XOFF in flow control

TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去

接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去

DWORD fErrorChar: 1; // enable error replacement

该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符DWORD fNull: 1; // enable null stripping

TRUE时,接收时去掉空(0值)字节

DWORD fRtsControl:2; // RTS flow control

RTS_CONTROL_DISABLE时,RTS置为OFF

RTS_CONTROL_ENABLE时, RTS置为ON

RTS_CONTROL_HANDSHAKE时,

当接收缓冲区小于半满时RTS为ON

当接收缓冲区超过四分之三满时RTS为OFF

RTS_CONTROL_TOGGLE时,

当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF

DWORD fAbortOnError:1; // abort reads/writes on error TRUE时,有错误发生时中止读和写操作

DWORD fDummy2:17; // reserved

未使用

WORD wReserved; // not currently used

未使用,必须为0

WORD XonLim; // transmit XON threshold

指定在XON字符发送这前接收缓冲区中可允许的最小字节数

WORD XoffLim; // transmit XOFF threshold

指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数BYTE ByteSize; // number of bits/byte, 4-8

指定端口当前使用的数据位

BYTE Parity; // 0-4=no,odd,even,mark,space

指定端口当前使用的奇偶校验方法,可能为:

EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY

BYTE StopBits; // 0,1,2 = 1, 1.5, 2

指定端口当前使用的停止位数,可能为:

ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS

char XonChar; // Tx and Rx XON character

指定用于发送和接收字符XON的值

char XoffChar; // Tx and Rx XOFF character

指定用于发送和接收字符XOFF值

char ErrorChar; // error replacement character

本字符用来代替接收到的奇偶校验发生错误时的值

char EofChar; // end of input character

当没有使用二进制模式时,本字符可用来指示数据的结束

char EvtChar; // received event character

当接收到此字符时,会产生一个事件

WORD wReserved1; // reserved; do not use 未使用

} DCB;

6.改变端口设置

使用如下的两个方法

BOOL GetCommState(hComm,&dcb);

BOOL SetCommState(hComm,&dcb);

7.改变普通设置

BuildCommDCB(szSettings,&DCB);

szSettings的格式:baud parity data stop 例: "baud=96 parity=n data=8 stop=1"

简写:"96,N,8,1"

szSettings 的有效值

baud:

11 or 110 = 110 bps

15 or 150 = 150 bps

30 or 300 = 300 bps

60 or 600 = 600 bps

12 or 1200 = 1200 bps

24 or 2400 = 2400 bps

48 or 4800 = 4800 bps

96 or 9600 = 9600 bps

19 or 19200= 19200bps

parity:

n=none

e=even

o=odd

m=mark

s=space

data:

5,6,7,8

StopBit

1,1.5,2

https://www.wendangku.net/doc/8214316451.html,MCONFIG结构:

typedef struct _COMM_CONFIG {

DWORD dwSize;

WORD wVersion;

WORD wReserved;

DCB dcb;

DWORD dwProviderSubType;

DWORD dwProviderOffset;

DWORD dwProviderSize;

WCHAR wcProviderData[1];

} COMMCONFIG, *LPCOMMCONFIG;

可方便的使用BOOL CommConfigDialog(

LPTSTR lpszName,

HWND hWnd,

LPCOMMCONFIG lpCC);

来设置串行口。

9.超时设置:

可通过COMMTIMEOUTS结构设置超时,

typedef struct _COMMTIMEOUTS {

DWORD ReadIntervalTimeout;

DWORD ReadTotalTimeoutMultiplier;

DWORD ReadTotalTimeoutConstant;

DWORD WriteTotalTimeoutMultiplier;

DWORD WriteTotalTimeoutConstant;

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

区间超时:(仅对从端口中读取数据有用)它指定在读取两个字符之间要经历的时间总超时: 当读或写特定的字节数需要的总时间超过某一阈值时,超时触发.

超时公式:

ReadTotalTimeout = (ReadTotalTimeoutMultiplier * bytes_to_read)

+ ReadToTaltimeoutConstant

WriteTotalTimeout = (WriteTotalTimeoutMuliplier * bytes_to_write)

+ WritetoTotalTimeoutConstant

NOTE:在设置超时时参数0为无限等待,既无超时

参数MAXDWORD为立即返回

超时设置:

GetCommTimeouts(hComm,&timeouts);

SetCommTimeouts(hComm,&timeouts);

10.查询方式读写数据

例程:

COMMTIMEOUTS to;

DWORD ReadThread(LPDWORD lpdwParam)

{

BYTE inbuff[100];

DWORD nBytesRead;

if(!(cp.dwProvCapabilities&PCF_INTTIMEOUTS))

return 1L;

memset(&to,0,sizeof(to));

to.ReadIntervalTimeout = MAXDWORD;

SetCommTimeouts(hComm,&to);

while(bReading)

{

if(!ReadFile(hComm,inbuff,100,&nBytesRead,NULL))

locProcessCommError(GetLastError());

else

if(nBytesRead)

locProcessBytes(inbuff,nBytesRead);

}

PurgeComm(hComm,PURGE_RXCLEAR);

return 0L;

}

NOTE:

PurgeComm()是一个清除函数,它可以中止任何未决的后台读或写,并且可以冲掉I/O缓冲区.

BOOL PurgeComm(HANDLE hFile,DWORD dwFlags);

dwFlages的有效值:

PURGE_TXABORT: 中止后台写操作

PRUGE_RXABORT: 中止后台读操作

PRUGE_TXCLEAR: 清除发送缓冲区

PRUGE_RXCLEAR: 清除接收缓冲区

技巧:

可通过ClearCommError()来确定接收缓区中处于等待的字节数。

BOOL ClearCommError(

HANDLE hFile, // handle to communications device

LPDWORD lpErrors, // pointer to variable to receive error codes

LPCOMSTAT lpStat // pointer to buffer for communications status

);

ClearCommError()将返回一个COMSTAT结构:

typedef struct _COMSTAT { // cst

DWORD fCtsHold : 1; // Tx waiting for CTS signal

DWORD fDsrHold : 1; // Tx waiting for DSR signal

DWORD fRlsdHold : 1; // Tx waiting for RLSD signal

DWORD fXoffHold : 1; // Tx waiting, XOFF char rec`d

DWORD fXoffSent : 1; // Tx waiting, XOFF char sent

DWORD fEof : 1; // EOF character sent

DWORD fTxim : 1; // character waiting for Tx

DWORD fReserved : 25; // reserved

DWORD cbInQue; // bytes in input buffer

DWORD cbOutQue; // bytes in output buffer

} COMSTAT, *LPCOMSTAT;

其中的cbInQue和cbOutQue中即为缓冲区字节。

11.同步I/O读写数据

COMMTIOMOUTS to;

DWORD ReadThread(LPDWORD lpdwParam)

{

BYTE inbuff[100];

DWORD nByteRead,dwErrorMask,nToRead;

COMSTAT comstat;

if(!cp.dwProvCapabilities&PCF_TOTALTIMEOUTS)

return 1L;

memset(&to,0,sizeof(to));

to.ReadTotalTimeoutMultiplier = 5;

to.ReadTotalTimeoutConstant = 50;

SetCommTimeouts(hComm,&to);

while(bReading)

{

ClearCommError(hComm,&dwErrorMask,&comstat);

if(dwErrorMask)

locProcessCommError(dwErrorMask);

if(comstat.cbInQue >100)

nToRead = 100;

else

nToRead = comstat.cbInQue;

if(nToRead == 0)

continue;

if(!ReadFile(hComm,inbuff,nToRead,&nBytesRead,NULL))

locProcessCommError(GetLastError());

else

if(nBytesRead)

locProcessBytes(inbuff,nBytesRead);

}

return 0L;

}

12.异步I/O读写数据

当CreateFile()中的fdwAttrsAndFlags参数为FILE_FLAG_OVERLAPPEN时, 端口是为异步I/O打开的,此时可以在ReadFile的最后一个参数中指定一个OVERLAPPED结构,使数据的读操作在后台进行。WINDOWS 95包括了异步I/O的许多变种。

typedef struct _OVERLAPPED {

DWORD Internal;

DWORD InternalHigh;

DWORD Offset;

DWORD OffsetHigh;

HANDLE hEvent;

} OVERLAPPED;

对于串行口仅hEvent成员有效,其于成员必须为0。

例程:

COMMTIMEOUTS to;

...

DWORD ReadThread((LPDWORD lpdwParam)

{

BYTE inbuff[100];

DWORD nRytesRead,endtime,lrc;

static OVERLAPPED o;

if(!cp.dwProvCapabilities & PCF_TOTALTIMEOUTS)

return 1L;

memset(&to,0,sizeof(to));

to.ReadTotalTimeoutMultiplier = 5;

to.ReadTotalTimeoutConstant = 1000;

SetCommTimeouts(hComm,&to);

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

while(bReading)

{

if(!ReadFile(hComm,inbuff,10,&nBytesRead,&o))

{

nBytesRead = 0;

if(lrc=GetLastError() == ERROR_IO_PENDING)

{

endtime = GetTickCount() + 1000;

while(!GetOverlappedResult(hComm,&o,&nBytesRead,FALSE)) if(GetTickCount() > endtime) break;

}

if(nBytesRead) locProcessBytes(inbuff,nBytesRead);

}

else

{

if(nBytesRead) locProcessBytes(inbuff,nBytesRead); ResetEvent(o.hEvent);

}

}

PurgeComm(hComm,PURGE_RXCLEAR);

return 0L;

}

这一例程是对一开始读缓冲区就读到所需的字节时的处理:while(bReading)

{

if(!ReadFile(hComm,inbuff,10,&nBytesRead,&o))

{

if((lrc=GetLastError()) ==ERROR_IO_PENDING)

{

if(GetOverlappedResult(hComm,&o,&nBytesRead,TRUE))

{

if(nBytesRead)

locProcessBytesa(inbuff,nBytesRead);

}

else

locProcessCommError(GetLastError());

}

else

locProcessCommError(GetLastError));

}

else

if(nBytesRead) locProcessBytes(inbuff,nBytesRead);

ResetEvent(o.hEvent);

}

13.事件驱I/O读写:

GetCommMask(hComm,&dwMask)

Windows 95报告给应用程序的事件由此方法返回。

SetCommMasl(hComm,&dwMask)

添加或修改Windows 95所报告的事件列表。

事件掩码如下:

EV_BREAK 检测到输入为止

EV_CTS CTS(清除发送)信号改变状态

EV_DSR DSR(数据设置就绪)信号改变状态

EV_ERR 发生了线路状态错误.

线路状态错误为:

CE_FRAME(帧错误)

CE_OVERRUN(接收缓冲区超限)

CE_RXPARITY(奇偶校验错误)

EV_RING 检测到振铃

EV_RLSD RLSD(接收线路信号检测)信号改变状态

EV_EXCHAR 接收到一个字符,并放入输入缓冲区

EV_RXFLAG 接收到事件字符(DCB成员的EvtChar成员),度放入输入缓冲区

EV_TXEMPTY 输出缓冲区中最后一个字符发送出去

在用SetCommMask指定了有用的事件后,应用程序可调用WaitCommEvent()来等待事件发生.

BOOL WaitCommEvent(

HANDLE hFile, // handle of communications device

LPDWORD lpEvtMask, // address of variable for event that occurred

LPOVERLAPPED lpOverlapped, // address of overlapped structure

);

此方法可以以同步或异步方式操作

例程:

COMMTIMEOUTS to;

...

DWORD ReadTherad(LPDWORD lpdwParam)

{

BYTE binbuff[100];

DWORD nBytesRead,dwEvent,dwError;

COMSTAT cs;

SetCommMask(hComm,EV_RXHAR);

while(bReading)

{

if(WaitCommEvent(hComm,&dwEvent,NULL))

{

ClearCommError(hComm,&dwError,&cs);

if((dwEvent&EV_RXCHAR)&&cs.cbInQue)

{

if(!ReadFile(hComm,inbuff,cs.cbInQue,&nBytesRead,NULL)

locProcessCommError(GetLastError());

}

else

{

if(nByteRead)

locProcessBytes(inbuff,nBytesRead);

}

else

locProcessCommError(GetLastError());

}

PurgeComm(hComm,PURGE_RXCLEAR);

return 0L;

}

NOTE: SetCommMask(hComm,0)可使WaitCommEvent()中止.

可使用GetCommmodemStatus()方法,例程:

if(cp.dwProvCapabilities&PCF_RTSCTS)

{

SetCommMask(hComm,EV_CTS);

WaitCommEvent(hComm,&dwMask,NULL);

if(dwMask&EV_CTS)

{

GetCommModemStatus(hComm,&dwStatus)

if(dwStatus&MS_CTS_ON) /* CTS stransition OFF-ON */

else /* CTS stransition ON-OFF */

}

}

MS_CTS_ON CTS为ON

MS_DSR_ON DSR为ON

MS_RING_ON RING为ON

MS_ELSD_ON RLSD为ON

14.错误

当发生错误时应用方法ClearCommError(hComm,&dwErrorMask,&constat)得到错误掩码。

CE_BREAK 中止条件

CE_FRAME 帧错误

CW_IOE 一般I/O错误,常伴有更为详细的错误标志

CE_MODE 不支持请求的模式

CE_OVERRUN 缓冲区超限下一个字符将丢失

CE_RXOVER 接收缓冲区超限

CE_RXPARITY 奇偶校验错误

CE_TXFULL 发送缓冲区满

CE_DNS 没有选择并行设备

CE_PTO 并行设备发生超时

CE_OOP 并行设备缺纸

15.控制命令

EscapeCommFunction()可将硬件信号置ON或OFF,模拟XON或XOFF

BOOL EscapeCommFunction(

HANDLE hFile, // handle to communications device

DWORD dwFunc // extended function to perform

);

dwFunc的有效值(可用'|'同时使用多个值)

CLRDTR DTR置OFF

CLRRTS RTS置OFF

SETDTR STR置ON

SETRTS TRS置ON

SETXOFF 模拟XOFF字符的接收

SETXON 模拟XON字符的接收

SETBREAK 在发送中产生一个中止

CLRBREAK 在发送中清除中止

51串口通信程序(带详细注释)

51串口通信程序(带详细注释) #include#include //后面有一个比较函数#define uchar unsigned char#define uint unsigned intbit UART_Flag=0; //定义串口接收标志位 uchar str[50]; //定义一数组uchar length=0; //数组长度从0 开始void init() //初 始化uart{ TMOD=0X20; //定时器1 定时器方式工作模式2,可自动重载的8 位计数器常把定时/计数器1 以模式2 作为串行口波特率发生器 SCON=0X50; //选择工作模式1 使能接收,允许发送,允许接收 EA=1; //开总中断 ES=1; //打开串口中断ET1=0; //打开定时器中断 PCON=0X80; //8 位自动重载,波特率加倍 TH1=0XFF; //用22.1184 mhz 波特率 TL1=0XFF;TR1=1; //打开中时器 }void UART_Putch(uchar dat) //输出一个字符{SBUF=dat; //把数据送给sbuf 缓 存器中 while(TI!=1);//发送标志位TI 如果发送了为1,没发送为0,没发送等待,到 了退出循环 TI=0; //到了,TI 清为0 }void init1() interrupt 4 //uart 中断,4 为串口中断{ if(RI==1) //收到数据{ uchar m=SBUF; //m 为计算机发送给串口的数据,例,open //总体思想是,计算 机通知串口,我要发数据了RI=0; //收到清0 if(m==) //判断m 这位数据有无{ UART_Putch(); //回车UART_Putch(); // 换行str[length]=; //数据最后位加0 标 志位表示发完了数据UART_Flag=1; // 传完标志位} else if(m==) { } else if(m==)//b表退格//下面几句表删锄{ UART_Putch();

VC与c51串口通讯程序

跟着步骤学习 1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest 2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX就可以了), 这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw 文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标 将此图标拖到对话框中,程序运行后,这个图标是看不到的。 3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard ->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1 添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动 加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。 4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显 示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为 IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内 容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。别忘记了将接收编辑 框的Properties->Styles中把Miltiline和Vertical Scroll属性选上,发送编辑框若你想输入多行文字,也可选上Miltiline。 再打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_EDIT_RXDATA 添加CString变量m_strRXData,为IDC_EDIT_TXDATA添加CString变量m_strTXData。说明: m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。 5.添加串口事件消息处理函数OnComm()打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。 这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件,我们刚才添加的函数就会执行,我们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。请你在函数中加入如下代码: void CSCommTestDlg::OnComm() { // TODO: Add your control notification handler code here VARIANT variant_inp; COleSafeArray safearray_inp; LONG len,k; BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed. CString strtemp; if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符 { ////////以下你可以根据自己的通信协议加入处理代码 variant_inp=m_ctrlComm.GetInput(); //读缓冲区 safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量 len=safearray_inp.GetOneDimSize(); //得到有效数据长度 for(k=0;k

51单片机串口通信,232通信,485通信,程序

51单片机串口通信,232通信,485通信,程序代码1:232通信 #include #define uchar unsigned char #define uint unsigned int uchar flag,a,i; uchar code table[]="i get"; void init() { TMOD=0X20; TH1=0XFD; TH0=0XFD; TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1; } void main() { init();

while(1) { if(flag==1) { ES=0; for(i=0;i<6;i++) { SBUF=table[i]; while(!TI); TI=0; } SBUF=a; while(!TI); TI=0; ES=1; flag=0; } } } void ser() interrupt 4 {

RI=0; a=SBUF; flag=1; } 代码2:485通信 #include #include"1602.h" #define uchar unsigned char #define uint unsigned int unsigned char flag,a,i; uchar code table[]="i get "; void init() { TMOD=0X20; TH1=0Xfd; TL1=0Xfd; TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1;

} void main() { init_1602(); init(); while(1) { if(flag==1) { display(0,a); } } } void ser() interrupt 4 { RI=0; a=SBUF; flag=1; } Love is not a maybe thing. You know when you love someone.

VC6.0MFC串口通信编写全过程(DOC)

其于MFC 的串口调试助手编辑过程 一、新建 打开 VC6.0 文件 新建 工程 MFC AppWiard(exe) 位置(选择保存工程位置) 工程名称(输入工程名XXXX ) 确定 选择基本对话框 下一步 下一步 下一步 选择(CXXXXDlg ) 完成 确定 在生成的基本对话框内将不需要按钮及提示框(自动生成的“确定”“取消” 及提示框)删除或修改使用,至此基本框架完成如下图: 二、往生成的基本框架中添加控件 1、因为控件列表框内没有串口通信用到的通信控件,所以要先添加到控件列表框内再将控件添加到基本框内使用,步骤如下: 菜单栏 工程 添加到工程 Components and controls … Registered ActiveX Controls 选择“Microsoft Communications Control, version 6.0” Insert 确定 OK 关闭此子窗口完成添加操作标志如上图所示。 2、将刚才添加添加到控件列表框内的串口控件添加到基本框架内 点击控件列表框内的串口控件,此时光标变为“十”形,在基本框架内随意划取一矩 形区域,即可以添加串口控件,不需要修改此控件的大小及位置,因为程编译运行后此控件是看不到的,步骤结果如下图:

3、继续往基本框架内添加用于编辑发送数据的输入编辑框及输出编辑框,同理选择控件列表框内的“编辑框控件”,以相同的操作即可添加两个编辑窗口及一个按纽控件如下图所示: 这两个窗口需要修改大小及位置,因为程序运行后将会显示而串口通信控件则不显示,上图是运行后的效果。 4、对以上四个控件编程步骤如下: a 、右击串口通信控件 建立类向导 Member variables Control IDS 中选择IDC_MSCOMM1 add variable … Member variable name 中输入控件变量名m_ctrlComm (变量名可以随意选取,但程序中应与所取变量名一致) OK 确定

VC++_串口上位机编程实例

VC++串口上位机简单例程(源码及详细步骤) (4.33MB) VC++编写简单串口上位机程序 2010年4月13日10:23:40 串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。 编译环境:VC++6.0 操作系统:VMWare虚拟出来的Windows XP 程序实现功能: 1、PC初始化COM1口,使用n81方式,波特率57600与单片机通信。PC的COM口编号可以通过如下方式修改: 当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。COM1口可用的话,会提示串口初始化完毕。否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。 2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC转

换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC进行数值转换后在窗口里显示。(见文章末尾图) 3、为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口,点击可重新打开COM1。 程序的编写: 1、打开VC++6.0建立基于对话框的MFC应用程序Test,

2、在项目中插入MSComm控件:工程->增加到工程->Components and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control,version6.0->Insert,按

单片机串口通信C程序及应用实例

一、程序代码 #include//该头文件可到https://www.wendangku.net/doc/8214316451.html,网站下载#define uint unsigned int #define uchar unsigned char uchar indata[4]; uchar outdata[4]; uchar flag; static uchar temp1,temp2,temp3,temp; static uchar R_counter,T_counter; void system_initial(void); void initial_comm(void); void delay(uchar x); void uart_send(void); void read_Instatus(void); serial_contral(void); void main() { system_initial(); initial_comm(); while(1) { if(flag==1) { ES = 0; serial_contral(); ES = 1; flag = 0; } else read_Instatus(); } } void uart_send(void) { for(T_counter=0;T_counter<4;T_counter++) { SBUF = outdata[T_counter]; while(TI == 0);

TI = 0; } T_counter = 0; } uart_receive(void) interrupt 4 { if(RI) { RI = 0; indata[R_counter] = SBUF; R_counter++; if(R_counter>=4) { R_counter = 0; flag = 1; } } } void system_initial(void) { P1M1 = 0x00; P1M0 = 0xff; P1 = 0xff; //初始化为全部关闭 temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致 temp = 0xf0; R_counter = 0; T_counter = 0; } void initial_comm(void) { SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit Reload PCON = 0x80; //波特率不加倍SMOD = 1 TH1 = 0xfa; //baud: 9600;fosc = 11.0596 IE = 0x90; // enable serial interrupt TR1 = 1; // timer 1 RI = 0; TI = 0; ES = 1; EA = 1; }

(完整版)VC6.0MFC串口通信编写全过程

其于MFC的串口调试助手编辑过程 一、新建 打开VC6.0 文件新建工程MFC AppWiard(exe) 位置(选择保存工程位置)工程名称(输入工程名XXXX)确定选择基本对话框下一步下一步下一步选择(CXXXXDlg)完成确定在生成的基本对话框内将不需要按钮及提示框(自动生成的“确定”“取消”及提示框)删除或修改使用,至此基本框架完成如下图: 二、往生成的基本框架中添加控件 1、因为控件列表框内没有串口通信用到的通信控件,所以要先添加到控件列表框内再 将控件添加到基本框内使用,步骤如下: 菜单栏工程添加到工程Components and controls…Registered ActiveX Controls 选择“Microsoft Communications Control, version 6.0”Insert 确定OK 关闭此子窗口完成添加操作标志如上图所示。 2、将刚才添加添加到控件列表框内的串口控件添加到基本框架内 点击控件列表框内的串口控件,此时光标变为“十”形,在基本框架内随意划取一矩形区域,即可以添加串口控件,不需要修改此控件的大小及位置,因为程编译运行后此控件是看不到的,步骤结果如下图:此控件(标志)是下面步骤添加进来的串口控件 基本框架

3、继续往基本框架内添加用于编辑发送数据的输入编辑框及输出编辑框,同理选择控 件列表框内的“编辑框控件”,以相同的操作即可添加两个编辑窗口及一个按纽控件如 下图所示: 选择其中任 意一个作为 输入编辑框 及输出编辑 框 这两个窗口需要修改大小及位置,因为程序运行后将会显示而串口通信控件则不显示, 上图是运行后的效果。 4、对以上四个控件编程步骤如下: a、右击串口通信控件建立类向导Member variables Control IDS中选 择IDC_MSCOMM1 add variable…Member variable name中输入控件变量名 m_ctrlComm(变量名可以随意选取,但程序中应与所取变量名一致)OK 确 定

51串口通信协议(新型篇)

51串口通信协议(新型篇) C51编程:这是网友牛毅编的一个C51串口通讯程序! //PC读MCU指令结构:(中断方式,ASCII码表示) //帧:帧头标志|帧类型|器件地址|启始地址|长度n|效验和|帧尾标志 //值: 'n' 'y'| 'r' | 0x01 | x | x | x |0x13 0x10 //字节数: 2 | 1 | 1 | 1 | 1 | 1 | 2 //求和: ///////////////////////////////////////////////////////////////////// //公司名称:*** //模块名:protocol.c //创建者:牛毅 //修改者: //功能描述:中断方式:本程序为mcu的串口通讯提供(贞结构)函数接口,包括具体协议部分 //其他说明:只提供对A T89c51具体硬件的可靠访问接口 //版本:1.0 //信息:QQ 75011221 ///////////////////////////////////////////////////////////////////// #include #include //预定义 //帧 #define F_ST1 0x6e //帧头标志n #define F_ST2 0x79 //帧头标志y #define F_R 0x72 //帧类型读r #define F_W 0x77 //帧类型写w #define F_D 0x64 //帧类型数据帧d #define F_B 0x62 //帧类型写回应帧b #define F_C 0x63 //帧类型重发命令帧c #define F_Q 0x71 //帧类型放弃帧q #define F_ADDR 0x31 //器件地址0-9 #define F_END 0x7a //帧尾标志z #define F_SPACE 0x30 //空标志0 #define F_ERR1 0x31 //错误标志1,flagerr 1 #define F_ERR2 0x32 //错误标志2 2 //常数 #define S_MAXBUF 16 //接收/发送数据的最大缓存量 #define FIELD_MAXBUF 48 //最小场缓存,可以大于48字节,因为协议是以20字节为

VCMSComm串口发送与接收上位机制做总结

VC++MSComm串口发送与接收上位机本设计用VC编写的一个简单的上位机软件,实现功能为:简单的串口数据发送与接收。 具体步骤如下: 一.建立应用程序工程“串口通信_韩季方01” 1.打开VC++6.0—》建立对话框MFC应用程序:串口通信_韩季方01—》 添加基本控件如图1.0。 图1.0 2.添加MSComm控件:Add To Project—》Components and Controls…打开如图1.1,双击“Registered ActiveX Contronls”项—》出现如图1.2—》选择“Microsoft Communications Control,version 6.0”控件—》点击“Insert”—》提示“…”确认即可—》弹出图1.3—》点击“OK”—》再点击“Close”。 下一步,将对话框资源控件中的电话状控件托到对话框中即可,如图1.4。

图1.1 图1.2

图1.3 图1.4 3.编辑控件及其属性设置:如表1.0

4.添加变量及其类型方法如图1.5 图1.5 二.初始化串口:设置MSComm控件属性 打开Class Wizard—》Member Variables—》选IDC_MSCOMM1—》点击“Add Varialbe…”—》添加变量m_ctrlComm。如图1.5。 之后,在工作空间打开文件如图2.0—》在函数OnInitDialog中添加代码如图2.1。

图2.0

图2.1 三.添加串口事件消息处理函数OnComm() 打开Class Wizard—》Member Maps—》Class Name中选择C_01Dlg—》在Object Ids中选择IDC_MSCOMM1—》在Message中选中OnComm—》单击“Add Function”按钮—》将函数名改为OnComm(好记而已)—》单击OK,完成后如图3.0 同理在函数OnComm()中添加代码如图3.1

串口通信测试方法

串口通信测试方法 1 关于串口通信的一些知识: RS-232C是目前最常用的串行接口标准,用来实现计算机和计算机之间、计算机和外设之间的数据通信。 在PC机系统中都装有异步通信适配器,利用它可以实现异步串行通信。而且MCS-51单片机本身具有一个全双工的串行接口,因此只要配以电平转换的驱动电路、隔离电路就可以组成一个简单可行的通信接口。 由于MCS-51单片机的输入和输出电平为TTL电平,而PC机配置的是RS-232C 标准串行接口,二者电气规范不一致,因此要完成PC机与单片机的数据通信,必须进行电平转换。 注明:3)RS-232C上传送的数字量采用负逻辑,且与地对称 逻辑1:-3 ~-15V 逻辑0:+3~+15V 所以与单片机连接时常常需要加入电平转换芯片: 2 实现串口通信的三个步骤: (1)硬件连接 51单片机有一个全双工的串行通讯口,所以单片机和计算机之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如计算机的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换。我们采用了三线制连接串口,也就是说和计算机的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接。 使用MAX232串口通信电路图(9孔串口接头) (2)串行通信程序设计 ①通信协议的使用 通信协议是通信设备在通信前的约定。单片机、计算机有了协议这种

约定,通信双方才能明白对方的意图,以进行下一步动作。假定我们需要在PC 机与单片机之间进行通信,在设计过程中,有如下约定:

如何用VC++实现串口通信

用VC 6.0实现串行通信的三种方法 中国科学院王颖 ---- 摘要:本文介绍了在Windows平台下串行通信的实现机制,讨论了根据不同的条件用Visual C++ 设计串行通信程序的三种方法,并结合实际,实现对温度数据的接收监控。 ---- 在实验室和工业应用中,串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛。依据不同的条件实现对串口的灵活编程控制是我们所需要的。 ---- 在光学镜片镀膜工艺中,用单片机进行多路温度数据采集控制,采集结果以串行方式进入主机,每隔10S向主机发送一次采样数据,主机向单片机发送相关的控制命令,实现串行数据接收,处理,记录,显示,实时绘制曲线。串行通信程序开发环境为VC++ 6.0。 ---- Windows下串行通信 ---- 与以往DOS下串行通信程序不同的是,Windows不提倡应用程序直接控制硬件,而是通过Windows 操作系统提供的设备驱动程序来进行数据传递。串行口在Win 32中是作为文件来进行处理的,而不是直接对端口进行操作,对于串行通信,Win 32 提供了相应的文件I/O函数与通信函数,通过了解这些函数的使用,可以编制出符合不同需要的通信程序。与通信设备相关的结构有COMMCONFIG ,COMMPROP,COMMTIMEOUTS,COMSTAT,DCB,MODEMDEVCAPS,MODEMSETTINGS共7个,与通信有关的Windows API函数共有26个,详细说明可参考MSDN帮助文件。以下将结合实例,给出实现串行通信的三种方法。 ---- 实现串行通信的三种方法 ---- 方法一:使用VC++提供的串行通信控件MSComm 首先,在对话框中创建通信控件,若Control 工具栏中缺少该控件,可通过菜单Project --> Add to Project --> Components and Control插入即可,再将该控件从工具箱中拉到对话框中。此时,你只需要关心控件提供的对Windows 通讯驱动程序的API 函数的接口。换句话说,只需要设置和监视MSComm控件的属性和事件。 ---- 在ClassWizard中为新创建的通信控件定义成员对象(CMSComm m_Serial),通过该对象便可以对串口属性进行设置,MSComm 控件共有27个属性,这里只介绍其中几个常用属性: ---- CommPort 设置并返回通讯端口号,缺省为COM1。 ---- Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 ---- PortOpen 设置并返回通讯端口的状态,也可以打开和关闭端口。 ---- Input 从接收缓冲区返回和删除字符。 ---- Output 向发送缓冲区写一个字符串。 ---- InputLen 设置每次Input读入的字符个数,缺省值为0,表明读取接收缓冲区中的全部内

VC串口通信实例 MSComm

VC串口通信实例 MSComm 计算机与外界的信息交换称为通信。基本的通信方式有并行通信和串行通信两种。串行通信是指一条信息额各位数据被逐位按顺序传送的通信方式。随着计算机技术的发展和推广,利用串口进行数据通讯在通讯领域中占有着重要的地位。串行通信的特点是:数据位传送,按位顺序进行,最少只需要一根传输线即可完成,成本低但传送速度慢。串行通信的距离可以从几米到几千米。利用串口进行数据通讯在通讯领域中占有着重要的地位,串口通讯在通讯软件中有着十分广泛的应用。如电话、传真、视频和各种控制等。串口通讯目前流行的方法大概有三种:一是利用Microsoft提供的CMSCOMM控件进行通讯,不过现在很多程序员都觉应该放弃这种方式。二是利用WINAPI函数进行编程,这种编程的难度高,要求掌握很多的API 函数。三是利用现在网络上面提供的一些串口通讯控件进行编写。这三种方法都没有同Windows服务联系起来。 串行接口输入输出过程描述 串行接口包括4个主要寄存器,即控制寄存器、状态寄存器、数据输入寄存器及数据输出寄存器。控制寄存器用来接收CPU送给此接口的各种控制信息,而控制信息决定接口的工作方式。状态寄存器的各位叫状态位,每一个状态位都可以用来指示传输过程中的某一种错误或当前传输状态。数据输入寄存器总是和串行输入/并行输出移位寄存器配对使用的。在输入过程中,数据一位一位从外部设备进入接口的寄存器,当接收完一个数据后,数据就从移位寄存器送到输入寄存器,再等待CPU来取走。输出的情况与输入过程类似,在输出过程中,数据输出寄存器与并行输入/串行输出移位寄存器配对使用。当CPU往数据输出寄存器中输出一个数据后,数据便传输到移位寄存器,然后一位一位地通过输出线送到外设。串行通信数据的收发方式分为异步通信方式与同步通信方式。

51单片机与蓝牙串口通信程序

#include #include #include #include "LCD1602.h" #include "matrix_key.h" #define uint unsigned int #define uchar unsigned char #define Nop() _nop_() sbit P10 = P1^0; /*定义独立对地按键端口*/ sbit P11 = P1^1; /*定义独立对地按键端口*/ sbit P12 = P1^2; /*定义独立对地按键端口*/ sbit P13 = P1^3; /*定义独立对地按键端口*/ //shift键 bit shift_flag; bit call_flag ; bit CallIn_flag=0; bit reci_flag; bit reci_flag1; sbit sled_en_port = P3^6; /*定义数码管数据锁存器控制端口*/ sbit led_en_port = P2^5; /*定义发光二极管数据锁存器控制端口*/ sbit ds1302_en_port = P2^2; /*定义时钟的选片脚*/ uchar CallIn_Num[15];//={"00000000000"}; uchar CallOut_Num[15]={" "}; uchar m=0; //拨号指针 uchar temp='?'; uchar code clr[16]={" "}; uchar code lcd_table[16] = {"Ky: Cm: Re: "}; //uchar send_buff[15]; uchar reci_buff[15]={" "}; uchar z; //接收缓冲区指针 uchar time;//定时器中断次数 uchar code mun_to_char[]={"0123456789ABCDEF"}; /*1MS为单位的延时程序*/ void init(); void send(uchar cc); void send_f(uchar ccc); void interrupt_pro(); void key_pro(); void call_out();

MFC串口通信编程详解解析

MFC串口通信编程介绍 主要介绍了用CreateFile(函数和WriteFile(函数读写串口的实例,以及设置串口属性的实例. 在工业控制中,工控机(一般都基于Windows平台经常需要与智能仪表通过串口 进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络上的各智能控制单元子节点.每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答. 在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活.其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活.下面只介绍API串口通信部分. 串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式.同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中, 虽然不会阻塞主线程,但是仍然会阻塞监听线程;而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞. 无论哪种操作方式,一般都通过四个步骤来完成: (1打开串口 (2配置串口 (3读写串口 (4关闭串口

一打开串口 Win32系统把文件的概念进行了扩展.无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的.该函数的原型为: HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile; ?lpFileName:将要打开的串口逻辑名,如“COM1”; ?dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列; ?dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0; ?lpSecurityAttributes:引用安全性属性结构,缺省值为NULL; ?dwCreationDistribution:创建标志,对串口操作该参数必须置为 OPEN_EXISTING; ?dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操 作;

VC++串口通信编程

在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。串口通信方便易行,应用广泛。 一般情况下,工控机和各智能仪表通过RS485总线进行通信。RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络上的各智能控制单元子节点。每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答。 在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX 控件,这种方法程序简单,但欠灵活。其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。本文我们只介绍API串口通信部分。 串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。 无论那种操作方式,一般都通过四个步骤来完成: (1)打开串口 (2)配置串口 (3)读写串口 (4)关闭串口 (1)打开串口 Win32系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。该函数的原型为: HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); ?lpFileName:将要打开的串口逻辑名,如“COM1”; ?dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列; ?dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0; ?lpSecurityAttributes:引用安全性属性结构,缺省值为NULL; ?dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING; ?dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同 步I/O操作; ?hTemplateFile:对串口而言该参数必须置为NULL;

51单片机串口通信

一、串口通信原理 串口通讯对单片机而言意义重大,不但可以实现将单片机的数据传输到计算机端,而且也能实现计算机对单片机的控制。由于其所需电缆线少,接线简单,所以在较远距离传输中,得到了广泛的运用。串口通信的工作原理请同学们参看教科书。 以下对串口通信中一些需要同学们注意的地方作一点说明: 1、波特率选择 波特率(Boud Rate)就是在串口通信中每秒能够发送的位数(bits/second)。MSC-51串行端口在四种工作模式下有不同的波特率计算方法。其中,模式0和模式2波特率计算很简单,请同学们参看教科书;模式1和模式3的波特率选择相同,故在此仅以工作模式1为例来说明串口通信波特率的选择。 在串行端口工作于模式1,其波特率将由计时/计数器1来产生,通常设置定时器工作于模式2(自动再加模式)。在此模式下波特率计算公式为:波特率=(1+SMOD)*晶振频率/(384*(256-TH1)) 其中,SMOD——寄存器PCON的第7位,称为波特率倍增位; TH1——定时器的重载值。 在选择波特率的时候需要考虑两点:首先,系统需要的通信速率。这要根据系统的运作特点,确定通信的频率范围。然后考虑通信时钟误差。使用同一晶振频率在选择不同的通信速率时通信时钟误差会有很大差别。为了通信的稳定,我们应该尽量选择时钟误差最小的频率进行通信。 下面举例说明波特率选择过程:假设系统要求的通信频率在20000bit/s以下,晶振频率为12MHz,设置SMOD=1(即波特率倍增)。则TH1=256-62500/波特率 根据波特率取值表,我们知道可以选取的波特率有:1200,2400,4800,9600,19200。列计数器重载值,通信误差如下表: 因此,在通信中,最好选用波特率为1200,2400,4800中的一个。 2、通信协议的使用 通信协议是通信设备在通信前的约定。单片机、计算机有了协议这种约定,通信双方才能明白对方的意图,以进行下一步动作。假定我们需要在PC机与单片机之间进行通信,在双方程式设计过程中,有如下约定:0xA1:单片机读取P0端口数据,并将读取数据返回PC机;0xA2:单片机从PC机接收一段控制数据;0xA3:单片机操作成功信息。 在系统工作过程中,单片机接收到PC机数据信息后,便查找协议,完成相应的操作。当单片机接收到0xA1时,读取P0端口数据,并将读取数据返回PC机;当单片机接收到0xA2时,单片机等待从PC机接收一段控制数据;当PC机接收到0xA3时,就表明单片机操作已经成功。 3、硬件连接 51单片机有一个全双工的串行通讯口,所以单片机和计算机之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如计算机的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。我们采用了三线制连接串口,也就是说和计算机的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接。

VC串口编程API详解

V C串口编程A P I详解集团企业公司编码:(LL3698-KKI1269-TM2483-LUI12689-ITT289-

V C++串口编程主要A P I详解该文档是本人在刚刚接触到VC++下的串口编程时,总结归纳的一些主要的API函数,可以帮助初学者更好的理解串口编程的方法。 1.打开串口 HANDLECreateFile(LPCTSTRlpFileName, DWORDdwDesiredAccess, DWORDdwShareMode, LPSECURITY_ATTRIBUTESlpSecurityAttributes, DWORDdwCreationDistribution, DWORDdwFlagsAndAttributes, HANDLEhTemplateFile); 参数: lpFileName:将要打开的串口逻辑名,如“COM1”;dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列; dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;lpSecurityAttributes:引用安全性属性结构,缺省值为NULL;

dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING; dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作,本工程采用异步方式; hTemplateFile:对串口而言该参数必须置为NULL; 2.获取串口设备控制块DCB BOOLGetCommState( HANDLEhFile, //标识通讯端口的句柄,由CreateFile()函数返回的句柄 LPDCBlpDCB //指向一个设备控制块(DCB结构)的指针 ); 3.设置串口设备控制块DCB BOOLSetCommState( HANDLEhFile,//标识通讯端口的句柄,由CreateFile()函数返回的句柄LPDCBlpDCB//指向一个设备控制块(DCB结构)的指针 ); 4.设置串口输入输出缓冲区大小 BOOLSetupComm( HANDLEhFile, //通信设备的句柄DWORDdwInQueue, //输入缓冲区的大小(字节数)DWORDdwOutQueue //输出缓冲区的大小(字节数)

单片机与pc串口通信程序及电路图

单片机与pc串口通信程序及电路图 单片机与pc串口通信程序及电路图 #include #define BUFFERLEGTH 10 //----------------------------------------------------------------- void UART_init(); //串口初始化函数 void COM_send(void); //串口发送函数 char str[20]; char j; //------------------------------------------------------------------- void main(void) { unsigned char i; UART_init(); j=0; //初始化串口 for(i = 0;i }; while(1); } //------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- // 函数名称:UART_init()串口初始化函数 // 函数功能:在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s // 串口接收中断允许,发送中断禁止 //-------------------------------------------------------------------------------------------------- void UART_init() { //初始化串行口和波特率发生器

相关文档
相关文档 最新文档