使用的USB转CAN的设备是周立功的USBCAN-II,在购买的时候,会有上位机二次开发的库文件、例程和API文档等材料,可以参考。

1、库函数的调用

首先,把库函数文件都放在工作目录下。库函数文件总共有三个文件:ControlCAN.h、ControlCAN.lib、ControlCAN.dll和一个文件夹kerneldlls。

VC调用动态库的方法

(1) 在扩展名为.CPP的文件中包含ControlCAN.h头文件。

如:#include “ControlCAN.h”

(2) 在工程的连接器设置中连接到ControlCAN.lib文件。

如:在VC7环境下,在项目属性页里的配置属性→连接器→输入→附加依赖项中添加ControlCAN.lib

中间换了一台电脑,出现电脑丢失ControlCAN.dll的问题,将ControlCAN.dll拷到了可执行文件的文件夹中即可

2、基本操作

2.1 连接设备

我这里每次连接都会重新开启接收数据的线程,创建一次接收数据的txt文档

voidCTest_OilDlg::OnBnClickedButtonConnect()

{//首先判断CAN是否打开,,如果已经打开,则先复位及重启CAN--1.8//关闭程序前必须点击断开连接按钮,否则报错

if(m_connect == 1)

{

m_connect= 0;//isShow = 0;

Sleep(500);

GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowTextW(_T("连接"));

VCI_CloseDevice(m_deviceType,m_deviceIndex);

showListInfo(_T("断开设备成功"));//结束自发自收测试的定时器

KillTimer(0);//结束当前线程

if(m_pThread !=NULL)

{//::WaitForSingleObject(m_pThread->m_hThread,INFINITE);//该函数会造成死锁//https://blog.csdn.net/silvervi/article/details/5874212将上面函数修改成如下,以避免上面函数阻塞对话框主线程的消息队列

DWORD dwRet = 0;

MSG msg;while(true)

{//等待处理数据线程结束,和等待消息队列中的任何消息

dwRet = MsgWaitForMultipleObjects(1,&m_pThread->m_hThread,false,INFINITE,QS_ALLINPUT);//dwRet = WaitForSingleObject(m_pThread->m_hThread,50);

switch(dwRet)

{caseWAIT_OBJECT_0:break;case WAIT_OBJECT_0 + 1://get the message from Queue and dispatch it to specific window

PeekMessage(&msg,NULL,0,0,PM_REMOVE);

DispatchMessage(&msg);continue;default:break;

}break;

}//CloseHandle(m_pThread->m_hThread);

deletem_pThread;

m_pThread= NULL;//不太懂

}//关闭存储数据的文件

for(int i = 0;i < 4;i++)

{//判断文件是否打开,若打开了关闭

if(m_waveDataFile[i].m_hFile !=CFile::hFileNull)

{

m_waveDataFile[i].Close();

}

}

GetDlgItem(IDC_BUTTON_START)->SetWindowTextW(_T("开始工作"));return;

}//------------打开设置---------------------//

//设备类型

m_deviceType =VCI_USBCAN2;//设备索引号,只有一个设备,索引号为0

m_deviceIndex = 0;//第0路CAN--只有一路,用户选择

CString canNum;

m_selectCANNum.GetWindowTextW(canNum);

m_canNumA=_ttoi(canNum);if(VCI_OpenDevice(m_deviceType,m_deviceIndex,0) != STATUS_OK)//m_deviceType:设备类型号;m_deviceIndex:设备索引号;最后一个是保留参数,一般为0

{

MessageBox(_T("打开设备失败!",_T("警告"),MB_OK|MB_ICONQUESTION));

showListInfo(_T("打开设备失败"));

SetHScroll();return;

}else{

showListInfo(_T("打开设备成功"));

SetHScroll();

}///-------------对CAN进行初始化------------------//

//对CAN进行初始化

VCI_INIT_CONFIG init_config;

init_config.AccCode= 0x00000000;

init_config.AccMask= 0xffffffff;//表示全部接收,(全部接收,AccMask:0xffffffff;AccCode:0x00000000---这块可以通过测试软件中的滤波设置功能中计算)

init_config.Mode = 0;//正常模式;1:表示只听模式(只接收,不影响总线)

init_config.Timing0 = 0x00;

init_config.Timing1= 0x14;//相当于波特率1000kbps

if(VCI_InitCAN(m_deviceType,m_deviceIndex,m_canNumA,&init_config) !=STATUS_OK)

{

MessageBox(_T("初始化CAN失败!"),_T("警告"),MB_OK|MB_ICONQUESTION);

VCI_CloseDevice(m_deviceType,m_deviceIndex);

showListInfo(_T("初始化CAN失败"));

SetHScroll();return;

}else{

showListInfo(_T("初始化CAN成功"));

SetHScroll();

}

m_connect= 1;

GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowTextW(_T("断开"));//创建存储数据的文件

CTime time0 =CTime::GetCurrentTime();

CString fileName= _T("WaveData");if(!PathIsDirectory(fileName))

{

::CreateDirectory(fileName,NULL);

}

fileName.Format(_T("WaveData/%d-%d %dh%dm%ds"),time0.GetMonth(),time0.GetDay(),time0.GetHour(),time0.GetMinute(),time0.GetSecond());if(!PathIsDirectory(fileName))

{

::CreateDirectory(fileName,NULL);

}

CString fileName0=fileName;for(int i = 0;i < 4;i++)

{

CString i0;

i0.Format(_T("/%dth"),i+1);

fileName= fileName0 +i0;

fileName+= _T(".txt");

m_waveDataFile[i].Open(fileName,CFile::modeWrite|CFile::modeCreate|CFile::modeNoTruncate);//若文件存在,则清空

}//开启接收数据的线程

m_pThread = AfxBeginThread(ReceiveThread,this,0,CREATE_SUSPENDED,NULL);

m_pThread->m_bAutoDelete = false;

}

