WinCE下读写串口非常简单好用的例程

转自:http://www.armce.cn/bbs/thread-8-1-1.html

 

//打开串口
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 <dwLength/10240;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;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值