异步打开串口的方法
异步传输是一种典型的基于字节的输入输出,指数据按每次一个字节进行传输,其传输速度低。同步传输是把数据字节组合起来一起发送,这种组合称之为帧,其传输速度比异步传输快,同步串口的传送速率高,异步串口实现简单,这是异步串口与同步串口间最主要的区别。
一,异步非阻塞串口通讯的优点
读写串行口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。
例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。"重叠"一词的含义就在于此。
二,异步非阻塞串口通讯的基本原理
首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;
其次,为了保护系统对串口的初始设置,调用GetCommTimeouts()得到串口的原始超时设置;
然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;
再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。
三,异步非阻塞串口通讯的基础知识
VC串口通信技术网下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数
CreateFile()
功能:打开串口设备
函数原型
1HANDLE CreateFile(
2LPCTSTR lpFileName, // 串口名称字符串;如:"COM1" 或"COM2"
3DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE,
4DWORD dwShareMode, // 共享模式;"必须"为0, 即不能共享
5LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULL
6DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"
为OPEN_EXISTING
7DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/O
8HANDLE hTemplateFile // 临时文件的句柄,通常为NULL
9);
函数说明:
如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。例子:
10Handle m_hComm = CreateFile(com1,GENERIC_READ||GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLA G_OVERLAPPED,0);
CloseHandle();
函数原型:
11BOOL CloseHandle(
12HANDLE hObject // handle to object to close
13)
使用比较简单,其中参数hObject为需要关闭的串口句柄。
GetCommState()
功能:获得串口状态
函数原型:
14BOOL GetCommState(
15HANDLE hFile, // handle of communications device
16LPDCB lpDCB // address of device-control block structure
17);
SetCommState()
功能:设置串口状态
18BOOL SetCommState(
19HANDLE hFile, // handle of communications device
20LPDCB lpDCB // address of device-control block structure
21);
函数说明:
在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。这需要通过一个DCB结构来进行。DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置置串行口的属性时,都要用DCB结构来作为缓冲区。
调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。一般在用CreateFile打开串行口后,可以调用GetCommState函数来获取串行口的初始配置。要修改串行口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB结构来设置串行口。举例:
22DCB dcb;
23memset(&dec,0,dizeof(dcb));
24if(!GetCommState(HComm,&dcb))//获取当前DCB配置
25return FALSE;
26dcb.BaudRate = CBR_9600;//修改数据传输率
27............
28if(SetCommState(hComm,&dcb))//设置新参数
29...... //错误处理
BuildCommDCB()
功能:初始化DCB结构
函数原型:
30BOOL BuildCommDCB(
31LPCTSTR lpDef, // pointer to device-control string
32LPDCB lpDCB // pointer to device-control block
33);
示例:
34DCB dcb;
35memset(&dcb,0,sizeof(dcb));
36dcb.DCBlength = sizeof(dcb);
37if(!BuildCommDCb("9600,n,8,1",&dcb))//"baud=9600 parity=N data=8 stop=1"
38{
39 ...... //参数修改错误
40return FALSE;
41}
42else
43{
44 ...... //己准备就绪
45}
SetupComm()
功能:设置I/O缓冲区的大小
函数原型:
46BOOL SetupComm(
47HANDLE hFile, // handle to communications device
48DWORD dwInQueue, // size of input buffer
49DWORD dwOutQueue // size of output buffer
50);
说明:
除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。Windows用I/O缓冲区来暂存串行口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。
先介绍一个结构:COMMTIMEOUTS
51typedef struct _COMMTIMEOUTS {
52DWORD ReadIntervalTimeout; // 读间隔超时
53DWORD ReadTotalTimeoutMultiplier; // 读时间系数
54DWORD ReadTotalTimeoutConstant; // 读时间常量
55DWORD WriteTotalTimeoutMultiplier; // 写时间系数
56DWORD WriteTotalTimeoutConstant; // 写时间常量
57} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
再介绍两个函数
GetCommTimeouts
功能:读取TimeOut的值
函数原型:
58BOOL GetCommTimeouts(
59HANDLE hFile, // handle of communications device
60LPCOMMTIMEOUTS lpCommTimeouts // address of comm.
time-outs structure
61);
SetCommTimeouts
功能:设置TimeOUt的值
函数原型:
62BOOL SetCommTimeouts(
63HANDLE hFile, // handle of communications device
64LPCOMMTIMEOUTS lpCommTimeouts // address of communications time-out structure
65);
这里顺便介绍一下TimeOut机制的两个性质:
超时函数
说明:
在用ReadFile和WriteFile读写串行口时,需要考虑超时问题。如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFile或WriteFile的操作就会结束。要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。
有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:COMMTIMEOUTS结构的成员都以毫秒为单位。总超时的计算公式是:
总超时=时间系数×要求读/写的字符数+ 时间常量
例如,如果要读入10个字符,那么读操作的总超时的计算公式为:
读总超时=ReadTotalTimeoutMultiplier×10 + ReadTotalTimeoutConstant
可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。
如果所有写超时参数均为0,那么就不使用写超时。如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0,则不使用读总超时。如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。
在用重叠方式读写串行口时,虽然ReadFile和WriteFile在完成操作以前就可能返回,但超时仍然是起作用的。在这种情况下,超时规定的是操作的完成时间,而不是ReadFile和WriteFile的返回时间。示例:
66COMMTIMEOUTS timeOver;
67memset(&&timeOver.0.sizeof(timeOver));
68DWORDtimeMultiplier,timeConstant;
69timeOver.ReadTotalTimeoutMultiplier=timeMultiplier;
70timeOver.ReadTotalTimeoutConstant=timeConstant;
71SetCommTimeouts(hComport,&&timeOver);
ReadFile()
功能:读取数据
函数原型:
72BOOL ReadFile(
73HANDLE hFile, // 串口名称字符串(文件句柄)
74LPVOID lpBuffer, // 读缓冲区
75DWORD nNumberOfBytesToRead, // 要求读入的字节数
76LPDWORD lpNumberOfBytesRead, // 实际读入的字节数
77LPOVERLAPPED lpOverlapped // 指向一个OVERLAPPED结构
78); //若返回TRUE则表明操作成功
示例:
79char *pReciveBuf;
80DWORD nWantRead = 100,
81nReadRead;
82LPOVERLAPPED m_OverlappedRead;
83BOOL bReadStatus = ReadFile( m_hComm, preciveBuf,nWantRead, &&nReadRead, &&m_OverlappedRead );
WriteFile()
功能:来将资料写入Serial port.
函数原型:
84BOOL WriteFile(
85HANDLE hFile, // handle to file to write to
86LPCVOID lpBuffer, // pointer to data to write to file
87DWORD nNumberOfBytesToWrite, // number of bytes to write
88LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
89LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
90);
说明:
ReadFile函数只要在串行口输入缓冲区中读入指定数量的字符,就算完成操作。
而WriteFile函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串行口送出去后才算完成操作。
当ReadFile 和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING。
如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还为完成,线程可以等待操作完成。有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED 结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult。
另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent 事件。GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果。
如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。因此,在超时发生后,WaitForSingleObject和GetOverlappedResult都会结束等待。WaitForSingleObject的dwMilliseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去。ClearCommError()
功能:从字面上的意思看来, 它是用来清除错误情况用的, 但是实际上它还可以拿来取得目前通讯设备的一些信息.
函数原型
91BOOL ClearCommError(
92HANDLE hFile, // handle to communications device
93LPDWORD lpErrors, // pointer to variable to receive error codes 94LPCOMSTAT lpStat // pointer to buffer for communications status
95);
说明:
在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。
PurgeComm()
功能:终止目前正在进行的读或写的动作
函数原型:
96BOOL PurgeComm(
97HANDLE hFile, // handle of communications resource
98);
参数说明:
HANDLE hFile,//串口名称字符串
dwFlags 共有四种flags:
PURGE_TXABORT: 终止目前正在进行的(背景)写入动作
PURGE_RXABORT: 终正目前正在进行的(背景)读取动作
PURGE_TXCLEAR: flush 写入的buffer
PURGE_TXCLEAR: flush 读取的buffer
调用PurgeComm函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。GetCommMask()
功能:得到设置的通信事件的掩码
函数原型:
99BOOL GetCommMask(
100HANDLE hFile, // handle of communications device
101LPDWORD lpEvtMask // address of variable to get event mask 102);
SetCommMask()
功能:设置想要得到的通信事件的掩码
函数原型:
103BOOL SetCommMask(
104HANDLE hFile, // handle of communications device
105DWORD dwEvtMask // mask that identifies enabled events
106);
说明:
可设置的通信事件标志(即SetCommMask()函数所设置的掩码)
可以有EV_BREAK、EV_CTS、EV_DSR、EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。
注:若对端口数据的响应时间要求较严格,可采用事件驱动I/O读写,Windows定义了9种串口通信事件,较常用的有:
EV_RXCHAR: 接收到一个字节,并放入输入缓冲区。
EV_TXEMPTY: 输出缓冲区中的最后一个字符发送出去。
EV_RXFLAG: 接收到事件字符(DCB结构中EvtChar成员),放入输入缓冲区。
下面是MSDN上的解释:
EV_BREAK A break was detected on input.
EV_CTS The CTS (clear-to-send) signal changed state.
EV_DSR The DSR (data-set-ready) signal changed state.
EV_ERR A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING A ring indicator was detected.
EV_RLSD The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR A character was received and placed in the input buffer.
EV_RXFLAG The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY The last character in the output buffer was sent.
WaitCommEvent()
功能:等待设定的通讯事件的发生
函数原型:
107BOOL WaitCommEvent(
108HANDLE hFile, // handle of communications device
109LPDWORD lpEvtMask, // address of variable for event that occurred
110LPOVERLAPPED lpOverlapped, // address of overlapped structure 111);
说明:
WaitCommEvent()会一直block(阻塞)到你所设定的通讯事件发生为止.
所以当WaitCommEvent()返回时, 你可以由lpEvtMask 取得究竟是那一事件发生, 再来决定要如何处理.
WaitForSingleObject()
功能:保证线程同步的等待函数
函数原型:
112DWORD WaitForSingleObject(HANDLE hHandle,//同步对象的句柄
113DWORD dwMilliseconds//以毫秒为单位的超时间隔,如果设为INFINITE,则超时间隔是无限的
114);
说明:
返回值含义
WAIT_FAILED 函数失败
WAIT_OBJECT_0 指定的同步对象处于有信号的状态
WAIT_ABANDONED 拥有一个mutex的线程已经中断了,但未释放该MUTEX
WAIT_TIMEOUT 超时返回,并且同步对象无信号
WaitForMultipleObjects()
功能:可以同时监测多个同步对象
函数原型:
115DWORD WaitForMultipleObjects(DWORD nCount,//句柄数组中句柄的数目
116CONST HANDLE *lpHandles,//代表一个句柄数组
117BOOL bWaitAll, //说明了等待类型(),如果为TRUE,那么函数在所有对象都有信号后才返回,
118//如果为FALSE,则只要有一个对象变成有信号的,函数就返
回
119DWORD dwMilliseconds//以毫秒为单位的超时间隔
120);
说明:
返回值含义
WAIT_OBJECT_0到WAIT_ OBJECT_0+nCount-1
若bWaitAll为TRUE,则返回值表明所有对象都是有信号的。如果bWaitAll为FALSE,则返回值减去WAIT_OBJECT_0就是数组中有信号对象的最小索引。
WAIT_ABANDONED_0 到WAIT_ ABANDONED_ 0+nCount-1
若bWaitAll为TRUE,则返回值表明所有对象都有信号,但有一个mutex被放弃了。若bWaitAll为FALSE,则返回值减去WAIT_ABANDONED_0就是被放弃mutex在对象数组中的索引。
WAIT_TIMEOUT 超时返回
实现重叠模型的步骤
下面就结合俺写的一个Console程序简单示例进行说明:
第一步、打开串口
121HANDLE m_hCom = CreateFile("com1",GENERIC_READ | GENERIC_WRITE, 0, NULL, 122OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
123if (m_hCom == INVALID_HANDLE_VALUE)
124{
125cout<<"CreateFile fail!"<
126return -1;
127}
128cout<<"CreateFile OK!"<< p="" />
第二步、设置缓冲区大小
129if(!SetupComm(m_hCom,2048,2048))
130{
131cout<<"SetupComm fail! Close Comm!"<
132CloseHandle(m_hCom);
133return -1;
134}
135cout<<"SetupComm OK!"<< p="" />
第三步、设置超时
136COMMTIMEOUTS TimeOuts;
137memset(&TimeOuts,0,sizeof(TimeOuts));
138TimeOuts.ReadIntervalTimeout = MAXDWORD;
139TimeOuts.ReadTotalTimeoutConstant = 0;
140TimeOuts.ReadTotalTimeoutMultiplier = 0;
141TimeOuts.WriteT otalTimeoutConstant = 2000;
142TimeOuts.WriteT otalTimeoutMultiplier = 50;
143SetCommTimeouts(m_hCom,&TimeOuts);
第四步、设置串口参数
144DCB dcb;
145if (!GetCommState(m_hCom,&dcb))
146{
147cout<<"GetCommState fail! Comm close"<
148CloseHandle(m_hCom);
149return -1;
150}
151cout<<"GetCommState OK!"<
152
153dcb.DCBlength = sizeof(dcb);
154if (!BuildCommDCB("9600,n,8,1",&dcb))//填充DCB的数据传输率、奇偶校验类型、数据位、停止位
155{
156//参数修改错误,进行错误处理
157cout<<"BuileCOmmDCB fail,Comm close!"<
158CloseHandle(m_hCom);
159return -1;
160}
161if(SetCommState(m_hCom,&dcb))
162{
163cout<<"SetCommState OK!"<
164}
第五步、建立并初始化重叠结构
165OVERLAPPED wrOverlapped;
166ZeroMemory(&wrOverlapped,sizeof(wrOverlapped));
167if (wrOverlapped.hEvent != NULL)
168{
169ResetEvent(wrOverlapped.hEvent);
170wrOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
171}
第六步、封装数据(应按照自己的格式封装需要发送的数据)
172typedef enum
173{
174HEAT_BEAT, //心跳数据
175NET_STATE,//网络状态数据
176PACKET //正常数据包
177//支持可扩展性......
178}ProtocolType;
179
180typedef enum
181{
182Train_No,//无线车次信息
183Attemper_Command,//调度命令信息
184Revert_Command,//调度命令回执信息
185Replay_Command,//重发的调度命令信息
186KGL_SING //开关量数据
187//支持可扩展性......
188}PacketDataType;
189
190//串口数据结构
191typedef struct SerialNetProto
192{
193unsigned long PacketSize; //包总长度,不包括本身字段
194ProtocolType NetState; //协议包类型
195PacketDataType DataType; //数据类型
196unsigned long SourcedAddr; //数据包源地址
197unsigned long DestinationAddr; //数据包目的地址
198unsigned long DataLength; //包的数据段长度
199unsigned long Offset; // 数据在整个包中的偏移地址
200}PacketHead;
201
202int DataLen = 100;
203char *pBuf = new char[DataLen];
204strcpy(pBuf,"Hello World!");
205DataLen = strlen(pBuf);
206PacketHead Myhead;
207Myhead.DestinationAddr = 11;
208Myhead.SourcedAddr = 10;
209Myhead.DataType = Attemper_Command;
210Myhead.DataLength = DataLen;
https://www.360docs.net/doc/c16169240.html,State = PACKET;
212Myhead.PacketSize = sizeof(PacketHead) - sizeof(unsigned long);
213Myhead.Offset = sizeof(Myhead.DestinationAddr) +sizeof(Myhead.SourcedAddr) + sizeof(Myhead.DataType) +sizeof(Myhead.DataLength) + sizeof(https://www.360docs.net/doc/c16169240.html,State) + sizeof(Myhead.PacketSize);
214
215char *pSendBuffer = new char[sizeof(Myhead)+DataLen+ 4];//发送的数据
216memcpy(pSendBuffer,"##",2);//包头标志
217memcpy(pSendBuffer+2,(char*)&Myhead,sizeof(Myhead));//包头
218memcpy(pSendBuffer+2+sizeof(Myhead),pBuf,DataLen);//数据
219memcpy(pSendBuffer+2+sizeof(Myhead)+DataLen,"@@",2);//包尾标志
220
第七步、发送数据
221DWORD dwError;
222//DWORD dwWantSend = 100;
223DWORD dwRealSend = 0;
224char* pReadBuf = NULL;
225if (ClearCommError(m_hCom,&dwError,NULL))
226{
227PurgeComm(m_hCom,PURGE_TXABORT | PURGE_TXCLEAR);
228cout<<"PurgeComm OK!"<
229}
230if (!WriteFile(m_hCom,pSendBuffer,sizeof(Myhead)+DataLen+ 4,&dwRealSend,&wrOverlapped))
231{
232if (GetLastError() == ERROR_IO_PENDING)
233{
234while
(!GetOverlappedResult(m_hCom,&wrOverlapped,&dwRealSend,FALSE))
235{
236if (GetLastError() == ERROR_IO_INCOMPLETE)
237{
238//cout<<"写未完成,继续!"<
239continue;
240}
241else
242{
243cout<<"发生错误,尝试恢复!"<
244ClearCommError(m_hCom,&dwError,NULL);
245break;
246}
247}
248}
249}
第八步、数据接收
250DWORD dwError;
251DWORD dwWantRead = 100;
252DWORD dwRealRead = 0;
253char* pReadBuf = new char[100];
254if (ClearCommError(m_hCom,&dwError,NULL))
255{
256PurgeComm(m_hCom,PURGE_TXABORT | PURGE_TXCLEAR);
257cout<<"PurgeComm OK!"<
258}
259
260if(!ReadFile(m_hComm,pReadBuf,dwWantRead,&RealRead,&wrOverlapped))
261{
262if(dwError = GetLastError()==ERROR_IO_PENDING)
263{
While(GetOverlappedResult(m_hComm,&wrOverlapped,&dwRealRead,FALSE)) 265{
266//对接收到的数据进行数据解析,处理
267//【第九步】............
268cout<<"dwRealRead = "<<
269}
270}
271}
第九步、数据解析(数据解包处理)
272#define MAX_SERIAL_BUFFER 4096
273BOOL CanGetFullFrame(char* pReadBuf,int& dwRealRead)
274{
275static char Buf[MAX_SERIAL_BUFFER*2];//自定义一个数据缓冲区
276static unsigned long nFrameStart = 0;//数据祯的开始位置
277static unsigned long nFrameEnd = 0;//数据祯的结束位置
278static unsigned long nCurrectPos = 0;//指针当前位置
279char *pdest = NULL;
280
281if (pReadBuf && (dwRealRead!= 0))
282{
283memcpy(&Buf[nCurrectPos],pReadBuf,dwRealRead);
284nCurrectPos = nCurrectPos + dwRealRead;//更新当前位置
285}
286//查找数据祯的开始标志
287pdest = (char*)Find(Buf,"##",MAX_SERIAL_BUFFER*2,2);
288if (pdest)
289{
290nFrameStart = unsigned long(pdest - Buf);//找到数据祯的开始位置291}
292else//没有找到开始祯标志"##"
293{
294Buf[0] = Buf[nCurrectPos];//丢弃数据
295nFrameStart = 0;
296return FALSE;
297}
298
299//查找数据祯的结尾标志
300pdest = (char*)Find(Buf,"@@",MAX_SERIAL_BUFFER*2,2);
301if (pdest)
302{
303nFrameEnd = unsigned long (pdest - Buf+2);
304dwRealRead= nFrameEnd - nFrameStart;
305memcpy(pReadBuf,&Buf[nFrameStart],dwRealRead);
307nFrameStart = nFrameEnd;//指向下一帧的开始位置
308nCurrectPos = nCurrectPos - dwRealRead;//修正nCurrentPos值
309memcpy(Buf,&Buf[nFrameEnd],nCurrectPos);//向前移动数据
310return TRUE;
311}
312else
313{
314return FALSE;
315}
316}
317
318//一个在内存块中查找指定字符串的函数
319void* Find(const char *pSour,const char *pDest,int SourLen,int DestLen)
320{
321int i = 0, j = 0;
322while(i < SourLen && j < DestLen)
323{
324if(*(pSour + i) == *(pDest + j))
325{
326i++;
327j++;
328}
329else
330{
331i =i - j + 1;
332j = 0;
333}
334}
335if(j == DestLen)
336{
337return (void*)(pSour + (i - DestLen));
338}
339else
340{
341return NULL;
342}
343
344}
345
【第十步】重新投递Overlapped
.......略.........
以上VC异步串口编程代码未使用任何串口控件或串口类,在VC串口通信技术网的另一篇文章《用Windows API进行串口编程的一般步骤及相关函数讲解》也讲到了VC串口编程时的异步串口和同步串
口操作方法。
KEIL中如何用虚拟串口调试串口程序
KEIL中如何用虚拟串口调试串口程序 发表于2008/5/7 15:30:22 以前没接触过串口,一直都以为串口很复杂。最近在做一个新项目,用单片机控制GSM模块。单片机和GSM模块接口就是串口。调试完后觉得串口其实很简单。“不过如此”。这可能是工程师做完一个项目后的共同心态吧。下面详细介绍下如何用虚拟串口调试串口发送接收程序。 需要用到三个软件:KEIL,VSPD XP5(virtual serial ports driver xp5.1虚拟串口软件),串口调试助手。 1、首先在KEIL里编译写好的程序。 2、打开VSPD,界面如下图所示: 左边栏最上面的是电脑自带的物理串口。点右边的add pair,可以添加成对的串口。一对串口已经虚拟互联了,如果添加的是COM3、COM4,用COM3发送数据,COM4就可以接收数据,反过来也可以。 3、接下来的一步很关键。把KEIL和虚拟出来的串口绑定。现在把COM3和KEIL 绑定。在KEIL中进入DEBUG模式。在最下面的COMMAND命令行,输入MODE COM3 4800,0,8,1(设置串口3的波特率、奇偶校验位、数据位、停止位,打开COM3串口,注意设置的波特率和程序里设置的波特率应该一样)ASSIGN COM3
4、打开串口调试助手 可以看到虚拟出来的串口COM3、COM4,选择COM4,设置为波特率4800,无校验位、8位数据位,1位停止位(和COM3、程序里的设置一样)。打开COM4。 现在就可以开始调试串口发送接收程序了。可以通过KEIL发送数据,在串口调试助手中就可以显示出来。也可以通过串口调试助手发送数据,在KEIL中接收。这种方法的好处是不用硬件就可以调试。这是网上一篇文章介绍的方法,联系我实际的使用做了整理。有用的着的人就不用继续摸索了
C++ 串口API 异步操作
C++ 串口API 异步操作50 有谁能说下串口API异步操作的例子,最好有代码的。 如果是BCB的更好,谢谢啦,有些函数直接看的不是很懂。一,我要同时向20个端口发送数据,句柄怎样才能控制好二,如果采用异步操作,怎样操作才最好,需要代码支持谢谢啦初始化: //串行设备句柄; HANDLE hComDev=0; //串口打开标志; BOOL bOpen=FALSE; //线程同步事件句柄; HANDLE hEvent=0; DCB dcb; COMMTIMEOUTS timeouts; //设备已打开 if(bOpen) return FALSE; //打开COM1
if((hComDev=CreateFile(“COM1”,GENERIC?READ|GENERIC?WRITE,0,N ULL,OPEN?EXISTING,FILE?ATTRIBUTE?NORMAL,NULL))==INVALID?HAN DLE?VALUE) return FALSE; //设置超时控制 SetCommTimeouts(hComDev,&timeouts); //设置接收缓冲区和输出缓冲区的大小 SetupComm(hComDev,1024,512); //获取缺省的DCB结构的值 GetCommState(hComDev,&dcb); //设定波特率为9600 bps dcb.BaudRate=CBR?9600; //设定无奇偶校验 dcb.fParity=NOPARITY; //设定数据位为8 dcb.ByteSize=8;
//设定一个停止位 dcb.StopBits=ONESTOPBIT; //监视串口的错误和接收到字符两种事件SetCommMask(hComDev,EV?ERR|EV?RXCHAR); //设置串行设备控制参数 SetCommState(hComDev,&dcb); //设备已打开 bOpen=TRUE; //创建人工重设、未发信号的事件 hEvent=CreateEvent(NULL,FALSE,FALSE, “WatchEvent”);
串口调试助手使用方法
串口调试助手使用方法 你可以试试串口监控器,一个功能强大,非常易用的软件。 串口监控器是一个免费的多功能串口通讯监控软件,它能够多种方式显示,接收,分析通讯数据;能够以多种灵活方式发送数据;功能强大,操作简便,在串口通讯监控,设备通讯测试中,能够有效提高工作效率。 主要功能如下: 接收数据: 1. 以十六进制方式显示接收到的数据。 2. 以字符方式显示接收到的数据。 3. 数据帧自动识别,分行显示。 4. 接收数据自动换行设置。 5. 显示或隐藏数据帧的接收时间。 6. 自动清除,自动保存接收到的数据。 7. 接收数据个数计数。 发送数据: 1. 十六进制方式发送数据。 2. 字符串方式发送数据。 3. 发送“发报窗口”当前光标行的数据帧。 4. 循环发送“发报窗口”当前光标行的数据帧。 5. 循环发送“发报窗口”固定行的数据帧。 6. 循环依次发送“发报窗口”的多行数据帧。(设置起始行,行数) 7. 触发发送,接收到“发报窗口”某一行数据,触发发送“发报窗口”另一行数据。 8. 发送数据个数计数。 实用增强功能: 1. 强大易用的进制转换功能。 2. 智能识别当前光标处数据帧的行号,“字符”或“十六进制数”的个数。 3. 智能计算当前选择的“字符”或“十六进制数”的个数。 4. 强大的数据查找功能。 5. 定时保存,定时清除数据。 6. 根据自己的喜好,灵活变换操作界面。
应用场合: 1. 截取和分析设备之间通讯数据流。 2. 串行外围设备硬件开发。 3. 串行设备驱动程序开发。 4. 调试和测试设备和设备之间的串行通讯过程。 5. 记录和分析RS232/422/485通信过程。 6. 模拟某设备通讯过程,对另外设备进行通讯测试。
串口协议
串口协议 所谓通信协议是指通信双方的一种约定。约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。因此,也叫做通信控制规程,或称传输控制规程,它属于ISO'S OSI七层参考模型中的数据链路层。目前,采用的通信协议有两类:异步协议和同步协议。同步协议又有面向字符和面向比特以及面向字节计数三种。其中,面向字节计数的同步协议主要用于DEC公司的网络体系结构中。 一、物理接口标准 1.串行通信接口的基本任务 (1)实现数据格式化:因为来自CPU的是普通的并行数据,所以,接口电路应具有实现不同串行通信方式下的数据格式化的任务。在异步通信方式下,接口自动生成起止式的帧数据格式。在面向字符的同步方式下,接口要在待传送的数据块前加上同步字符。 (2)进行串-并转换:串行传送,数据是一位一位串行传送的,而计算机处理数据是并行数据。所以当数据由计算机送至数据发送器时,首先把串行数据转换为并行数才能送入计算机处理。因此串并转换是串行接口电路的重要任务。 (3)控制数据传输速率:串行通信接口电路应具有对数据传输速率——波特率进行选择和控制的能力。 (4)进行错误检测:在发送时接口电路对传送的字符数据自动生成奇偶校验位或其他校验码。在接收时,接口电路检查字符的奇偶校验或其他校验码,确定是否发生传送错误。(5)进行TTL 与EIA电平转换:CPU 和终端均采用TTL电平及正逻辑,它们与EIA采用的电平及负逻辑不兼容,需在接口电路中进行转换。 (6)提供EIA-RS-232C 接口标准所要求的信号线:远距离通信采用MODEM 时,需要9根信号线;近距离零MODEM 方式,只需要3 根信号线。这些信号线由接口电路提供,以便与MODEM 或终端进行联络与控制。 2、串行通信接口电路的组成 为了完成上述串行接口的任务,串行通信接口电路一般由可编程的串行接口芯片、波特率发生器、EIA 与TTL 电平转换器以及地址译码电路组成。其中,串行接口芯片,随着大规模继承电路技术的发展,通用的同步(USRT)和异步(UART)接口芯片种类越来越多,如下表所示。它们的基本功能是类似的,都能实现上面提出的串行通信接口基本任务的大部分工作,且都是可编程的。才用这些芯片作为串行通信接口电路的核心芯片,会使电路结构比较简单。
UART异步串口
MSP430程序库<二>UART异步串口 串行通信接口是处理器与其他设备进行数据通信最常用的方式之一。我的这个程序库是针对MSP430f14系列和MSP430f16系列的,我常用的单片机是这两款:msp430f149,ms p430f169。这两款单片机中均有两个增强型串行通信接口,都可以进行同步或是异步通信,甚至169的模块USART0还能进行进行I2C协议通信。在这里,我们只讨论异步串行通信。 硬件介绍: MSP单片机的USART模块可以配置成SPI(同步通信)模式或UART(异步通信)模式,这里只讨论UART方式。UART数据传输格式如下: 起始位,数据位由高到低7/8位,地址位0/1位,奇偶校验位奇偶或无,停止位1/2位。数据位位数、地址位、奇偶校验位、停止位均可由单片机内部寄存器控制;这两款单片机都有两个USART模块,有两套独立的寄存器组;以下寄存器命中出现x代表0或是1,0代表对应0模块的寄存器,1代表对应1模块的寄存器;其中,与串口模式设置相关的控制位都位于UxCTL寄存器,与接收相关的控制位都位于UxRCTL寄存器,与发送相关的控制位都位于UxTCTL寄存器;波特率设置用UxBR0、UxBR1、UxMCT L三个寄存器;接收与发送有独立的缓存UxRXBUF、UxTXBUF,并具有独立的移位寄存器和独立的中断;中断允许控制位位于IE1/2寄存器,中断标志位位于IFG1/2寄存器。 波特率设置:430的波特率设置用三个寄存器实现, UxBR0:波特率发生器分频系数低8位。 UxBR1:波特率发生器分频系数高8位。 UxMCTL:波特率发生器分频系数的小数部分实现。 设置波特率时,首先要选择合适的时钟源:USART模块可以设置的时钟源有UCLK引脚、ACLK、SMCLK;对于较低的波特率(9600以下),可选ACLK作为时钟源,这样,在LPM3(低功耗3)模式下,串口仍能正常发送接收数据;另外,由于串口接收过程有一个三取二判决逻辑,这至少需要三个时钟周期,因此分频系数必须大于3;波特率高于9600时,将不能使用ACLK作为时钟源,要调为频率较高的SMCLK作为时钟源;另外还可以外部输入UCLK时钟。分频系数计算公式如下:
第八章课后习题
第八章习题 1. 计算机的数据传送有两种方式,即方式和方式,其中具有成本低特点的是数据传送。 2. 异步串行数据通信的帧格式由位、位、位和位组成。 3. 异步串行数据通信有、和共3种数据通路形式。 4. 串行接口电路的主要功能是化和化,把帧中格式信息滤除而保留数据位的操作是化。 5. 专用寄存器“串行数据缓冲寄存器”,实际上是寄存器和 寄存器的总称。 6. MCS-51的串行口在工作方式0下,是把串行口作为同步移位寄存器来使用。这样,在串入并出移位寄存器的配合下,就可以把串行口作为使用,在并入串出移位寄存器的配合下,就可以把串行口作为使用。 7. 在串行通信中,收发双方对波特率的设定应该是的。 8. 使用定时器/计数器设置串行通信的波特率时,应把定时器/计数器1定为工作方式,即方式。 (三)选择题 1.调制解调器(MODEM)的功能是 (A)数字信号与模拟信号的转换 (B)电平信号与频率信号的转换 (C)串行数据与并行数据的转换 (D)基带传送方式与频带传送方式的转换 2.串行通信的传送速率单位是波特,而波特的单位是 (A)字符/秒(B)位/秒(C)帧/秒(D)帧/分 3.80C51有一个全双工的串行口,下列功能中该串行口不能完成的是 (A)网络通信(B)异步串行通信 (C)作为同步移位寄存器(D)位地址寄存器 4. 帧格式为1个起始位、8个数据位和1个停止位的异步串行通信方式是 (A)方式0 (B)方式1 (C)方式2 (D)方式3 5. 通过串行口发送或接收数据时,在程序中应使用 (A)MOV指令(B)MOVX指令(C)MOVC指令(D)SW AP指令 6. 以下所列特点中,不属于串行工作方式2的是 (A)11位帧格式(B)有第9数据位 (C)使用一种固定的波特率(D)使用两种固定的波特率 7. 以下有关第9数据位的说明中,错误的是 (A)第9数据位的功能可由用户定义 (B)发送数据的第9数据位内容在SCON寄存器的TB8位中预先准备好 (C)帧发送时使用指令把TB8位的状态送入发送SBUF中 (D)接收到的第9数据位送SCON寄存器的RB8中保存 8. 串行工作方式1的波特率是 (A)固定的,为时钟频率的1/12 (B)固定的,为时钟频率的1/32 (C)固定的,为时钟频率的1/64 (D)可变的,通过定时器/计数器l的溢出率设定
通信协议简介及区别(串行、并行、双工、RS232等)
基本的通讯方式有并行通讯和串行通讯两种。 并行通讯:一条信息的各位数据被同时传送的通讯方式称为并行通讯。 并行通讯的特点是:各数据位同时传送,传送速度快、效率高,但有多少数据位就需多少根数据线,因此传送成本高,且只适用于近距离(相距数米)的通讯。 串行通讯:一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。 串行通讯的特点是:数据位传送,传按位顺序进行,最少只需一根传输线即可完成,成本低但送速度慢。串行通讯的距离可以从几米到几千米。 根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。信息只能单向传送为单工;信息能双向传送但不能同时双向传送称为半双工;信息能够同时双向传送则称为全双工。 而按照串行数据的时钟控制方式,串行通信又可分为同步通信和异步通信两种方式。 异步通信:接收器和发送器有各自的时钟; 同步通信:发送器和接收器由同一个时钟源控制。 1、异步串行方式的特点 所谓异步通信,是指数据传送以字符为单位,字符与字符间的传送是完全异步的,位与位之间的传送基本上是同步的。异步串行通信的特点可以概括为: ①以字符为单位传送信息。 ②相邻两字符间的间隔是任意长。 ③因为一个字符中的比特位长度有限,所以需要的接收时钟和发送时钟只要相近就可以,不需同步。 ④异步方式特点简单的说就是:字符间异步,字符内部各位同步。 2、异步串行方式的数据格式 异步串行通信的数据格式如图1所示,每个字符(每帧信息)由4个部分组成: ①1位起始位,规定为低电0; ②5~8位数据位,即要传送的有效信息; ③1位奇偶校验位; ④1~2位停止位,规定为高电平1。 3、同步串行方式的特点 所谓同步通信,是指数据传送是以数据块(一组字符)为单位,字符与字符之间、字符内部的位与位之间都同步。同步串行通信的特点可以概括为: ①以数据块为单位传送信息。 ②在一个数据块(信息帧)内,字符与字符间无间隔。 ③因为一次传输的数据块中包含的数据较多,所以接收时钟与发送进钟严格同步,通常要有同步时钟。 4、同步串行方式的数据格式 同步串行通信的数据格式如图2所示,每个数据块(信息帧)由3个部分组成: ①2个同步字符作为一个数据块(信息帧)的起始标志; ②n个连续传送的数据 ③2个字节循环冗余校验码(CRC) 图1 异步串行数据格式图2 同步串行数据格式
Win32API 异步串口通讯
使用Win32API实现Windows下异步串口通讯 目录: 1.异步非阻塞串口通讯的优点 2.异步非阻塞串口通讯的基本原理 3.异步非阻塞串口通讯的基础知识 4.异步非阻塞串口通讯的实现步骤 一,异步非阻塞串口通讯的优点 读写串行口时,既可以同步执行,也可以重叠(异步)执行。 在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。 例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。"重叠"一词的含义就在于此。 二,异步非阻塞串口通讯的基本原理 首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口; 其次,为了保护系统对串口的初始设置,调用GetCommTimeouts()得到串口的原始超时设置; 然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。 三,异步非阻塞串口通讯的基础知识 下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数 CreateFile() 功能:打开串口设备 函数原型 HANDLE CreateFile( LPCTSTR lpFileName, // 串口名称字符串;如:"COM1" 或"COM2" DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE, DWORD dwShareMode, // 共享模式;"必须"为0, 即不能共享 LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULL DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为OPEN_EXISTING DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/O HANDLE hTemplateFile // 临时文件的句柄,通常为NULL ); 说明: 如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。Forexample: Handle m_hComm = CreateFile(com1,GENERIC_READ||GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERL APPED,0);
串口服务器的原理及使用方法
串口服务器的原理及使用方法 串口服务器是将来自TCP/IP协议的数据包,解析为串口数据流;反之,也可以将串口数据流打成TCP/IP协议的数据包,从而实现数据的网络传输。它能多个串口设备连接并能将串口数据流进行选择和处理,把现有的TTL串口或者RS232/RS485/RS422接口的数据转化为IP端口的数据,这样就能够将传统的串行数据送上流行的IP通道,而无须过早的淘汰原有的不带以太网模块的设备,从而提高现有设备的利用率,节约了投资,简化了布线。在数据处理方面,串口服务器完成的是一个面向连接的TTL串口或者RS232/RS485/RS422链路和面向无连接以太网之间的通讯数据的存储控制,系统对各种数据进行处理,处理来自串口设备的串口数据流,并进行格式转换,使之成为可以在以太网中传播的数据帧;对来自以太网的数据帧进行判断,并转换成串行数据送达响应的串口设备。在实际应用方面,串口服务器完成是将TCP/IP协议的以太网接口映射为Windows操作系统下的一个标准串口,应用程序可以像对普通串口一样对其进行收发和控制,比如一般计算机有两个串口COM1和COM2,通过串口服务器可将其上面的串口映射为COM3、COM4、COM5等。 串口联网服务器产品提供了直接通过网络来访问工业设备的解决方案。传统串口设备因此可以被转换成可以从局域网甚至互联网来监测和控制的以太网设备。IOTworkshop的串口服务器提供不同的配置和规格特性以符合特殊应用的需求,包括有Modbus协议转换、TCP、UDP操作模式等。串口联网服务器是重新改造既有串口设备最简单的办法,包括PLC、数控机床、仪器仪表、传感器、无线电收发机和其他串口设备。在自动化工业领域、有成千上万的感应器、检测器、PLC、读卡器或其他设备,互相连接形成一个控制网络,作为信息系统中管理数据的工具。而最常用来连接这些设备的通讯界面就是RS232和RS422/RS485总线。以太网/互联网等网络架构已逐渐在自动化产业内被广泛的采用,取代传统的串口通讯而成为自动化系统通讯的主流。在这种趋势下,以TCP/IP和以太网为代表的成熟度较高的开放式网络技术,正逐渐地被应用在各个自动化系统,连接并控制所有的设备。对所有设备制造商和设备使用者而言,寻求一个经济、快速的解决方案,让现有的设备可立即联网使用,成为掌握竞争商机的重要课题。IOTworkshop出品的Eport-E10超级网口、HF5111设备联网服务器正是这种“立即联网”的解决方案。它可以让传统的TTL串口或者RS232/485/422设备,立即转换成具备网络界面的网络设备。 1.直连方式:所谓直连就是将计算机上的网线口与串口服务器上的以太网口直接相连, 如图1所示。该组网方式布线简单,可以实现较长距离传输,较长距离传输的实现 是因为从计算机到串口服务器的距离增大。网线的制作与一般的上网用的网线接线 相同。通过虚拟串口管理软件将串口服务器上的串口映射为COM3、COM4等,便 可像普通串口一样对其进行操作。对于Eport-E10来说,如果将其TTL串口增加 MAX485芯片就成为RS422或RS485,同样可以将其映射为COM3、COM4等,所 以对于上位机来说不管串口服务器以什么样的串口方式输出,其操作方式与对计算 机自身的COM1、COM2口的操作方式一样,大大简化了上位机的编程工作量。然 而,串口服务器真正的优势以及价值的体现并不是表现在直连方式的应用上,将设 备连接到以太网上是它重要的目的。
串口通信协议
串口通信协议 串口通信的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。
的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。 什么是RS-232 RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接工业仪器仪表。用于驱动和连线的改进,实际应用中RS-232的传输长度或者速度常常超过标准的值。RS-232只限于PC串口和设备间点对点的通信。RS-232串口通信最远距离是50英尺。 DB-9针连接头 9针串口连接口顺序图 从计算机连出的线的截面。 RS-232针脚的功能: 数据: TXD(pin 3):串口数据输出(Transmit Data) RXD(pin 2):串口数据输入(Receive Data) 握手: RTS(pin 7):发送数据请求(Request to Send) CTS(pin 8):清除发送(Clear to Send) DSR(pin 6):数据发送就绪(Data Send Ready) DCD(pin 1):数据载波检测(Data Carrier Detect) DTR(pin 4):数据终端就绪(Data Terminal Ready) 地线: GND(pin 5):地线 其他 RI(pin 9):铃声指示 什么是RS-422 RS-422(EIA RS-422-AStandard)是Apple的Macintosh计算机的串口连接标准。RS-422使用差分信号,RS-232使用非平衡参考地的信号。差分传输使用两根线
STM32利用虚拟串口调试
STM32串口利用虚拟串口调试 解决*** error 30: undefined name of virtual register 问题 以下摘录于网络。 1. 利用VSPD将PC上的两个虚拟串口连接起来。如图我将COM2 和COM3连接起来。点击Addr pair。 2. 可以看到Virtual ports上将两个虚拟串口连接到了一起了。 3.虚拟串口准备就绪了。先将直接输入命令的方式来调试。我们打开KEIL MDK的,设置成仿真的模式。点DEBUG.在COMMAND串口输入: MODE COM2 38400, 0, 8, 1
说明: MODE命令的作用是设置被绑定计算机串口的参数。基本使用方式为:
MODE COMx baudrate, parity, databits, stopbits 其中: COMx(x = 1,2,…)代表计算机的串口号; baudrate代表串口的波特率;parity代表校验方式; databits代表数据位长度; stopbits代表停止位长度。 例如:MODE COM1 9600, n, 8, 1 设置串口1。波特率为9 600,无校验位,8位数据,1位停止位。 MODE COM2 19200, 1, 8, 1 设置串口2。波特率为19 200,奇校验,8位数据,1位停止位。 4、点回车后,再输入ASSIGN COM2
实现异步串口
异步传输是一种典型的基于字节的输入输出,指数据按每次一个字节进行传输,其传输速度低。同步传输是把数据字节组合起来一起发送,这种组合称之为帧,其传输速度比异步传输快,同步串口的传送速率高,异步串口实现简单,这是异步串口与同步串口间最主要的区别。 一,异步非阻塞串口通讯的优点 读写串行口时,既可以同步执行,也可以重叠(异步)执行。 在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。 在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。 例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。"重叠"一词的含义就在于此。 二,异步非阻塞串口通讯的基本原理 首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口; 其次,为了保护系统对串口的初始设置,调用 GetCommTimeouts()得到串口的原始超时设置; 然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制; 再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。 三,异步非阻塞串口通讯的基础知识 VC串口通信技术网下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序 中将会使用到的几个关键函数 CreateFile() 功能:打开串口设备 函数原型 1.HANDLE CreateFile( 2.LPCTSTR lpFileName, // 串口名称字符串;如: "COM1" 或 "COM2" 3.DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为 GENERIC_READ|GENERIC_WRITE, 4.DWORD dwShareMode, // 共享模式;"必须"为 0, 即不能共享 5.LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为 NULL 6.DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值; 在这里"必须"为 OPEN_EXISTING 7.DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成 FILE_FLAG_OVERLAPPED ,实现异步I/O 8.HANDLE hTemplateFile // 临时文件的句柄,通常为NULL
串口通信的接线方法
目前较为常用的串口有9针串口(DB9)和25针串口(DB25),通信距离较近时(<12m),可以用电缆线直接连接标准RS232端口(RS422、RS485较远),若距离较远,需附加调制解调器(MODEM)。最为简单且常用的是三线制接法,即地、接收数据和发送数据三脚相连,本文只涉及到最为基本的接法,且直接用RS232相连。 1、DB9和DB25的常用信号脚说明 2、RS232C串口通信接线方法(三线制) 首先,串口传输数据只要有接收数据针脚和发送针脚就能实现:同一个串口的接收脚和发送脚直接用线相连,两个串口相连或一个串口和多个串口相连同一个串口的接收脚和发送脚直接用线相连对9针串口和25针串口,均是2与3直接相连; 两个不同串口(不论是同一台计算机的两个串口或分别是不同计算机的串口) 图2 上面表格是对微机标准串行口而言的,还有许多非标准设备,如接收GPS数据或电子罗盘数据,只要记住一个原则:接收数据针脚(或线)与发送数据针脚(或线)相连,彼些交叉,信号地对应相接,就能百战百胜。 3、串口调试中要注意的几点: 不同编码机制不能混接,如RS232C不能直接与RS422接口相连,市面上专门的各种转换器卖,必须通过转换器才能连接; 线路焊接要牢固,不然程序没问题,却因为接线问题误事;
串口调试时,准备一个好用的调试工具,如串口调试助手、串口精灵等,有事半功倍之效果; 强烈建议不要带电插拨串口,插拨时至少有一端是断电的,否则串口易损坏。 RS232C标准串口接线方法 (第二版) 检验仪器与微机的通讯主要是以RS232C标准接口为主,而串口的接线方法也有一定的标准,在此谈谈几种常用的串口接法,仅作参考: 一、标准接法 1、9对9(包括9针对9孔,9孔对9孔,9针对9针): 说明:以下的孔、针指串口线两端的串口,不过2、3有可能不交换 2-------------3 3-------------2 4-------------6 5-------------5 6-------------4 7-------------8 8-------------7 2、9对25(包括9孔对25孔,9孔对25针) 2-------------3 (备注:2、3有可能不交换) 3-------------2 4-------------6 5-------------7 6-------------20 7-------------5 8-------------4
异步串行通信协议的设计与实现
10 | 电子制作 2018年10月 时传送;串行通信,即数据一位一位顺序传送。串行通信能够节省传输线,特别是数据位数很多和远距离数据传送时,这一优点更为突出。现在流行的高级语言一般都支持对串口的直接操作,常用的单片机也把串行通讯口作为一个标准接口集成在单片机内,串行通讯接口的开发具有开发周期短,开发简单等特点。目前异步串行通信已广泛用于微机之间的通信、工业控制系统中的数据采集与控制、远程数据的传送等方面。 1 串口通信的基本原理 串口在嵌入式系统当中是一类重要的数据通信接口,其本质功能是作为CPU和串行设备间的编码转换器。当数据从CPU经过串行端口发送出去时,字节数据转换为串行的位;在接收数据时,串行的位被转换为字节数据。应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。 典型地,串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线,(2)发送数据线,(3)接收数据线。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通行的端口,这些参数必须匹配:波特率是一个衡量通信速度的参数,它表示每秒钟传送的bit的个数;数据位是衡量通信中实际数据位的参数,当计算机发送一个信息包,标准的值是5、7和8位。如何设置取决于你的需求;停止位用于表示单个包的最后一位,典型的值为1,1.5和2位,停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会;奇偶校验位是串口通信中一种简单的检错方式,有四种检错方式——偶、奇、高和低,也可以没有校验位。做出统一规定。 在控制系统中,单片机间通信一般采用异步串行通信,传统的异步串行通信协议一般采用如图1所示的命令格式,命令消息包括帧头(命令码)、数据帧、校验帧;响应消息为ACK信号(ACK取不同的值,例如:正确响应 ACK = 0x55;错误响应 ACK = 0xAA)。由于在串口通信中还存在很多不可靠的因素,例如由于电磁干扰造成的帧字节丢失、传输误码,以及因主从单片机处理繁忙而造成的响应延迟等。传统的通信协议难以克服由于单片机处理繁忙而造成的响应延迟现象。如图2所示,当主芯片发送[命令1]后,当超过响应等待时间而没有得到ACK时,主芯片发[命令2],而此时在下一个响应等待时间内收到两次[ACK],这时将导致主芯片做出错误判断,调用并非本意的程序执行,严重影响系统的正常运行。因此,本文在通信协议的设计中,采用响应消息加权的方法,提高了通信的可靠性,保证系统正常运行。 图1 通信命令格式 图2 通信时序 本响应消息加权式通信协议,实现方式如下:通信协议
虚拟串口使用方法
虚拟串口使用方法 虚拟串口访问方法要配合上位机驱动软件一起使用。安装了虚拟串口驱动程序后,利用虚拟串口管理软件创建一个虚拟串口,此虚拟串口的使用方法相当于电脑自带的实串口,它会自动检测打开该串口的软件所用的波特率和数据位停止位等信息,并同步到串口服务器,不需要手动设置。虚拟串口软件具有网络连接心中检测功能,可以检测到网络的异常断开,并自动重新连接。 按以下步骤操作,先把串口服务器的工作模式设置为TCP 服务器模式,再安装驱动软件创建串口。 0,串口服务器的设置 先通过网页浏览器登录串口服务器管理页面,设置串口服务器的工作参数。在浏览器的URL地址栏中输入串口服务器的IP地址(如串口服务器的默认IP为:192.168.1.111,用户名为:admin,密码为:admin),打开管理登录界面: 输入用户名和密码后看到串口服务器的当前工作参数:
在对应的串口的[串口设置]功能选项中的[连接模式]选项中选择“TCP 服务器”(串口服务器一厂时一般默认为该模式),其它参数不用设置(驱动程序会根据实际检测到的情况自动 修改)。如下所示:
其它选项不用填,选择“保存为默认设置”后提交马上生效,关机后仍然生效,当[连接模式]改变时请重启串口服务器。 1 虚拟串口软件安装 要通过虚拟串口方式来访问设备必须安装此软件,通过socket方式即可不安装. 安装软件系统要求: 操作系统:windows2000/XP/2003; CPU:1.4G或以上; 内存:128M以上。 在安装文件中,双击Setup.exe 文件,进入安装界面.
点击下一步,进入下一个安装界面, 如果同意软件安装协议选择”我接受”,否则选择”取消”退出安装.选择”我接受”进入下一个安装界面: 选择程序安装目标文件夹,由于所需空间很小,只需要8M左右,一般按照默认则可,若要改变目标文件夹,在”浏览”中选择你的目标文件夹,单击”安装”按钮进入一下安装界面. 在安装过程中会弹出以下窗口,提示正在安装驱动,请勿关闭此窗口,驱动安装完成后些窗口会自动关闭。
异步串行通信的工作方式
异步串行通信的工作方式,然后给出了VB MSComm控件下异步串行通信在电子衡器中的应用实例,包括硬件接口及软件设计。关键词:RS-232 异步串行通信Visual Basic 电子衡器控件计算机一般提供了2个25针或9针的RS-232标准串行口,简称为COM1和COM2。在某些应用中,我们还可以通过插通信卡来获得额外的RS-232标准串行口。利用这些串行口可以与其它数字设备进行一般的数据通信,计算机的串行接口主要用于远程通信和低速输入输出设备。由于串行数据通信传输线条数最少,而且有许多较便宜的专用芯片可实现它,发送和接受器也简单,因而对数据传输速度要求不高的计算机和数字设备间的近程通信,多采用串行通信实现。而目前各个厂家生产的电子衡器的称重仪表多配有与上位机通信的RS—232C串行接口,因而计算机与称重仪表之间的数据通信用串口很容易实现,只需要制作一条2芯或3芯的数据线编写相应的接口程序即可实现,不需要增加其他硬件设备。采用这种方式组成的微机电子衡器有许多优点:称重仪表经过多年的发展,在数据采集、抗干扰、可靠性等方面技术成熟,质量稳定;而计算机在存储容量、数据处理、查询、统计报表等数据管理方面有明显优势。正是两者的完美结合,才使计算机与称重仪表组成的在线式称重管理系统得到了广泛的应用。1串行通信的工作方式串行通信,可分为同步和异步两种方式。异步方式是指在约定的波特率下,传送和接受的数据不需要严格的保持同步,允许有相对的延迟,虽然速度较慢,但经济实用,所以异步串行通信现大量应用于计算机接口技术中。计算机与称重仪表就采用异步通信的方式传送数据。1.1异步串行通信的数据格式在这种通信方式中,一般以一个字符为一帧。一帧最少由三部分组成:起始位、数据位、停止位,开始是一位起始位以发送一个逻辑“0”表示,接着是表示这个数据的数据位,数据位可以是5位、6位、7位或8位,再加一位奇偶校验位,然后是一个、一个半或二个停止位,停止位以逻辑“1”表示。1.2波特率串行通信每秒传送的位数,传送时先低位后高位。常用的波特率有600、1200、2400、4800、9600等。1.3端口在计算机中,一般都配有两个标准串行口,用COM1和COM2表示。(通常采用2个9针D型阳性插头。)1.4信号线RS—232C标准规定有25根连线,使用21个信号线。在我们讨论的微机电子衡器中仅用到3根信号线,它们是:发送数据线TXD(输出信号),接受数据线RXD(输入信号线),信号地GND。其余信号线定义可参考相关书籍。2串行通信在电子衡器中的应用实例串行通信接口设计,包括硬件、软件设计两部分。在WINDOWS操作系统下,可选用VC++、VB等可视化开发工具。下面将以上海耀华称重系统公司的XK3190—A1+为例,以VB6.0编程语言,说明串行通信的软、硬件设计过程。 2.1称重仪表仪表选用上海耀华XK3190-A1+仪表,其串口通信格式如下:2.1.1连续方式发送:所传送的数据为仪表显示的当前称量(毛重或净重),每帧数据由12组数据组成。 第X组 内容及注释 1 02(XON)开始 2 +或- 符号位 3 称量数据高位 : 称量数据: : 称量数据: 8 称量数据低位 9
异步串行UART协议详解 中文版
异步串行UART协议
7.1.1 串行口的结构
2个物理上独立的接收、发送缓冲器SBUF,占用同一地 个物理上独立的接收、发送缓冲器 个物理上独立的接收 , 址99H ;接收器是双缓冲结构 。
7.1.2 串行口的控制
1、串行口控制寄存器SCON (98H)
设定工作方式、接收 发送控制以及设置状态标志 设定工作方式、接收/发送控制以及设置状态标志 SCON (98H)
SM0
SM1
SM2
REN
TB8
RB8
TI
RI
SM0、SM1:工作方式设置位 、 :
SM2,多机通信控制位。 ,多机通信控制位。
主要用于方式2和方式 。 主要用于方式 和方式3。对于接收机 和方式 SM2=0,收到 ,收到RB8(0或1)既可使收到的数据进入 ( 或 )既可使收到的数据进入SBUF, , 并激活RI。 并激活 。 SM2=1,收到的 信息丢弃, ,收到的RB8=0时,收到的信息丢弃,不激活 ; = 时 收到的信息丢弃 不激活RI 若收到的RB8=1时,收到的数据进入 数据进入SBUF,并激活 ,进而 若收到的 = 时 收到的数据进入 ,并激活RI, 读走。 在中断服务中将数据从 读走 在中断服务中将数据从SBUF读走。 方式0时 必须是0。 方式 时,SM2必须是 。 必须是 方式1时 才激活。 方式 时,SM2=1时,只有接收到有效停止位时,RI才激活。 时 只有接收到有效停止位时, 才激活
REN,允许串行接收位。 ,允许串行接收位。
置REN=1,启动串口接收过程 , 置REN=0,则禁止串口接收 ,
虚拟串口Virtual Serial Port说明书
VSPM虚拟串口软件使用帮助虚拟串口软件使用帮助 (Ver2.5) (Ver2.5)
一、一、 软件介绍软件介绍 1、 功能说明功能说明 VSPM 虚拟串口软件可以将TCP/IP 连接、连接、UDP UDP 广播,映射成本机的虚拟COM 口,应用程序通过访问虚拟串口,就可以完成远程控制、数据传输等功能。等功能。 VSPM 虚拟串口软件特点:虚拟串口软件特点: 多虚拟串口映射多虚拟串口映射 收/发多线程架构发多线程架构 支持虚拟串口参数同步指令支持虚拟串口参数同步指令 自动错误纠正、自动连接、自动重新试自动错误纠正、自动连接、自动重新试 实时虚拟串口数据传输监控实时虚拟串口数据传输监控 集成Telnet 管理器管理器 集成设备探测器集成设备探测器 Server Server、、Client Client、、U DP 广播模式,广播模式,33种工作模式种工作模式 支持扩展DLL 插件,具备强大的扩展功能插件,具备强大的扩展功能 免费软件免费软件
2、 VSPM 软件适用范围软件适用范围 适用的嵌入式设备适用的嵌入式设备 可以将任何使用TCP/IP 或UDP 广播方式传输数据的嵌入式设备虚拟成本机COM 口。口。 这些设备包括串口服务器、无线DTU 或其他各类嵌入式以太网&TCP/IP 设备。设备。 虚拟串口互联虚拟串口互联 1台电脑用Server 模式和Client 模式运行2个VSPM 虚拟串口软件,可以实现虚拟串口互联。可以实现虚拟串口互联。 软件调试及串口通讯模拟软件调试及串口通讯模拟 利用各类扩展DLL 插件,可以使VSPM 模拟成一个串口设备,方便软件调试。件调试。 3、 VSP VSPM M 虚拟串口性能参数虚拟串口性能参数 项目项目 配置配置 端口速度端口速度 110110--115200bps 115200bps 数据位数据位 5、6、7、8 停止位停止位 1、2 校验位校验位 无、奇、偶、标记。无、奇、偶、标记。 流控流控 可设置流控,但VSPM 软件在转发时忽略此设置。软件在转发时忽略此设置。 发送缓冲发送缓冲 8K 字节,如果超过此长度,将丢弃超出部分的数据。字节,如果超过此长度,将丢弃超出部分的数据。