2.2 接收数据

UINT CTest_OilDlg::ReceiveThread(void *param)

{

CTest_OilDlg*dlg = (CTest_OilDlg*)param;

VCI_CAN_OBJ frameInfo[5000];//一次性从缓冲区获取50个帧

VCI_ERR_INFO errInfo;int len = 1;//获取到的CAN帧的个数

int i = 0;

CString str,tmpstr;while(1)

{

Sleep(1);if(dlg->m_connect == 0)

{break;

}//获取缓冲区的长度

int lenBuf = VCI_GetReceiveNum(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA);//获取到的数据的个数,如果缓冲区大于5000,则取出5000,否则将缓冲区全部取出

len = VCI_Receive(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA,frameInfo,5000,400);//每次从缓冲区获取50帧,等待200ms无响应后结束

if(len <= 0)

{//注意:如果没有读到数据则必须调用此函数来读取出当前的错误码//千万不能省略这一步(即使你可能不想知道错误码是什么)

DWORD error = VCI_ReadErrInfo(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA,&errInfo);//返回值为1 表示操作成功

if((errInfo.ErrCode & 0x0000) == 0x0000)

{//表示错误码是0x0000

}

}else{for(i = 0;i < len;i++)

{

str= _T("数据:\n");if(frameInfo[i].DataLen > 8)

frameInfo[i].DataLen= 8;//原始数据----但是这里没有保存

for(int j = 0; j < frameInfo[i].DataLen;j++)

{

tmpstr.Format(_T("%04x \n"),frameInfo[i].Data[j]);

str+=tmpstr;

}

::SendMessage(dlg->GetSafeHwnd(),WM_WAVEFORM,WPARAM(&frameInfo[i]),NULL);//TRACE(_T("receive\n"));

}

}

}return 0;

}

这里的数据处理是通过发送自定义消息的方法实现的,因为这些数据同时也要画成曲线显示在界面上,需要对界面进行更新操作,这时候需要给界面的主线程发消息去实现界面更新

2.3 发送数据

voidCTest_OilDlg::OnBnClickedButtonSend()

{//-----------------发送井下仪器工作模式命令-------------------// if(m_connect == 0)return;

VCI_CAN_OBJ frameInfo;//设置发送重发超时时间,建议不小于1500ms,默认4000ms

VCI_SetReference(m_deviceType,m_deviceIndex,m_canNumA,4,&m_sendTimeout);

frameInfo.ID= 0x84444444;//需要再确定

frameInfo.SendType = 0;//正常发送

frameInfo.RemoteFlag = 0;//数据帧

frameInfo.ExternFlag = 1;//扩展帧

frameInfo.DataLen = 3;//一个字节

frameInfo.Data[0] = 0x04;

frameInfo.Data[1] = 0xff;//01仪器待机;02:仪器自检;03:仪器定时开关机;04:仪器测试;05:仪器连续工作

frameInfo.Data[2] = m_selectMode.GetCurSel() + 1;int ret = VCI_Transmit(m_deviceType,m_deviceIndex,m_canNumA,&frameInfo,1);if(ret == 1)

{

showListInfo(_T("命令发送成功"));

SetHScroll();

}else{

showListInfo(_T("命令发送失败"));

SetHScroll();

}

}

View Code

3、问题

做到现在,程序自发自收可以,接收下位机数据能接受5个左右的循环就接不到了,后来把数据的操作都屏蔽掉,只接收,发现也接不到,缓冲区内的数据个数为0.这个问题还没解决。

这个问题在使用USBCAN给的例程里面也是存在的,目前不清楚什么问题

3.28:这个问题是因为下位机需要跟两个CAN总线交互,一个是跟上位机,一个是跟其他板子,跟其他板子交互的CAN必须要有人接收,他才会持续的给上位机发数,上位机收不到是因为下位机的另一个CAN没有接收,进入了中断。而CANtest能接收是因为,我在操作的时候犯懒,同时打开了两个通道,也就是另一个通道有人接收,所以才能持续发数。

