VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 597|回复: 2

在学串口通讯程序,可是在vs2010里,不知道该怎么找手册参考查api,用帮助一搜就有很多条

[复制链接]
94_avatar_middle
最佳答案
0 
在线会员 发表于 2019-5-18 13:55:03 | 显示全部楼层 |阅读模式
3驿站币
本帖最后由 richthoffen 于 2019-5-18 14:06 编辑

在学串口通讯程序,可是在vs2010里,不知道该怎么找手册参考查api,用帮助一搜comm就有很多条
该怎么搜更有效,有函数或者类的index吗
有没有集中一起讲串口通讯函数的页面 或示例程序
我好久没学习了,问的傻大家别介意





上一篇:求自己搭建视频直播服务器的详细步骤
下一篇:关于vector和list容器,我遇到的问题向大师们提问
75_avatar_middle
最佳答案
0 
在线会员 发表于 2019-5-21 10:05:04 | 显示全部楼层
本帖最后由 xx_player 于 2019-5-21 10:06 编辑

     VS串口通信从6到几千,文档一直都没变,都是那个方法。可以用到老,一直吃到老的东西。
熟悉后就会感觉很简单,就是读取设备文件操作。
    由于这接口长期没改变,当时提供的都是只支持HANDLE的文件访问,无法改成现代流文件。
