使用Java 通过jna调用can卡的dll,所有返回值都是正确的,但是接收到的数据帧数始终是0, 发送帧返回消息也是正确的,但是设备没有反应:
public class TestDll {
public interface ControlCANAPI extends Library{
//此处我的jdk版本为64位,故加载64位的Dll
// ControlCANAPI INSTANCE = (ControlCANAPI)Native.loadLibrary("ControlCAN",ControlCANAPI.class);
//Dll2x64中定义的函数
// double Add(double a,double b);
// 1.实现ControlCAN.dll文件接口集成JNA的Library接口
// public interface ControlCANAPI extends Library {
// 2.变量定义:
/// 初始化CAN的配置
public static class VCI_INIT_CONFIG extends Structure{
public static class ByReference extends VCI_INIT_CONFIG implements
Structure.ByReference {}
public static class ByValue extends VCI_INIT_CONFIG implements
Structure.ByValue {}
public long AccCode; // 验收码
public long AccMask; // 屏蔽码
public long Reserved; // 保留
public byte Filter; // 滤波方式,允许设置为0-3
public byte Timing0; // 波特率定时器0
public byte Timing1; // 波特率定时器1
public byte Mode; // 模式 =0表示正常模式(相当于正常节点),=1表示只听模式(只接收,不影响总线),=2表示自发自收模式(环回模式)
@Override
protected List<String> getFieldOrder() {
List<String> Field = new ArrayList<String>();
Field.add("AccCode");
Field.add("AccMask");
Field.add("Reserved");
Field.add("Filter");
Field.add("Timing0");
Field.add("Timing1");
Field.add("Mode");
return Field;
}
}
/// 设备信息对象
@Structure.FieldOrder({"can_Num","hw_Version","fw_Version","dr_Version","in_Version","irq_Num","str_Serial_Num","tmBuildTime"})
public static class VCI_BOARD_INFO extends Structure{
public static class ByReference extends VCI_BOARD_INFO implements
Structure.ByReference {}
public static class ByValue extends VCI_BOARD_INFO implements
Structure.ByValue {}
// public VCI_BOARD_INFO(){
// this.allocateMemory();
// }
// @Structure.FieldOrder();
public byte can_Num; // 表示有几路CAN通道
public Short hw_Version; // 硬件版本号
public Short fw_Version; // 固件版本号
public Short dr_Version; // 驱动程序版本号
public Short in_Version; // 接口库版本号
public Short irq_Num; // 保留参数
public byte[] str_Serial_Num = new byte[20]; // 此板卡的序列号
public byte[] str_hw_Type = new byte[40]; // 硬件类型
public Short tmBuildTime; // 保留参数
@Override
protected List<String> getFieldOrder() {
List<String> Field = new ArrayList<String>();
Field.add("hw_Version");
Field.add("fw_Version");
Field.add("dr_Version");
Field.add("tmBuildTime");
Field.add("in_Version");
Field.add("irq_Num");
Field.add("can_Num");
Field.add("str_Serial_Num");
Field.add("str_hw_Type");
// Field.add("tmBuildTime");
return Field;
}
}
/// CAN信息帧
@Structure.FieldOrder({"ID","TimeStamp","TimeFlag","SendType","RemoteFlag","ExternFlag","DataLen","Data"})
public static class VCI_CAN_OBJ extends Structure{
public static class ByReference extends VCI_CAN_OBJ implements
Structure.ByReference {}
public static class ByValue extends VCI_CAN_OBJ implements
Structure.ByValue {}
public int ID; // 帧ID
public int TimeStamp; // 时间标识
public byte TimeFlag; // 是否使用时间标识,为1时TimeStamp有效
public byte SendType; // 发送帧类型
public byte RemoteFlag; // 是否是远程帧。=0时为为数据帧,=1时为远程帧
public byte ExternFlag; // 是否是扩展帧。=0时为标准帧,=1时为扩展帧
public int DataLen; // 数据长度
public byte[] Data = new byte[8]; // CAN帧的数据
// public byte[] Reserved = new byte[3]; // 系统保留
@Override
protected List<String> getFieldOrder() {
List<String> Field = new ArrayList<String>();
Field.add("ID");
Field.add("TimeStamp");
Field.add("TimeFlag");
Field.add("SendType");
Field.add("RemoteFlag");
Field.add("ExternFlag");
Field.add("DataLen");
Field.add("Data");
// Field.add("Reserved");
return Field;
}
}
/**
* 打开设备
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param Reserved 保留参数,通常为0
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_OpenDevice(int DeviceType, int DeviceInd, int Reserved);
/**
* 关闭设备
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_CloseDevice(int DeviceType, int DeviceInd);
/**
* 初始化指定的CAN通道
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @param pInitConfig 初始化参数结构
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_InitCAN(int DeviceType, int DeviceInd, int CANInd, VCI_INIT_CONFIG.ByReference struct);
/**
* 获取设备信息
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param pInfo 设备信息
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_ReadBoardInfo(int DeviceType, int DeviceInd, VCI_BOARD_INFO struct);
/**
* 获取指定CAN通道的接收缓冲区中,接收到但尚未被读取的帧数量
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_GetReceiveNum(int DeviceType, int DeviceInd, int CANInd);
/**
* 清空指定CAN通道的缓冲区
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_ClearBuffer(int DeviceType, int DeviceInd, int CANInd);
/**
* 启动CAN卡的某一个CAN通道
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_StartCAN(int DeviceType, int DeviceInd, int CANInd);
/**
* 复位 CAN, 与 VCI_StartCAN配合使用
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @return 返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_ResetCAN(int DeviceType, int DeviceInd, int CANInd);
/**
* 发送函数
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @param pSend 要发送的帧结构体 VCI_CAN_OBJ数组
* @param pLength 要发送的帧结构体数组的长度(发送的帧数量
* @return 返回实际发送的帧数,=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_Transmit(int DeviceType, int DeviceInd, int CANInd, VCI_CAN_OBJ.ByReference struct, int pLength);
// int VCI_Transmit(int DeviceType, int DeviceInd, int CANInd, VCI_CAN_OBJ struct, int pLength);
/**
* 接收函数
* @param DeviceType 设备类型
* @param DeviceInd 设备索引
* @param CANInd CAN通道索引
* @param pReceive 接收的帧结构体VCI_CAN_OBJ数组
* @param pLength 接收的帧结构体数组的长度
* @param waitTime 保留参数
* @return 返回实际发送的帧数,=-1表示USB-CAN设备不存在或USB掉线
*/
int VCI_Receive(int DeviceType, int DeviceInd, int CANInd, VCI_CAN_OBJ.ByReference struct, int pLength, int waitTime);
int VCI_ReadErrInfo(int DeviceType, int DeviceInd, int CANInd, VCI_CAN_OBJ pSend);
/***************************control can apl************************/
}
public static void main(String[] args) {
ControlCANAPI controlCAN = (ControlCANAPI) Native.loadLibrary("ControlCAN", ControlCANAPI.class);
if (controlCAN != null) {
System.out.println("VCI_OpenDevice="+controlCAN.VCI_OpenDevice(4, 0, 0)); //+ controlCAN.VCI_CloseDevice(4, 0));
VCI_BOARD_INFO.ByReference testBoardInfo = new VCI_BOARD_INFO.ByReference();
int board = controlCAN.VCI_ReadBoardInfo(4, 0, testBoardInfo);
System.out.println("VCI_ReadBoardInfo=" + board);
System.out.println("testBoardInfo=" + testBoardInfo.can_Num + "|" + testBoardInfo.dr_Version + "|" + testBoardInfo.fw_Version);
VCI_INIT_CONFIG.ByReference vciInitConfig = new VCI_INIT_CONFIG.ByReference();
BigInteger bAccCode = new BigInteger("00000000", 16);
BigInteger bAccMask = new BigInteger("FFFFFFFF", 16);
long lAccCode = bAccCode.longValue();
long lAccMask = bAccMask.longValue();
System.out.println("test---"+lAccCode);
System.out.println("test---"+lAccMask);
vciInitConfig.AccCode = lAccCode;
vciInitConfig.AccMask = lAccMask;
// vciInitConfig.Reserved = 0;
vciInitConfig.Filter = 0;
vciInitConfig.Mode = 0;
vciInitConfig.Timing0 = (byte)0x00;
vciInitConfig.Timing1 = (byte)0x16;
int initinfo = controlCAN.VCI_InitCAN(4, 0, 0, vciInitConfig);
System.out.println("VCI_InitCAN="+ initinfo);
int Startinfo = controlCAN.VCI_StartCAN(4, 0, 0);
System.out.println("VCI_StartCAN="+ Startinfo);
System.out.println("VCI_GetReceiveNum =" + controlCAN.VCI_GetReceiveNum(4,0,0));
byte[] commandBytes = new byte[8];
commandBytes[0] = (byte) 0X11;
commandBytes[1] = (byte) 0X21;
commandBytes[2] = (byte) 0X41;
commandBytes[3] = 0;
commandBytes[4] = 0; ////no used
commandBytes[5] = 0; ////no used
commandBytes[6] = 0; ////no used
commandBytes[7] = 0; ////no used
VCI_CAN_OBJ.ByReference vciCanObj = new VCI_CAN_OBJ.ByReference();
// VCI_CAN_OBJ vciCanObj = new VCI_CAN_OBJ();
vciCanObj.ID = 16;
vciCanObj.SendType = 1; // 单次发送
vciCanObj.ExternFlag = 0; //标准帧
vciCanObj.RemoteFlag = 0; //数据帧
vciCanObj.Data = commandBytes;
vciCanObj.DataLen = 8;
vciCanObj.TimeFlag = 0;
vciCanObj.TimeStamp = 0;
int sendInfo = controlCAN.VCI_Transmit(4, 0, 0, vciCanObj, 1);
System.out.println("VCI_Transmit="+ sendInfo);
VCI_CAN_OBJ.ByReference vciCanObjRec = new VCI_CAN_OBJ.ByReference();
VCI_CAN_OBJ.ByReference[] vciCanObjRecArr = (VCI_CAN_OBJ.ByReference[])vciCanObjRec.toArray(1);
for (int i = 0; i < vciCanObjRecArr.length; i ++) {
vciCanObjRecArr[i].TimeFlag = 1;
}
int receiveInfo = controlCAN.VCI_Receive(4, 0, 0, vciCanObjRec, 100, 0);
if(receiveInfo != 1){
controlCAN.VCI_ReadErrInfo(4, 0, 0, vciCanObjRec);
}
// for (int i = 0; i < receiveInfo; i++) {
// System.out.println("test==" + vciCanObjRecArr[i].DataLen + vciCanObjRecArr[i].ID + vciCanObjRecArr[i].Data);
// }
System.out.println("VCI_Receive="+ receiveInfo);
int Clearinfo = controlCAN.VCI_ClearBuffer(4, 0, 0);
System.out.println("VCI_ClearBuffer="+ Clearinfo);
System.out.println("VCI_CloseDevice="+ controlCAN.VCI_CloseDevice(4, 0));
}
// int a = ControlCANAPI.INSTANCE.VCI_InitCAN(4,0,);
}
}
输出的信息:
VCI_OpenDevice=1
VCI_ReadBoardInfo=1
testBoardInfo=49|2304|824
test---2147483648
test---4294967295
VCI_InitCAN=1
VCI_StartCAN=1
VCI_GetReceiveNum =0
VCI_Transmit=1
VCI_Receive=0
VCI_ClearBuffer=1
VCI_CloseDevice=1
哪里出了问题?该如何调试。