//串行设备句柄;
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,NULL,OPEN�EXISTING,FILE�ATTRIBUTE�NORMAL,NULL))==INVALID�HANDLE�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”)
//创建一个事件监视线程来监视串口事件
AfxBeginThread(CommWatchProc,pParam)
}
数据发送
数据发送利用WriteFile(山歼)函数实现。对于同步I/O *** 作,它的最后一个参数可为NULL;而对异步I/O *** 作,它的最后一个参数必需是一个指向OVERLAPPED结构的指针,通过OVERLAPPED结构来获得当前的 *** 作状态。
BOOL WriteComm(LPCVOID lpSndBuffer,DWORD dwBytesToWrite)
{
//lpSndBuffer为发送数据缓冲区指针,
dwBytesToWrite为将要发送的字节长度
//设备已打开
BOOL bWriteState
//实际发送的字节数
DWORD dwBytesWritten
//设备未打开
if(!bOpen) return FALSE
bWriteState=WriteFile(hComDev,lpSndBuffer,dwBytesToWrite,&dwBytesWritten,NULL)
if(!bWriteState || dwBytesToWrite!=dwBytesWritten)
//发送失败
return FALSE
else
//发送成功
return TRUE
}
数据接收
接收数据的任务由ReadFile函数完成。该函数从串口接收缓冲区中读取数据,读取数据前,先用ClearCommError函数获得接收缓冲区中的字节数。接收数据时,同步和异步读取的差别同发送数据是一样的返做。
DWORD ReadComm(LPVOID lpInBuffer,DWORD dwBytesToRead)
{
//lpInBuffer为接收数据的缓冲区指针, dwBytesToRead为准备读取的数据长度(字节数)
//串行设备状态结构
COMSTAT ComStat
DWORD dwBytesRead,dwErrorFlags
//设备未打开
if(!bOpen) return 0
//读取串行设备的当前状态
ClearCommError(hComDev,&dwErrorFlags,&ComStat)
/漏唯衡/应该读取的数据长度
dwBytesRead=min(dwBytesToRead,ComStat.cbInQue)
if(dwBytesRead>0)
//读取数据
if(!ReadFile(hComDev,lpInBuffer,dwBytesRead,&dwBytesRead,NULL))
dwBytesRead=0
return dwBytesRead
}
事件监视线程
事件监视线程对串口事件进行监视,当监视的事件发生时,监视线程可将这个事件发送(SendMessage)或登记(PostMessage)到对事件进行处理的窗口类(由pParam指定)中。
UINT CommWatchProc(LPVOID pParam)
{
DWORD dwEventMask=0//发生的事件;
while(bOpen)
{
//等待监视的事件发生
WaitCommEvent(hComDev, &dwEventMask,NULL)
if ((dwEventMask & EV�RXCHAR)==EV�RXCHAR)
……//接收到字符事件后,可以将此消息登记到由pParam有指定的窗口类中进行处理
if(dwEventMask & EV�ERR)==EV�ERROR)
……//发生错误时的处理
}
SetEvent(hEvent)
//发信号,指示监视线程结束
return 0
}
关闭串行设备
在整个应用程序结束或不再使用串行设备时,应将串行设备关闭,包括取消事件监视,将设备打开标志bOpen置为FALSE以使事件监视线程结束,清除发送/接收缓冲区和关闭设备句柄。
void CloseSynComm()
{
if(!bOpen) return
//结束事件监视线程
bOpen=FALSE
SetCommMask(hComDev,0)
//取消事件监视,此时监视线程中的WaitCommEvent将返回
WaitForSingleObject(hEvent,INFINITE)
//等待监视线程结束
CloseHandle(hEvent)//关闭事件句柄
//停止发送和接收数据,并清除发送和接收缓冲区
PurgeComm(hComDev,PURGE�TXABORT| PURGE�RXABORT|PURGE�TXCLEAR|PURGE�RXCLEAR)
//关闭设备句柄
CloseHandle(hComDev)
}
您好,基本的通信方式偶并行通信和串行掘宴通信两种。一条信息的各位数据被同拦棚时传送的通信方式称为并行通信。一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通信。而串行通信又分为异步通信和同步通信两种方式。在单片机中,主要使用异步通信方式。异步通信方式的特点是:按字符传输的,每传输一个字符就用起始位来进来收、发双方的同步,简散则不会因收发双方的始终频率的小的偏差导致错误,这种传输方式利用每一帧的起、止信号来建立发送与接收之间的同步。谢谢。个人研究认为串口类的读 *** 作都是同步方法,为了防止同步接受数据时由于超时等问题使主线程死锁,建议使用线程仔余异步接受念冲滚数据,如://异步读取
private void AsyReceiveData(object serialPortobj)
{
SerialPort sp = (SerialPort)serialPortobj
System.Threading.Thread.Sleep(1000)
MessageBox.Show(sp.ReadExisting())
sp.Close()
}
//开启接判销收数据线程
private void ReceiveData(SerialPort sp)
{
//异步接收数据线程
Thread threadReceiveSub = new Thread(new Parameterized
ThreadStart(AsyReceiveData))
threadReceiveSub.start}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)