那就这样用吧。
例程如下:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <Windows.h>
#include <process.h>
using namespace std;
#undef max
namespace app
{
        HANDLE hComm;
        BOOL boQuit;
        OVERLAPPED overlapped;
        BOOL Open(TCHAR *dev,int baudrate, int databit, int parity,int stopbit);
        int Read();
        int Write(BYTE*data,int len);
        void Close();
        void SendData();
    DWORD WINAPI RecvThread(LPVOID lpParam);
};
using namespace app;
int main()
{
        string serialport[] = {
                "0..COM1",
                "1..COM2",
                "2..COM3",
                "3..COM4",
                "4..COM5",
                "5..COM6",
                "6..COM7",
                "7..COM8"
        };
        string baudrate[] = {
                "0..110",
                "1..300",
                "2..600",
                "3..1200",
                "4..2400",
                "5..4800",
                "6..9600",
                "7..14400",
                "8..19200",
                "9..38400",
                "a..57600",
                "b..115200",
                "c..128000",
                "d..256000"
        };
        string parity[] = {
                "0..NO",
                "1..ODD",
                "2..EVEN",
                "3..MARK",
                "4..SPACE"
        };
        string stopbit[] = {
                "0..1",
                "1..1.5",
                "2..2",
        };
        wcout.imbue(locale("chs"));
        cout << "串口例程\n=============" << endl;
        int defaultport = 0;
        int defaultbaudrate = 6;
        int defaultparity = 2;
        int defaultstopbit = 0;
        char ch;
        for (;;)
        {
                while (1) {
                        cout << "串口设备:" << endl;
                        for (auto x:serialport) {
                                cout <<"   "<<  x << endl;
                        }
                        cout << "请选择[Q退出]:";
                        ch = cin.get();
                        int sel = ch - '0';
                        if (sel > -1 && sel <8) {
                                defaultport = sel;
                                break;
                        }
                        if (tolower(ch) == 'q') return -1;
                        cin.clear();
                        cin.ignore();
                        cin.sync();
                }
                cin.clear();
                cin.ignore();
                cin.sync();
                cout << "-----------------" << endl;
                while (1) {
                        cout << "串口波特率:" << endl;
                        for (auto x : baudrate) {
                                cout << "   " << x << endl;
                        }
                        cout << "请选择[Q退出]:";
                        ch = cin.get();
                        int sel = 0;
                        if (ch >= '0'&& ch <= '9') sel= ch-'0';
                        if (tolower(ch) >= 'a' && tolower(ch) <= 'd') sel = tolower(ch) - 'a'+10;
                        if (sel > -1 && sel <15) {
                                defaultbaudrate = sel;
                                break;
                        }
                        if (tolower(ch) == 'q') return -1;
                        cin.clear();
                        cin.ignore();
                        cin.sync();
                }
                cin.clear();
                cin.ignore();
                cin.sync();
                cout << "-----------------" << endl;
                while (1) {
                        cout << "串口校验位:" << endl;
                        for (auto x : parity) {
                                cout << "   " << x << endl;
                        }
                        cout << "请选择[Q退出]:";
                        ch = cin.get();
                        int sel = 0;
                        if (ch >= '0'&& ch <= '4') sel = ch - '0';
                        if (sel > -1 && sel <5) {
                                defaultparity = sel;
                                break;
                        }
                        if (tolower(ch) == 'q') return -1;
                        cin.clear();
                        cin.ignore();
                        cin.sync();
                }
                cin.clear();
                cin.ignore();
                cin.sync();
                cout << "-----------------" << endl;
                while (1) {
                        cout << "串口停止位:" << endl;
                        for (auto x : stopbit) {
                                cout << "   " << x << endl;
                        }
                        cout << "请选择[Q退出]:";
                        ch = cin.get();
                        int sel = 0;
                        if (ch >= '0'&& ch <= '2') sel = ch - '0';
                        if (sel > -1 && sel <3) {
                                defaultstopbit = sel;
                                break;
                        }
                        if (tolower(ch) == 'q') return -1;
                        cin.clear();
                        cin.ignore();
                        cin.sync();
                }
                cin.clear();
                cin.ignore();
                cin.sync();
                //
                cout << endl;
                cout << "您输入的串口参数为:" << endl;
                cout << "-------------------" << endl;
                cout << "串口设备:"  << serialport[defaultport].substr(3) << endl;
                cout << "波 特 率:"  << baudrate[defaultbaudrate].substr(3) << endl;
                cout << "数 据 位:"  << 8 << endl;
                cout << "校 验 位:"  << parity[defaultparity].substr(3) << endl;
                cout << "停 止 位:"  << stopbit[defaultstopbit].substr(3) << endl;
                cout << endl;
                //
                while(1){
                        cout << "上述是否正确(Y/N/Q)";
                        ch = cin.get();
                        if (tolower(ch) == 'q') return 0;
                        if (tolower(ch) == 'y') break;
                        if (tolower(ch) == 'n') break;
                        cin.clear();
                        cin.sync();
                        cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
                }
                cin.clear();
                cin.ignore();
                cin.sync();
                if (tolower(ch) == 'y') break;
        }
       //这设备名是按vs2015文档,原来就是直接COM+数字
        wstringstream o;
        o << L"\\\\.\\COM" << (defaultport+1);
        wstring dev;
        dev = o.str();
        BOOL b=Open((TCHAR*)dev.c_str(),
                                defaultbaudrate,
                                8,
                                defaultparity,
                                defaultstopbit);
        if (!b) return -2;

        overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        overlapped.Internal = 0;
        overlapped.InternalHigh = 0;
        overlapped.Offset = 0;
        overlapped.OffsetHigh = 0;

        wcout << L"打开串口设备:" << dev << L"正常,准备接收线程..." << endl;
        boQuit = FALSE;
        _beginthreadex(NULL, 0, (_beginthreadex_proc_type)RecvThread, NULL, 0, NULL);
        while (1) {
                cout << "正监控通讯口[s发送q退出]..." << endl;
                cout << ">";
                cin.clear();
                cin.sync();
                ch = cin.get();
                if (tolower(ch) == 'q') break;
                if (tolower(ch) == 's') SendData();
        }
        cout << "退出接收线程" << endl;
        boQuit = TRUE;
        Close();
        cout << "bye!" << endl;
        system("pause");
    return 0;
}

