essbox 2019-04-30 18:35 采纳率: 100%
浏览 2382
已采纳

ReadFile异步读取串口

这里是用ReaFile函数辨别单片机串口来的信号,因为要同时响应键盘的输入所以ReadFile用的是异步方式,键盘输入用的是非阻塞函数kbhit可以让程序在这个while里面循环检测,有输入就跳出。
现在的问题是串口发出的信号不能被程序的判别信号触发。求大佬解惑!!希望提供解决办法

    DWORD wCount = 256;//读取的字节数
    DWORD wCount1 = 0;  
    unsigned char str[256];
    OVERLAPPED ov;
    ov.Offset = 0;
    ov.OffsetHigh = 0;
    do
    {
        while (!i)
        {
            ReadFile(hCom, str, wCount, &wCount1, &ov);
            GetOverlappedResult(hCom, &ov, &wCount1, INFINITE);
                for (int i1 = 0; i1 < wCount1; i1++)
                {
                    if (str[i1] == 0xAA)
                    {
                        a = 1;
                    }
                    if (str[i1] == 0xBB)
                        c = 1;
                }
            if (z == 1 && a == 1 && c == 1)
            {
                cout << "入库成功!!!" << endl;
                a = 0;
                c = 0;
                z = 0;
            }
            if (z == 2 && a == 1 && c == 1)
            {
                cout << "出库成功!!!" << endl;
                a = 0;
                c = 0;
                z = 0;
            }
            if (z == 0 && a == 1 && c == 1)
            {
                cout << "警告!!!!!!源未经登记!!!!!!" << endl;
                a = 0;
                c = 0;
                z = 0;
            }
            flag = 0;
            if (_kbhit())
                cin >> str1;
            i = str1.length();
        }
        switch (i)
        {

串口的初始化程序

void Initialization1()
{
    CloseHandle(hCom);
    bool flag1 = 0;
    cout << "正在链接单片机!!!(  请右键开始键>>  设备管理器  >>  端口(COM和LPT), 找到单片机的串口号并输入。)" << endl;
    cout << "请输入串口号(例如:COM1)    :";
    do
    {
        std::string m_csFileName;
        cin >> m_csFileName;
        LPCSTR lpFileName = m_csFileName.c_str();
        hCom = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        if (INVALID_HANDLE_VALUE == hCom)
        {
            cout << "打开COM失败!!!!请重新输入!!\n";
            cout << "请输入串口号(例如:COM1)    :";
        }
        else
        {
            cout << ("COM打开成功!\n");
            flag1 = 1;
        }
    } while (flag1 == 0);
    SetupComm(hCom, 20480, 20480);//输入缓冲区和输出缓冲区的大小都是1024

    COMMTIMEOUTS TimeOuts;//设定读超时    
    TimeOuts.ReadIntervalTimeout = 100;
    TimeOuts.ReadTotalTimeoutMultiplier = 500;
    TimeOuts.ReadTotalTimeoutConstant = 5000;
    TimeOuts.WriteTotalTimeoutMultiplier = 500;//设定写超时
    TimeOuts.WriteTotalTimeoutConstant = 2000;
    SetCommTimeouts(hCom, &TimeOuts);//设置超时

    DCB dcb1;
    GetCommState(hCom, &dcb1);
    dcb1.BaudRate = 9600;//波特率为9600
    dcb1.ByteSize = 8;//每个字节有8位
    dcb1.Parity = NOPARITY;//无奇偶校验位
    dcb1.StopBits = ONESTOPBIT;//一个停止位
    dcb1.fParity = FALSE;
    dcb1.fNull = FALSE;
    SetCommState(hCom, &dcb1);
    PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓冲区
}
  • 写回答

2条回答 默认 最新

  • essbox 2019-05-02 12:28
    关注

    经过多次测试,我发现同步读取也能解决问题。将单片机内的程序设置一个定时发送,刷新串口接收程序;
    将串口超时设定得更短

        COMMTIMEOUTS TimeOuts;//设定读超时    
        TimeOuts.ReadIntervalTimeout = 2;
        TimeOuts.ReadTotalTimeoutMultiplier = 0;
        TimeOuts.ReadTotalTimeoutConstant = 0;
    

    这样就可以同时实现读串口数据判断与检测键盘输入的目的
    图片说明

    主要是不会用多线程,一个只学了C++编程皮毛的咸鱼≡(▔﹏▔)≡。

    感谢@操作员马善福(贵阳专业挖机)大佬的回复!!!给您添蘑菇了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?