WinCE下读写串口

实例1

//打开串口
hPort=CreateFile(lpszPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

BOOL CSerial::InitDCB()
{
DCB PortDCB;//声明一个DCB结构
DWORD dwError;
PortDCB.DCBlength = sizeof (DCB); //初始化 DCBlength
GetCommState (hPort, &PortDCB); //得到端口的默认设置信息
//改变DCB结构设置
PortDCB.BaudRate =CBR_115200; //波特率
PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity = TRUE; //启用奇偶校验
PortDCB.fOutxCtsFlow = FALSE; //串行端口的输出由CTS线控制
PortDCB.fOutxDsrFlow = FALSE; //关闭串行端口的DSR流控制
PortDCB.fDtrControl = DTR_CONTROL_DISABLE; //启用DTR线
PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
//    PortDCB.fTXContinueOnXoff = TRUE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
//    PortDCB.fTXContinueOnXoff = FALSE;
PortDCB.fOutX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出
PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入
//  PortDCB.fErrorChar = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
//  PortDCB.fNull = FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节
PortDCB.fRtsControl = RTS_CONTROL_DISABLE; //启用RTS线
PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize = 8; //每字节的位数
PortDCB.Parity = EVENPARITY; //偶校验
PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位
//根据DCB结构配置端口
if (!SetCommState (hPort, &PortDCB))
{ //不能配置串行端口
MessageBox (NULL, TEXT("Unable to configure the serial port!"), TEXT("Error!"), MB_OK);
dwError = GetLastError (); //获得错误原因的代码
return FALSE;
}
return TRUE;
}
BOOL CSerial::InitCommTimeouts()
{
COMMTIMEOUTS CommTimeouts; //声明一个COMMTIMEOUTS结构
DWORD dwError;
//得到超时参数
GetCommTimeouts (hPort, &CommTimeouts);
//改变COMMTIMEOUTS结构设置
//不使用这个逾时功能,ReadFile直到所有字符接收完才会返回
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
//不使用这个逾时功能,WriteFile直到所有字符接收完才会返回
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant=0;
if (!SetCommTimeouts(hPort,&CommTimeouts)) //设置端口超时值
{ //不能设置超时值  
MessageBox (NULL, TEXT("Unable to set the time-out parameters!"),TEXT("Error!"), MB_OK);
dwError = GetLastError (); //获得错误原因的代码
return FALSE;
}
return TRUE;
}
DWORD CSerial::WritePort(byte *buf,DWORD dwCharToWrite)
{
BOOL fWriteState;
DWORD dwBytesWritten;
//写入数据
// PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
//PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
fWriteState=WriteFile(hPort,buf,dwCharToWrite,&dwBytesWritten,NULL);
if(!fWriteState) //不能写数据
{
MessageBox(NULL,TEXT("You can''''t write the data to the port!"),TEXT("Error!"),MB_OK);
dwBytesWritten=0;
}
//PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
//PurgeComm(hPort,PURGE_TXCLEAR);
return dwBytesWritten;
}
DWORD  WINAPI  ReadPortThread(LPVOID lpvoid)
{
    BOOL fReadState; //读入信息时返回值,若为TRUE就是正确读入
    DWORD dwCommModemStatus; //串口状态,以判断是否有事件发生
    DWORD dwLength; //读入信息的长度
    COMSTAT ComStat; //串口状态的详细情况表,
    DWORD dwErrorFlags; //读串口状态的标志
    BOOL readStatus=FALSE; //读入信息的状态,若为TRUE就是正在读入但还没有读完
    int iCounter=0;
    DWORD dwBytes;
    byte Byte;
    SetCommMask(hPort,EV_RXCHAR); //设置程序响应的事件
    PurgeComm(hPort,PURGE_RXCLEAR|PURGE_TXCLEAR); //清空串口的接收缓冲区,必要性不大,但有保证作用
    //ClearCommError(hPort,&dwErrorFlags,&ComStat); //清除串口状态标志,并返回当前状态
    while (hPort != INVALID_HANDLE_VALUE) //程序在串口有效的状态下,无限循环
    {
        if(WaitCommEvent(hPort, &dwCommModemStatus,0)) //等待串口的事件发生,当dwCommModemStatus值为1时表示接收到数据
        {
            SetCommMask (hPort, EV_RXCHAR); //重新设置程序响应的事件,但这个只是保证程序的安全性,一般并不起作用
            if (dwCommModemStatus & EV_RXCHAR) //检测收到的事件是否为"接收字符"的事件
            {
                ClearCommError(hPort,&dwErrorFlags,&ComStat); //清除串口状态标志,并返回当前状态
                dwLength=ComStat.cbInQue; //cbInQue返回在串行驱动程序输入队列中的字符数
                if(dwLength>0)//防止无故产生事件
                {
                    //从串口读取数据
                    //读入数据,并返回数据长度,采用同步方式
                    if(dwLength <10240)
                    {
                        fReadState=ReadFile(hPort,&fbuf[0],dwLength,&dwLength,NULL);
                        if(!fReadState)
                        {
                            MessageBox(NULL,TEXT("Can''''t fetch the data!"),TEXT("Reading Error!"),MB_OK); //不能从串口读取数据
                        }
                        else
                        {
                        //ProcessReceive((WPARAM)dwLength,(LPARAM)fbuf);
                            ::SendMessage(m_hWnd,WM_COMM_RCHAR2,(WPARAM)dwLength,(LPARAM)fbuf); //通知主窗口数据已经得到可以处理
                        }
                    }
                    else//当缓存溢出就处理读掉
                    {
                        DWORD j=dwLength%10240;
                        for(int i=0;i                         fReadState=ReadFile(hPort,&fbuf[0],dwLength,&dwLength,NULL);
                        fReadState=ReadFile(hPort,&fbuf[0],j,&j,NULL);
                    }
                }
            }
        }
        // PurgeComm(hPort,PURGE_RXCLEAR);//清空串口的接收缓冲区,必要性不大,但有保证作用
        //重新获得串口状态,必要性不大,48表示没有事件产生
        GetCommModemStatus (hPort, &dwCommModemStatus);
    }
    return 0;
}
///

实例2

BOOL fReadState; //读入信息时返回值,若为TRUE就是正确读入
DWORD dwCommModemStatus; //串口状态,以判断是否有事件发生
DWORD dwLength; //读入信息的长度
COMSTAT ComStat; //串口状态的详细情况表,
DWORD dwErrorFlags; //读串口状态的标志
BOOL readStatus=FALSE; //读入信息的状态,若为TRUE就是正在读入但还没有读完
int iCounter=0;
#if 1
//检测收到的事件是否为"接收字符"的事件
::ClearCommError(g_hGSMCOM,&dwErrorFlags,&ComStat); //清除串口状态标志,并返回当前状态
dwLength=ComStat.cbInQue; //cbInQue返回在串行驱动程序输入队列中的字符数
if(dwLength > 0) { //防止无故产生事件
DWORD dwRetLen = 0;
DWORD dwTimes = (dwLength / (GSM_READBUFF_SIZE - 1)) + 1;
DWORD j = dwLength % (GSM_READBUFF_SIZE-1);
for(DWORD i = 0; i < dwTimes; i++) {
DWORD dwRoundReadSize = ((dwTimes - i) == 1)? j:(GSM_READBUFF_SIZE-1);
memset(g_szReadBuff, 0, dwRoundReadSize + 1);
fReadState=::ReadFile( g_hGSMCOM,
g_szReadBuff,
dwRoundReadSize,
&dwRetLen,
NULL
);
if(!fReadState) {
//RETAILMSG(GSM_DEBUG_ERROR,(TEXT("[%s]: Can''''t fetch the data!/r/n"), pszFname));
MessageBox(NULL,TEXT("Can''''t fetch the data!"),TEXT("Reading Error!"),MB_OK); //不能从串口读取数据
return 0;
} else {
g_szReadBuff[dwRoundReadSize] = 0;
//MessageBox(NULL,TEXT("Read OK!"),TEXT("Reading OK!"),MB_OK);
EnterCriticalSection(&g_csSendLock);
g_pcMC55->CheckResult(g_szReadBuff, dwRoundReadSize);
LeaveCriticalSection(&g_csSendLock);
}
}
return dwLength;
}
#else
if(::WaitCommEvent(g_hGSMCOM, &dwCommModemStatus,0)) { //等待串口的事件发生,当dwCommModemStatus值为1时表示接收到数据
::SetCommMask (g_hGSMCOM, EV_RXCHAR); //重新设置程序响应的事件,但这个只是保证程序的安全性,一般并不起作用
if (dwCommModemStatus & EV_RXCHAR) {//检测收到的事件是否为"接收字符"的事件
::ClearCommError(g_hGSMCOM,&dwErrorFlags,&ComStat); //清除串口状态标志,并返回当前状态
dwLength=ComStat.cbInQue; //cbInQue返回在串行驱动程序输入队列中的字符数
if(dwLength > 0) { //防止无故产生事件
DWORD dwRetLen = 0;
DWORD dwTimes = (dwLength / (GSM_READBUFF_SIZE - 1)) + 1;
DWORD j = dwLength % (GSM_READBUFF_SIZE-1);
for(DWORD i = 0; i < dwTimes; i++) {
DWORD dwRoundReadSize = ((dwTimes - i) == 1)? j:(GSM_READBUFF_SIZE-1);
memset(g_szReadBuff, 0, dwRoundReadSize + 1);
fReadState=::ReadFile( g_hGSMCOM,
g_szReadBuff,
dwRoundReadSize,
&dwRetLen,
NULL
   );
if(!fReadState) {
//RETAILMSG(GSM_DEBUG_ERROR,(TEXT("[%s]: Can''''t fetch the data!/r/n"), pszFname));
MessageBox(NULL,TEXT("Can''''t fetch the data!"),TEXT("Reading Error!"),MB_OK); //不能从串口读取数据
return 0;
} else {
g_pcMC55->CheckResult(g_szReadBuff, dwRoundReadSize);
}
}
return dwLength;
}
}
}
#endif
// PurgeComm(hPort,PURGE_RXCLEAR);//清空串口的接收缓冲区,必要性不大,但有保证作用
//重新获得串口状态,必要性不大,48表示没有事件产生
//::GetCommModemStatus (g_hGSMCOM, &dwCommModemStatus);
return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值