DWORD WINAPI app::RecvThread(LPVOID lpParam) {
        COMSTAT comStat;
        DWORD dwError = 0;
        DWORD dwEvtMask=0;
        while (!boQuit) {
                if (ClearCommError(hComm, &dwError, &comStat) && dwError > 0)
                        PurgeComm(hComm, PURGE_RXABORT | PURGE_RXCLEAR);
                BOOL b = WaitCommEvent(hComm, &dwEvtMask, &overlapped);
                DWORD dwRet = WaitForSingleObject(overlapped.hEvent, INFINITE);
                if (dwRet == WAIT_OBJECT_0) {
                        //获取数据
                        if (dwEvtMask&EV_RXCHAR) {
                        Read();
                                cout << ">";
                        }
                }
                //重置为无信号,等待数据
                ResetEvent(overlapped.hEvent);
        SleepEx(1,TRUE);
        }
        CloseHandle(overlapped.hEvent);
        return 0;
}
void  app::Close() {
        CloseHandle(hComm);
}
BOOL app::Open(TCHAR *dev, int baudrate,int databit, int parity, int stopbit)
{
        if(hComm) CloseHandle(hComm);
        hComm = CreateFile(dev,
                        GENERIC_READ | GENERIC_WRITE,
                        0,       
                        NULL,
                        OPEN_EXISTING,  
                        FILE_FLAG_OVERLAPPED,
                        NULL);
        if (hComm == INVALID_HANDLE_VALUE) {
                wcout << L"打开" << dev << L"失败! 错误码=0x" <<hex<<GetLastError()<<dec<< endl;
                return FALSE;
        }
#define MAX_BUFFER_SIZE   8192
        DCB dcb;               
    // 设置读写缓冲区大小       
        SetupComm(hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);       
    // 设置通讯参数
        GetCommState(hComm, &dcb);
        dcb.BaudRate = baudrate;
        dcb.ByteSize = databit;
        dcb.Parity   = parity;
        dcb.StopBits = stopbit;
        if (!SetCommState(hComm, &dcb)) {
                cout << "SetCommState  失败! 错误码=0x" << hex << GetLastError() << dec << endl;
                return FALSE;
        }
        PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
        // 设置监听掩码
        SetCommMask(hComm, EV_RXCHAR | EV_RXFLAG);
       
        return TRUE;
}
int  app::Read() {
        COMSTAT comStat;       
        DWORD dwError = 0;
        if (ClearCommError(hComm, &dwError, &comStat) && dwError > 0)
        {
                PurgeComm(hComm, PURGE_RXABORT | PURGE_RXCLEAR);
        }
        DWORD dwRx = 0;               
        BYTE data[MAX_BUFFER_SIZE];
        ZeroMemory(data, MAX_BUFFER_SIZE);
        BOOL b = ReadFile(hComm, data, comStat.cbInQue, &dwRx, &overlapped);
        if (b) {
                if(dwRx >0) cout << "接收"<< dec << dwRx << "字节"<<endl;
                for (unsigned int i = 0;i < dwRx;i++) {
                        cout << setw(2) << setfill('0') << hex << data<<" ";
                        if (i % 16 == 15) cout << endl;
                }
                cout << endl;
        }
        return 0;
}
int  app::Write(BYTE*data,int len) {
        DWORD dwError = 0;
        if (ClearCommError(hComm, &dwError, NULL) && dwError > 0)
                PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR);

        cout << "发送数据:" << endl;
        for (int i = 0;i < len;i++) {
                cout << setw(2) << setfill('0') << hex << data << " ";
                if (i % 16 == 15) cout << endl;
        }
        cout << endl;
        DWORD dwTx = 0;
        BOOL b = FALSE;
        //这里异步发送,实际发送字节取不到,用数据长度。
        b = WriteFile(hComm, data, len, &dwTx, &overlapped);
        cout << "发送" << dec << len << "字节" << endl;

        return 0;
}
void app::SendData() {
        char buf[MAX_BUFFER_SIZE];
        ZeroMemory(buf, MAX_BUFFER_SIZE);
        cin.clear();
        cin.sync();
        cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
        cout << "输入要发送的数据:" << endl;
        cin.getline(buf, MAX_BUFFER_SIZE);
        int len = strlen(buf);
        if (len < 1) {
                cout << "没有要发送的数据!" << endl;
                return;
        }
        Write((BYTE*)buf, len);
        cout << endl;
        cout << ">";
}

代码测试,使用虚拟串口软件(需另外找下载),建COM3,COM4,用串口调试助手(需另外找下载)和它对接收发数据。
发送文本时,输入s按回车后输入文本。接收是自动的,线程守护。
虽然也可以不用串口调试助手,启动两个例程,但可视性差一些。例程只是示范工作流程,收发细节部分如数据发送前处理,转换就自行修改吧。
网上要搜资料就输入dcb,这是它独有地。


在学串口通讯程序,可是在vs2010里,不知道该怎么找手册参考查api,用帮助一搜就有很多条






94_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2019-5-21 19:24:49 | 显示全部楼层
xx_player 发表于 2019-5-21 10:05
VS串口通信从6到几千,文档一直都没变,都是那个方法。可以用到老,一直吃到老的东西。
熟悉后就会感 ...

谢谢你的帮助  我有单片机  而且可以直接短接电脑的rx tx
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-9-21 05:30

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表