【C工具】【串口助手】二、Windows下C语言的串口列表自动检索

需要链接这两个库setupapi uuid
添加链接库后下面的程序可以直接拷贝运行
终端需要设置为utf8以适应中文
我的环境是mingw+gcc,只要链接库添加好vs也是一样的
windows相关api文档:https://learn.microsoft.com/zh-cn/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceregistrypropertya

  • cv即可,相关细节从上面的api文档检索
#include <stdio.h>
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>

#pragma comment(lib, "setupapi.lib")

void searchSerialPorts()
{
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA devInfoData;
    DWORD index = 0;

    // 获取串口类设备列表
    hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT);

    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("无法获取串口设备列表\n");
        return;
    }

    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    while (SetupDiEnumDeviceInfo(hDevInfo, index, &devInfoData))
    {
        char deviceInstanceId[MAX_PATH];
        if (SetupDiGetDeviceInstanceIdA(hDevInfo, &devInfoData, deviceInstanceId, sizeof(deviceInstanceId), NULL))
        {
            printf("设备号:%s\n", deviceInstanceId);
        }

        char portDetails[256];
        if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &devInfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)portDetails, sizeof(portDetails), NULL))
        {
            // 将设备描述转换为UTF-8编码
            int utf8Len = MultiByteToWideChar(CP_ACP, 0, portDetails, -1, NULL, 0);
            wchar_t* wideStr = (wchar_t*)malloc(utf8Len * sizeof(wchar_t));
            MultiByteToWideChar(CP_ACP, 0, portDetails, -1, wideStr, utf8Len);

            int utf8Size = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, NULL, 0, NULL, NULL);
            char* utf8Str = (char*)malloc(utf8Size);
            WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, utf8Str, utf8Size, NULL, NULL);

            printf("设备描述:%s\n", utf8Str);

            free(wideStr);
            free(utf8Str);
        }
        else
        {
            printf("无法获取设备描述\n");
        }

        // 获取串口号
        char portName[10];
        HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, &devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
        if (hKey != INVALID_HANDLE_VALUE)
        {
            DWORD portNameSize = sizeof(portName);
            if (RegQueryValueExA(hKey, "PortName", NULL, NULL, (LPBYTE)portName, &portNameSize) == ERROR_SUCCESS)
            {
                printf("串口号:%s\n", portName);
            }
            else
            {
                printf("无法获取串口号\n");
            }

            RegCloseKey(hKey);
        }
        else
        {
            printf("无法打开注册表键\n");
        }

        printf("\n");

        index++;
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
}

int main()
{
    searchSerialPorts();

    return 0;
}

  • 结果正确
    在这里插入图片描述

在这里插入图片描述

  • 再贴一个初级的方法,就是挨着打开一个范围的串口号,能打开就是有,不能获取更多设备信息:
void searchSerialPorts()
{
    char portName[10];
    HANDLE hSerial;
    
    for (int i = 1; i <= 40; i++)
    {
        sprintf(portName, "COM%d", i);
        
        // 尝试打开串口
        hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        
        if (hSerial != INVALID_HANDLE_VALUE)
        {
            printf("找到串口:%s\n", portName);
            CloseHandle(hSerial);
        }
        else
        {
            // 尝试在串口名称前添加"\\\\.\\"后再次打开
            sprintf(portName, "\\\\.\\COM%d", i);
            
            hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
            
            if (hSerial != INVALID_HANDLE_VALUE)
            {
                printf("找到串口:%s\n", portName);
                CloseHandle(hSerial);
            }
        }
    }
}
  • 串口号搜索也可以,就是没有其他信息了
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2547eeece57e46e4a35f375dc7592c64.png

  • 另外,一个退出处理:

BOOL WINAPI consoleHandler(DWORD signal)
{
    if (signal == CTRL_C_EVENT || signal == CTRL_BREAK_EVENT)
    {
        // 关闭串口
        if (hSerial != INVALID_HANDLE_VALUE)
        {
            CloseHandle(hSerial);
        }
        printf("程序已退出\n");
        ExitProcess(0);
        return TRUE;
    }
    return FALSE;
}

int main()
{
     // 设置控制台信号处理函数
    if (!SetConsoleCtrlHandler(consoleHandler, TRUE))
    {
        printf("无法设置控制台信号处理函数\n");
        return -1;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过串口助手发送文件,你需要将文件读入内存,并将其通过串口发送。以下是一个简单的示例,假设你的文件名为“example.txt”,串口的波特率为9600,数据位为8,停止位为1,无校验位: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #define COMPORT "\\\\.\\COM1" // 串口号 #define BAUDRATE CBR_9600 // 波特率 #define DATABITS 8 // 数据位 #define STOPBITS ONESTOPBIT // 停止位 #define PARITY NOPARITY // 校验位 int main() { HANDLE hCom; DCB dcb; COMMTIMEOUTS timeouts; DWORD dwBytesWritten; char buf[1024]; FILE *fp; // 打开串口 hCom = CreateFile(COMPORT, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hCom == INVALID_HANDLE_VALUE) { printf("Error: cannot open COM port\n"); return 1; } // 配置串口 memset(&dcb, 0, sizeof(dcb)); dcb.DCBlength = sizeof(dcb); if (!GetCommState(hCom, &dcb)) { printf("Error: cannot get DCB\n"); CloseHandle(hCom); return 1; } dcb.BaudRate = BAUDRATE; dcb.ByteSize = DATABITS; dcb.StopBits = STOPBITS; dcb.Parity = PARITY; if (!SetCommState(hCom, &dcb)) { printf("Error: cannot set DCB\n"); CloseHandle(hCom); return 1; } // 设置超时 timeouts.ReadIntervalTimeout = 0; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 1000; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 1000; if (!SetCommTimeouts(hCom, &timeouts)) { printf("Error: cannot set timeouts\n"); CloseHandle(hCom); return 1; } // 打开文件 fp = fopen("example.txt", "rb"); if (fp == NULL) { printf("Error: cannot open file\n"); CloseHandle(hCom); return 1; } // 发送文件 while (!feof(fp)) { int n = fread(buf, 1, sizeof(buf), fp); if (n > 0) { if (!WriteFile(hCom, buf, n, &dwBytesWritten, NULL)) { printf("Error: cannot write to COM port\n"); fclose(fp); CloseHandle(hCom); return 1; } } } // 关闭文件和串口 fclose(fp); CloseHandle(hCom); return 0; } ``` 这个程序打开串口,设置波特率、数据位、停止位和校验位,并打开要发送的文件。然后它从文件读取数据块,将其写入串口。程序在文件末尾停止,关闭文件和串口。你可以根据需要修改程序以适应不同的串口和文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值