java CANUSB_周立功USBCAN-II 上位机开发(MFC)相关推荐

  1. java上位机开发(开篇)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 目前对于java语言,很多人都认为太简单.其实这是不对的,因为某种意义上来说所,java语言就像 ...

  2. java开发plc上位机软件开发_上位机开发之西门子PLC-S7通信实践

    写在前面: 就目前而言,在中国的工控市场上,西门子仍然占了很大的份额,因此对于上位机开发而言,经常会存在需要与西门子PLC进行通信的情况.然后对于西门子PLC来说,通信方式有很多,下面简单列举一下: ...

  3. 最简单DIY基于ESP32CAM的物联网相机系统⑥(用上位机VS2013 MFC实现WIFI图传)

    第一篇:最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传) 第二篇:最简单DIY基于ESP32CAM的物联网相机系统②(在JAVAWEB服务器实现图片查看器) 第三篇:最简单DI ...

  4. Matlab上位机开发(一) —— 了解上位机

    1. 上位机的作用 在嵌入式项目开发中,无论是单片机项目.嵌入式Linux项目.FPGA项目,上位机始终是一个很重要的部分,主要用于: 数据显示(波形.温度等) 用户控制(LED,继电器等) 文件传输 ...

  5. 以下是一些常用的上位机开发工具:

    上位机的开发工具很多,具体选择哪种开发工具需要根据具体的需求和开发经验来选择.以下是一些常用的上位机开发工具: Visual Studio:Visual Studio 是一款由微软公司开发的集成开发环 ...

  6. python上位机开发实例-python上位机

    广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! 若python上位机接受到的字符为"1',则print出ok,如果字符是 ...

  7. C# | 上位机开发新手指南(一)概述

    C#上位机开发新手指南(一)概述 文章目录 C#上位机开发新手指南(一)概述 前言 学习C#编程基础 熟悉上位机开发相关知识 选择合适的开发环境 熟练掌握C#编程技巧 掌握常用控件的使用方法 学习与硬 ...

  8. Matlab上位机开发

    Matlab上位机开发 1 了解上位机 1.1 上位机的作用 1.2 常用上位机开发方式 1.2.1 Windows上位机(基于串口通信) 1.2.2 Android上位机(基于网络通信) 1.3 教 ...

  9. android上位机编程,BLE的Android上位机开发(上)

    原标题:BLE的Android上位机开发(上) 各位坛友大家好啊! 上篇BLE的Android开发小技巧(见帖:BLE4.0安卓上位机开发小技巧),但因为当时Android上位机还没有完全开发完毕,B ...

  10. 1.3-原来这才是大家常用的上位机开发平台

    一.有哪些上位机开发平台(优缺点和使用场景) 由于上位机概念的广泛性,所以上位机开发平台可以是任何开发平台.这里介绍几个常用的经典的上位机开发平台及其特性. VB(Visual Basic) 开发语言 ...

最新文章

  1. 软件安全性能測试(转载)
  2. 一位美国前辈工程师的十大职业发展忠告
  3. 一夜吸粉200万被封杀,微信都有哪些逆鳞?
  4. shell+mysql获取数据库名_shell操作mysql数据库
  5. Blazor VS 传统Web应用程序
  6. [css] 能不能使用纯css使你的浏览器卡死?怎么实现?
  7. phpcmsV9首页loop文章调用顶级栏目名称
  8. redis zset底层数据结构
  9. easyui输入框模糊查询
  10. 软件项目成本估算的基本方法
  11. 被迫学计算机,IBM超级计算机Watson爆粗口 被迫“洗脑”
  12. excel如何去重统计户数_excel表格单一数据统计-Excel如何去重,然后统计数据?...
  13. verilogVGA显示太极图案
  14. 低深度测序下的拷贝数变异文章阅读笔记
  15. 华为坠亡员工博客称“心累”
  16. 防止学生机退出电子教室软件的方法
  17. 不要紧张,一切尽在掌握:应激源可控性的神经相关因素
  18. ABAQUS2022软件下载
  19. 回文数判断 — Python实现
  20. 20170204老男孩用过的一些运维软件

热门文章

  1. ARM926EJ-S/ARM920T 协处理器 CP14, CP15详解(转载)
  2. java中pmt计算_5个财务函数FV、PV、PMT、NPER与
  3. ttest求pvalue_TTEST 在EXCEL计算出的结果是t还是p值,用哪一个公式在excel中计算出t值和p值是多少...
  4. PWM的占空比、分辨率
  5. 解决502 bad gateway的九种方案及原因
  6. 创新设计思维自学报告
  7. 数字电视DVB-T/T2/C/S/S2,ATSC,ISDB-T参数设置
  8. 招聘后台投递设置联动按钮迭代开发总结
  9. mysql解锁_mysql锁表如何解锁
  10. 【用户画像】从0到1掌握用户画像知识体系