using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; /*------------兼容ZLG的数据类型---------------------------------*/ //1.ZLGCAN系列接口卡信息的数据类型。 public struct VCI_BOARD_INFO { public UInt16 hw_Version; public UInt16 fw_Version; public UInt16 dr_Version; public UInt16 in_Version; public UInt16 irq_Num; public byte can_Num; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] str_Serial_Num; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public byte[] str_hw_Type; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] Reserved; } ///////////////////////////////////////////////////// //2.定义CAN信息帧的数据类型。 unsafe public struct VCI_CAN_OBJ //使用不安全代码 { public uint ID; public uint TimeStamp; //时间标识 public byte TimeFlag; //是否使用时间标识 public byte SendType; //发送标志。保留,未用 public byte RemoteFlag; //是否是远程帧 public byte ExternFlag; //是否是扩展帧 public byte DataLen; //数据长度 public fixed byte Data[8]; //数据 public fixed byte Reserved[3];//保留位 } //3.定义初始化CAN的数据类型 public struct VCI_INIT_CONFIG { public UInt32 AccCode; public UInt32 AccMask; public UInt32 Reserved; public byte Filter; //0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。 public byte Timing0; //波特率参数,具体配置,请查看二次开发库函数说明书。 public byte Timing1; public byte Mode; //模式,0表示正常模式,1表示只听模式,2自测模式 } /*------------其他数据结构描述---------------------------------*/ //4.USB-CAN总线适配器板卡信息的数据类型1,该类型为VCI_FindUsbDevice函数的返回参数。 public struct VCI_BOARD_INFO1 { public UInt16 hw_Version; public UInt16 fw_Version; public UInt16 dr_Version; public UInt16 in_Version; public UInt16 irq_Num; public byte can_Num; public byte Reserved; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] str_Serial_Num; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] str_hw_Type; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] str_Usb_Serial; } public struct CHGDESIPANDPORT { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] szpwd; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] szdesip; public Int32 desport; public void Init() { szpwd = new byte[10]; szdesip = new byte[20]; } } public unsafe struct UdsAppMsgInfo { public UInt32 xUdsId; public UInt32 xDataLen; public byte xUdsRequest; public fixed byte aDataBuf[150]; } public unsafe struct UdsAppResponseInfo { public bool isPositiveResponse; public byte responseDataLength; public fixed byte responseData[100]; } public struct UdsDID { public byte DID_High; public byte DID_Low; } public struct UdsDIDList { public UdsDID fingerPrint; public UdsDID eraseFlash; public UdsDID checkProgramIndependence; public UdsDID checkCRCofBlock; } public struct FileDownloadDataType { public bool isDownloadFlag; public UInt32 memoryStartAddr; public UInt32 memorySize; public UInt16 fileBlockCRC16; public byte[] fileDownloadDataBuff; } namespace WindowsFormsApplication1 { public partial class Form1 : Form { const int DEV_USBCAN = 3; const int DEV_USBCAN2 = 4; UInt32 receCount = new UInt32(); /// /// /// /// /// /// /// /*------------兼容ZLG的函数描述---------------------------------*/ [DllImport("controlcan.dll")] static extern UInt32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved); [DllImport("controlcan.dll")] static extern UInt32 VCI_CloseDevice(UInt32 DeviceType, UInt32 DeviceInd); [DllImport("controlcan.dll")] static extern UInt32 VCI_InitCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig); [DllImport("controlcan.dll")] static extern UInt32 VCI_ReadBoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo); [DllImport("controlcan.dll")] static extern UInt32 VCI_GetReceiveNum(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd); [DllImport("controlcan.dll")] static extern UInt32 VCI_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd); [DllImport("controlcan.dll")] static extern UInt32 VCI_StartCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd); [DllImport("controlcan.dll")] static extern UInt32 VCI_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd); [DllImport("controlcan.dll")] static extern UInt32 VCI_Transmit(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len); [DllImport("controlcan.dll")] static extern UInt32 VCI_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime); /*------------其他函数描述---------------------------------*/ [DllImport("controlcan.dll")] static extern UInt32 VCI_ConnectDevice(UInt32 DevType, UInt32 DevIndex); [DllImport("controlcan.dll")] static extern UInt32 VCI_UsbDeviceReset(UInt32 DevType, UInt32 DevIndex, UInt32 Reserved); [DllImport("controlcan.dll")] static extern UInt32 VCI_FindUsbDevice(ref VCI_BOARD_INFO1 pInfo); private delegate void CrossThreadOperationControl(); /*------------函数描述结束---------------------------------*/ /*------------全局变量声明---------------------------------*/ //private float X;//当前窗体的宽度 //private float Y;//当前窗体的高度 //private bool IsFirst = true; bool isForm1Colsed = false; byte controllerChooseFlag = 0xFF; static UInt32 m_devtype = 4;//USBCAN2 UInt32 m_devind = 0; UInt32 m_canind = 0; UInt32[] m_arrdevtype = new UInt32[20]; bool UpdateServiceSwitch = false; VCI_CAN_OBJ[] receobj = new VCI_CAN_OBJ[20]; bool buttStartCan = false; bool buttStartDownload = false; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { } private void Form1_Load(object sender, EventArgs e) { Int32 curindex = 0; comboBox_devtype.Items.Clear(); curindex = comboBox_devtype.Items.Add("DEV_USBCAN"); m_arrdevtype[curindex] = DEV_USBCAN; //comboBox_devtype.Items[2] = "VCI_USBCAN1"; //m_arrdevtype[2]= VCI_USBCAN1 ; curindex = comboBox_devtype.Items.Add("DEV_USBCAN2"); m_arrdevtype[curindex] = DEV_USBCAN2; //comboBox_devtype.Items[3] = "VCI_USBCAN2"; //m_arrdevtype[3]= VCI_USBCAN2 ; comboBox_BoardIndex.SelectedIndex = 0; comboBox_CANIndex.SelectedIndex = 0; comboBox_DeviceIndex.SelectedIndex = 0; comboBox_CANIndex.SelectedIndex = 0; comboBox_MsgType.SelectedIndex = 1; comboBox_UC_TMSMod.SelectedIndex = 0; //comboBox_ControllerChoose.SelectedIndex = 0x00; //comboBox_MsgType.SelectedIndex = 0x01; //canMsgType = (byte)(comboBox_MsgType.SelectedIndex); //controllerChooseFlag = (byte)(comboBox_ControllerChoose.SelectedIndex + 1); // comboBox_devtype.SelectedIndex = 1; comboBox_devtype.MaxDropDownItems = comboBox_devtype.Items.Count; setBoxAndButtonEnalbe(true); isForm1Colsed = false; } private void setBoxAndButtonEnalbe(bool trueOrfalse) { comboBox_CANIndex.Enabled = trueOrfalse; comboBox_devtype.Enabled = trueOrfalse; comboBox_BoardIndex.Enabled = trueOrfalse; comboBox_DeviceIndex.Enabled = trueOrfalse; } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (buttStartCan == true) { //VCI_CloseDevice(m_devtype, m_devind); } //autoSaveFile(); //UpdateStep = 0xFF; isForm1Colsed = true; //setBoxAndButtonEnalbe(false); } private void button_StartCAN_Click(object sender, EventArgs e) { if (buttStartCan == true) { buttStartCan = false; timer_rec.Enabled = buttStartCan == true ? true : false; timer_send.Enabled = buttStartCan == true ? true : false; } else { canMsgType = (byte)(comboBox_MsgType.SelectedIndex); m_devtype = m_arrdevtype[comboBox_devtype.SelectedIndex]; m_devind = 0; m_canind = (UInt32)comboBox_CANIndex.SelectedIndex; m_devind = (UInt32)comboBox_DeviceIndex.SelectedIndex; if (VCI_OpenDevice(m_devtype, m_devind, 0) == 0) { MessageBox.Show("打开设备失败,请检查设备类型和设备索引号是否正确", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } buttStartCan = true; timer_rec.Interval = 10; timer_rec.Enabled = buttStartCan == true ? true : false; timer_send.Enabled = buttStartCan == true ? true : false; VCI_INIT_CONFIG config = new VCI_INIT_CONFIG(); if (comboBox_MsgType.Text == "标准帧") { config.AccCode = 0; config.AccMask = 0xffffffff; //config.AccCode = Convert.ToUInt32(textBox_responseAddr.Text, 16) << 21; //config.AccMask = 0x1FFFFF; config.Filter = 0x02;//只接收符合要求的标准帧 //0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。 } else if (comboBox_MsgType.Text == "扩展帧") { config.AccCode = 0; config.AccMask = 0xffffffff; //config.AccCode = Convert.ToUInt32(textBox_responseAddr.Text, 16) << 3; //config.AccMask = 0x07; config.Filter = 0x03;//只接收符合要求的扩展帧 } //波特率设置为250K switch (comboBox_BoardIndex.Text) { case "250K": config.Timing0 = 0x01; config.Timing1 = 0x1C; break; case "500K": config.Timing0 = 0x00; config.Timing1 = 0x1C; break; default: //250K config.Timing0 = 0x01; config.Timing1 = 0x1C; break; } //config.Filter = 0x00;//接收所有报文 config.Mode = (Byte)0x00; //正常工作模式 VCI_InitCAN(m_devtype, m_devind, m_canind, ref config); } button_StartCAN.Text = buttStartCan == true ? "停止CAN" : "启动CAN"; button_StartCAN.BackColor = buttStartCan == true ? Color.GreenYellow : SystemColors.Control; if (buttStartCan == false) { VCI_ResetCAN(m_devtype, m_devind, m_canind); comboBox_devtype.Enabled = true; comboBox_CANIndex.Enabled = true; comboBox_DeviceIndex.Enabled = true; comboBox_BoardIndex.Enabled = true; comboBox_MsgType.Enabled = true; //comboBox_ControllerChoose.Enabled = true; return; } VCI_StartCAN(m_devtype, m_devind, m_canind); comboBox_devtype.Enabled = false; comboBox_CANIndex.Enabled = false; comboBox_DeviceIndex.Enabled = false; comboBox_BoardIndex.Enabled = false; comboBox_MsgType.Enabled = false; //comboBox_ControllerChoose.Enabled = false; } private void timer_rec_Tick(object sender, EventArgs e) { if (receCount == 0) { uint res = VCI_GetReceiveNum(m_devtype, m_devind, m_canind); if (res > 0) { receobj = new VCI_CAN_OBJ[20]; receCount = 0; receCount = VCI_Receive(m_devtype, m_devind, m_canind, ref receobj[0], 15, 0); if (receCount == 0xFFFFFFFF) { receCount = 0; } for (int i = 0; i < receCount; i++) { CAN_Receive_Decode(receobj[i]); //strCanMsg += CANMsgRecord(receobj[i], "rx"); } receCount = 0; } else { } } } int getTwoByte(Byte data, int position) { return ((0X03 << position) & data) >> position; } private void CAN_Receive_Decode(VCI_CAN_OBJ data) { int bypassRelay = 0; byte RCB_bypass_rad = 0; byte RCB_bypass_HE = 0; byte RCB_pump = 0; byte RCB_fan = 0; byte RCB_PTC = 0; byte RCB_modTMax = 0; byte RCB_modTMin = 0; byte RCB_battery_inT = 0; byte RCB_battery_outT = 0; byte RCB_pdu_inT = 0; byte RCB_pdu_outT = 0; byte RCB_motor_outT = 0; byte RCB_rad_outT = 0; byte RCB_HE_outT = 0; byte RCB_EvT = 0; int RCB_battU = 0; int RCB_battCurr = 0; byte RCB_fltCode = 0; byte RCB_battSt = 0; UInt32 RCB_flowmeter1 = 0; UInt32 RCB_flowmeter2 = 0; byte RCB_T1 = 0; byte RCB_T2 = 0; byte RCB_T3 = 0; byte RCB_T4 = 0; unsafe { switch (data.ID) { case 0X1810EECB: bypassRelay = getTwoByte(data.Data[0], 2); if (1 == bypassRelay) { textBox_RCB_relay.Text = "开"; } else { textBox_RCB_relay.Text = "关"; } RCB_bypass_rad = data.Data[1]; RCB_bypass_HE = data.Data[2]; RCB_pump = data.Data[3]; RCB_fan = data.Data[4]; RCB_PTC = data.Data[5]; textBox_RCB_bypass_rad.Text = RCB_bypass_rad.ToString(); textBox_RCB_bypass_HE.Text = RCB_bypass_HE.ToString(); textBox_RCB_pump.Text = RCB_pump.ToString(); textBox_RCB_fan.Text = RCB_fan.ToString(); textBox_RCB_PTC.Text = RCB_PTC.ToString(); byte RCB_TMSMod = data.Data[6]; byte RCB_SOC = data.Data[7]; string[] tmsMod = { "关机模式","制冷模式","制热模式","自循环模式","ERROR"}; if(RCB_TMSMod < 4) { textBox_RCB_TMSMod.Text = tmsMod[RCB_TMSMod]; } else textBox_RCB_TMSMod.Text = tmsMod[4]; textBox_RCB_SOC.Text = ((RCB_SOC + 0.0) * 0.4).ToString(); break; case 0X1811EECB: RCB_modTMax = data.Data[0]; RCB_modTMin = data.Data[1]; RCB_battery_inT = data.Data[2]; RCB_battery_outT = data.Data[3]; RCB_pdu_inT = data.Data[4]; RCB_pdu_outT = data.Data[5]; RCB_motor_outT = data.Data[6]; RCB_rad_outT = data.Data[7]; textBox_RCB_modTMax.Text = (RCB_modTMax - 40).ToString(); textBox_RCB_modTMin.Text = (RCB_modTMin - 40).ToString(); textBox_RCB_battery_inT.Text = (RCB_battery_inT - 40).ToString(); textBox_RCB_battery_outT.Text = (RCB_battery_outT - 40).ToString(); textBox_RCB_pdu_inT.Text = (RCB_pdu_inT - 40).ToString(); textBox_RCB_pdu_outT.Text = (RCB_pdu_outT - 40).ToString(); textBox_RCB_motor_outT.Text = (RCB_motor_outT - 40).ToString(); textBox_RCB_rad_outT.Text = (RCB_rad_outT - 40).ToString(); break; case 0X1812EECB: RCB_HE_outT = data.Data[0]; RCB_EvT = data.Data[1]; RCB_battU = data.Data[3] + (data.Data[2] << 8); RCB_battCurr = data.Data[5] + (data.Data[4] << 8); RCB_fltCode = data.Data[6]; RCB_battSt = data.Data[7]; textBox_RCB_HE_outT.Text = (RCB_HE_outT - 40).ToString(); textBox_RCB_EvT.Text = (RCB_EvT - 40).ToString(); textBox_RCB_battU.Text = ((RCB_battU + 0.0)/10.0).ToString(); textBox_RCB_battCurr.Text = ((RCB_battCurr + 0.0)/10.0 - 1000.0).ToString(); textBox_RCB_fltCode.Text = (RCB_fltCode).ToString(); textBox_RCB_battSt.Text = (RCB_battSt).ToString(); break; case 0X1813EECB: byte[] tmp = new byte[8]; for (int i = 0; i < 8; i++) tmp[i] = data.Data[i]; RCB_flowmeter1 = BitConverter.ToUInt32(tmp, 0); RCB_flowmeter2 = BitConverter.ToUInt32(tmp, 4); textBox_RCB_flowmeter1.Text = ((RCB_flowmeter1 + 0.0)/100.0).ToString(); textBox_RCB_flowmeter2.Text = ((RCB_flowmeter2 + 0.0) / 100.0).ToString(); break; default:break; } } } byte twoByteMove( int position, bool ENABLE) { byte src = 0; if (true == ENABLE) src = 1; else src = 0; return (byte)(src << position); } byte canMsgType; private void CAN_Send_Decode_100ms() { byte tmp = 0; VCI_CAN_OBJ data = new VCI_CAN_OBJ(); unsafe { //0X1801CBEE data.ID = 0X1801CBEE; data.DataLen = 8; data.ExternFlag = canMsgType; tmp += twoByteMove(0, comboBox_HandControlEnable.Text.Equals("使能")); tmp += twoByteMove(2, comboBox_RelayControlEnable.Text.Equals("开")); data.Data[0] = tmp; if (numericUpDown_RaThreeSet.Text != "") data.Data[1] = (byte)numericUpDown_RaThreeSet.Value;// Convert.ToByte(numericUpDown_RaThreeSet.Text); if (numericUpDown_ExThreeSet.Text != "") data.Data[2] = (byte)numericUpDown_ExThreeSet.Value;// Convert.ToByte(numericUpDown_ExThreeSet.Text); for(int i = 1; i < 3; i++) { data.Data[i] = data.Data[i] > (byte)180 ? (byte)180 : data.Data[i]; } if (numericUpDown_WaPuSpConEnable.Text != "") data.Data[3] = (byte)numericUpDown_WaPuSpConEnable.Value;// Convert.ToByte(numericUpDown_WaPuSpConEnable.Text); if (numericUpDown_FanSpeedEnable.Text != "") data.Data[4] = (byte)numericUpDown_FanSpeedEnable.Value;// Convert.ToByte(numericUpDown_FanSpeedEnable.Text); if (numericUpDown_PTC_ControlEnable.Text != "") data.Data[5] = (byte)numericUpDown_FanSpeedEnable.Value;// Convert.ToByte(numericUpDown_PTC_ControlEnable.Text); for (int i = 3; i < 6; i++) { data.Data[i] = data.Data[i] > (byte)100 ? (byte)100 : data.Data[i]; } data.Data[6] = (byte)comboBox_UC_TMSMod.SelectedIndex; VCI_Transmit(m_devtype, m_devind, m_canind,ref data, 1); } } private void timer_send_Tick(object sender, EventArgs e) { CAN_Send_Decode_100ms(); } } }