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

发布于:2025-03-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

        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应用”,点击下一步。

        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, 0, 0, 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板子上的调试助手。

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

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