Windows 10 ARM64平台CAN程序开发
本文以Win10 IoT平台下的ESM8400为例,展示如何通过驱动提供CAN接口进行CAN通信。本文例程采用MFC进行界面开发。
1. 创建MFC工程
1. 打开visual studio 2022,点击“创建新项目”。
2. 选择筛选条件,语言C++,平台选择Windows,应用类型选择桌面。
3. 选择“MFC应用”,点击下一步。
4. 应用程序类型选择基于对话框,其它选项默认,创建好工程。
2. 界面设计
拖动工具栏中控件到设计窗口中,设置好控件属性,绑定好控件变量名及消息响应函数。此处与传统MFC程序开发一样。
3. 引用CAN驱动接口
将驱动中CAN接口封装定义头文件及对应cpp文件拷贝到工程目录,右键点击工程,选择添加->现有项,将它们加入工程中。
文件包括:
can.h
imxcan.h
imxcanhw.h
framework.h
FlexCAN.h
FlexCAN.cpp
前4个文件内是CAN驱动相关的必要参数,FlexCAN.h和FlexCAN.cpp中封装了CFlexCAN类,用户可以根据实际需求进行修改或者重新封装。
4. CAN代码
在对话框dlg的头文件中添加引用#include "FlexCAN.h",添加成员变量CFlexCAN m_Can;通过封装好的接口进行CAN通信。
4.1 打开串口
在MFC界面上添加一个按钮,点击后执行打开CAN口操作。
m_CanNo = 1;
DWORD dwBaud = 250000;
m_Can.Open(m_CanNo, dwBaud);
打开CAN1,波特率250K。
4.2 设置CAN过滤
根据实际应用情况设置过滤
//设置CAN过滤can_filter filter;filter.can_id[0].id = 0x10;filter.can_id[0].format = m_ComboExt1.GetCurSel();filter.can_id[0].type = m_ComboRtr1.GetCurSel();filter.can_id[0].id = 0x11;filter.can_id[1].format = m_ComboExt2.GetCurSel();filter.can_id[1].type = m_ComboRtr2.GetCurSel();ret = m_Can.SetFileter(&filter);
4.3 写CAN口
点击发送按钮,执行代码示例
flexcan_frame_t frame;
if (m_CheckExt.GetCheck())
{frame.mfs_0.format = (UINT8)kFLEXCAN_FrameFormatExtend;
}
else
{frame.mfs_0.format = (UINT8)kFLEXCAN_FrameFormatStandard;
}
if (m_CheckRtr.GetCheck())
{frame.mfs_0.type = (UINT8)kFLEXCAN_FrameTypeRemote;
}
else
{frame.mfs_0.type = (UINT8)kFLEXCAN_FrameTypeData;
}
frame.mfp.mfp_b.dataByte0 = data[0];
frame.mfp.mfp_b.dataByte1 = data[1];
frame.mfp.mfp_b.dataByte2 = data[2];
frame.mfp.mfp_b.dataByte3 = data[3];
frame.mfp.mfp_b.dataByte4 = data[4];
frame.mfp.mfp_b.dataByte5 = data[5];
frame.mfp.mfp_b.dataByte6 = data[6];
frame.mfp.mfp_b.dataByte7 = data[7];
ret = m_Can.Write(frame);
4.4 读CAN口
定义一个回调函数gOnRecv
static LPVOID glparam;
static void CALLBACK gOnRecv(LPVOID lparam)
{CFlexCAN* lpFlexCAN = (CFlexCAN*)lparam;CtestcanmfcDlg* pDlg = (CtestcanmfcDlg*)glparam;pDlg->OnRecv(pDlg, &(lpFlexCAN->frame), 1);
}
设置can接收回调函数
m_Can.OnReceive = gOnRecv;
glparam = this;
回调函数调用对话框处理函数
void CALLBACK CtestcanmfcDlg::OnRecv(CWnd* pWnd, flexcan_frame_t* pFrame, int num)
{CtestcanmfcDlg* pDlg = (CtestcanmfcDlg*)pWnd;int i;WCHAR wstrMsg[256];WCHAR wstr[64];int id;BOOL bExt;BOOL bRtr;int dlc;int nLen;int ret = 0;for (i = 0; i < num; i++){id = pFrame[i].mfs_1.id;bExt = pFrame[i].mfs_0.format;bRtr = pFrame[i].mfs_0.type;dlc = pFrame[i].mfs_0.length;wsprintf(wstrMsg, L"Id:0x%04x %s %s", pFrame[i].mfs_1.id, bExt ? L"Ext" : L"Std", bRtr ? L"Rtr" : L" ");if (bRtr){wsprintf(wstr, L" Remote Request DLC=%d\r\n", dlc);}else{wsprintf(wstr, L" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",pFrame[i].mfp.mfp_b.dataByte0, pFrame[i].mfp.mfp_b.dataByte1, pFrame[i].mfp.mfp_b.dataByte2, pFrame[i].mfp.mfp_b.dataByte3,pFrame[i].mfp.mfp_b.dataByte4, pFrame[i].mfp.mfp_b.dataByte5, pFrame[i].mfp.mfp_b.dataByte6, pFrame[i].mfp.mfp_b.dataByte7);wcscat_s(wstrMsg, wstr);}wcscat_s(wstrMsg, L"\r\n");pDlg->m_dwRev++;}}//pDlg->RefreshState();return;
}
4.5 关闭CAN
m_Can.Close();
5、调试
打开Win10 IoT板子上的调试助手。
选择工程平台为ARM64,编译运行,示例如下。
需要程序源码可以联系英创工程师获得。