Windows 10 ARM64平台MFC串口程序开发

 2025-3-26 17:06:13     作者:杨阳     联系作者     17次

Windows 10 IoT ARM64平台除了支持新的UWP框架,也兼容支持老框架MFC。使得用户在Windows 10 IoT下可以对原MFC工程进行功能升级,不用在新框架下重写整个工程。熟悉MFC开发的工程师也可以在Windows 10 IoT平台下继续使用MFC进行开发。

本文展示MFC串口程序开发,及需要注意的地方。

 1、创建MFC工程 

1.      打开visual studio 2022,点击“创建新项目”。

2.      选择筛选条件,语言C++,平台选择Windows,应用类型选择桌面。

3.      选择“MFC应用”,点击下一步。

6.png

4.  应用程序类型选择基于对话框,其它选项默认,创建好工程。

 2、界面设计 

拖动工具栏中控件到设计窗口中,设置好控件属性,绑定好控件变量名及消息响应函数。此处与传统MFC程序开发一样。

 3、串口代码 

可以参考文章《UWP串口程序开发》,使用新Devices库查询串口,打开串口,读写串口。本文依旧采用传统的接口Createfile,WriteFile,ReadFile操作串口。

3.1 查询串口 

已知串口名,可以直接通过CreateFile打开串口。或者通过API接口进行查询。

#include <cfgmgr32.h>
#include <propkey.h>
#include <initguid.h>
#include <devpkey.h>
std::wstring devicePath;
devicePath = GetFirstDevice();
Handle serialHandle= CreateFileW(devicePath.c_str(),GENERIC_READ | GENERIC_WRITE,0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,NULL));
//Handle serialHandle= CreateFileW(L” \\\\?\\ACPI#NXP0113#2#{86e0d1e0-8089-11d0-9ce4-08003e301f73}\\SERCX”,GENERIC_READ | GENERIC_WRITE,0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,NULL));
 
std::wstring GetFirstDevice ()
{
    ULONG length;
    CONFIGRET cr = CM_Get_Device_Interface_List_SizeW(
            &length,
            const_cast<GUID*>(&GUID_DEVINTERFACE_COMPORT),
            nullptr,        // pDeviceID
            CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
 
    if (cr != CR_SUCCESS) {
        throw wexception(
            L"Failed to get size of device interface list. (cr = 0x%x)",
            cr);
    }
 
    std::vector<WCHAR> buf(length);
    cr = CM_Get_Device_Interface_ListW(
            const_cast<GUID*>(&GUID_DEVINTERFACE_COMPORT),
            nullptr,        // pDeviceID
            buf.data(),
            static_cast<ULONG>(buf.capacity()),
            CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
 
    if (cr != CR_SUCCESS) {
        throw wexception(
            L"Failed to get device interface list. (cr = 0x%x)",
            cr);
    }
 
    return std::wstring(buf.data());
}

3.2 打开串口 

与WINCE不同,Windows 10 IoT需要用FILE_FLAG_OVERLAPPED异步操作模式打开和读写串口,如果使用同步操作模式打开串口进行读写,读写效率会有影响。

HANDLE m_hComm = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 00, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);

设置串口参数

GetCommState(m_hComm, &dcb);                                  /* 读取串口的DCB */
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = 0;
dcb.StopBits = 0;
dcb.fBinary = TRUE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
SetCommState(m_hComm, &dcb);                                  /* 设置串口的DCB */

3.3 读串口 

异步操作模式需要设置OVERLAPPED

#include <wrl.h>
using namespace Microsoft::WRL::Wrappers;
auto overlapped = OVERLAPPED();
overlapped.hEvent = overlappedEvent.Get();
 
DWORD bytesRead = 0;
if (!ReadFile(
       pDlg->m_hComm,
       reinterpret_cast<BYTE*>(recvBuf),
       1024,
       &bytesRead,
       &overlapped) && (GetLastError() != ERROR_IO_PENDING)) {
 
       DWORD error = GetLastError();
}
 
if (!GetOverlappedResult(
       pDlg->m_hComm,
       &overlapped,
       &bytesRead,
       TRUE)) {
       DWORD error = GetLastError();
}
 
if (bytesRead != 0)
{
       OnCommRecv(pDlg, recvBuf, bytesRead);                 /* 接收成功调用回调函数 */
}

3.4 写串口 

用异步模式写串口

auto overlapped = OVERLAPPED();
overlapped.hEvent = overlappedEvent.Get();
 
if (!WriteFile(
       m_hComm,
       psendbuf,
       len,
       &dwactlen,
       &overlapped) && (GetLastError() != ERROR_IO_PENDING)) {
       DWORD error = GetLastError();
}
 
if (!GetOverlappedResult(
       m_hComm,
       &overlapped,
       &dwactlen,
       TRUE)) {
       DWORD error = GetLastError();
}

3.5 串口关闭 

CloseHandle(m_hComm);

3.6 创建timer自动发送 


添加对话框的timer消息响应函数OnTimer

1.      启动timer

SetTimer(1, m_period, NULL);

2.      退出时关闭timer

KillTimer(1);

 4、调试 

打开Win10 IoT板子上的调试助手。

3.png

选择工程平台为ARM64,编译运行,示例如下。

7.png

需要程序源码可以联系英创工程师获得。