国内现在做MIT电机的工厂很多,有台州海泰(HT),深圳智擎(Dogi),江西老虎(T-MOTOR),江苏伺泰(SteadyWin),
自MIT去年下半年开源了猎豹机器人以及对应的mini-Cheetah actuator(MIT电机)以后,国内有不少做BLDC电机的厂商都开始做这玩意儿了,不过这些企业都是面向无人机市场或者高校研发之类的,
国内做工业伺服的工厂比如汇川伺服,就没有折腾这个

然后我买了个电机来研究一下……

我有两台MIT电机,一台是智擎的

智擎的会附带发你一个专门的驱动板,可以用这个跟电机做速度控制通信,但是,感觉对开发者而言没用,我无法直接用CAN发送报文。

另一个是海泰HT-03规格的MIT电机,同时也买了他们的USB2CAN模块

海泰客服发了我资料,我可以用USB2CAN模块对应的上位机来驱动MIT电机,但他们自己的上位机代码有问题无法实现速度控制只能位置控制,然后,他们拒绝给对应的上位机源码,所以只好自己用其他方式来驱动这个MIT电机。

最终用这个CAN卡来成功驱动了:

店家发CAN卡的时候,还附赠了一对汽车仪表还有发动机接口的线,看来这玩意儿主要是用于汽车维修行业做检测用的。


这是在店家发过来的资料里,自带的C#示例代码的基础上做的
用这种方式来控制电机,比另一位CSDN网友用STM32开发板来控制,我觉得会方便很多,毕竟嵌入式开发有点难,C#简单点……

CSDN惯例贴代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;/*------------兼容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];}
}namespace WindowsApplication1
{public partial class Form1 : Form{const int DEV_USBCAN = 3;const int DEV_USBCAN2 = 4;/// <summary>/// /// </summary>/// <param name="DeviceType"></param>/// <param name="DeviceInd"></param>/// <param name="Reserved"></param>/// <returns></returns>/*------------兼容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);/*------------函数描述结束---------------------------------*/static UInt32 m_devtype = 4;//USBCAN2UInt32 m_bOpen = 0;UInt32 m_devind = 0;UInt32 m_canind = 0;VCI_CAN_OBJ[] m_recobj = new VCI_CAN_OBJ[1000];UInt32[] m_arrdevtype = new UInt32[20];public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){comboBox_DevIndex.SelectedIndex = 0;comboBox_CANIndex.SelectedIndex = 0;textBox_AccCode.Text = "00000000";textBox_AccMask.Text = "FFFFFFFF";textBox_Time0.Text = "00";textBox_Time1.Text = "14";comboBox_Filter.SelectedIndex = 0;              //接收所有类型comboBox_Mode.SelectedIndex = 0;                //还回测试模式comboBox_FrameFormat.SelectedIndex = 0;comboBox_FrameType.SelectedIndex = 0;textBox_ID.Text = "1";textBox_Data.Text = "FF FF FF FF FF FF FF FC ";//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_devtype.SelectedIndex = 1;comboBox_devtype.MaxDropDownItems = comboBox_devtype.Items.Count;}private void Form1_FormClosed(object sender, FormClosedEventArgs e){if (m_bOpen==1){VCI_CloseDevice(m_devtype, m_devind);}}private void buttonConnect_Click(object sender, EventArgs e){if (m_bOpen==1){VCI_CloseDevice(m_devtype, m_devind);m_bOpen = 0;}else{m_devtype = m_arrdevtype[comboBox_devtype.SelectedIndex];m_devind=(UInt32)comboBox_DevIndex.SelectedIndex;m_canind = (UInt32)comboBox_CANIndex.SelectedIndex;if (VCI_OpenDevice(m_devtype, m_devind, 0) == 0){MessageBox.Show("打开设备失败,请检查设备类型和设备索引号是否正确", "错误",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);return;}m_bOpen = 1;VCI_INIT_CONFIG config=new VCI_INIT_CONFIG();config.AccCode=System.Convert.ToUInt32("0x" + textBox_AccCode.Text,16);config.AccMask = System.Convert.ToUInt32("0x" + textBox_AccMask.Text, 16);config.Timing0 = 0x00;// System.Convert.ToByte("0x" + textBox_Time0.Text, 16);config.Timing1 = 0x14;// System.Convert.ToByte("0x" + textBox_Time1.Text, 16);config.Filter = (Byte)(comboBox_Filter.SelectedIndex+1);config.Mode = (Byte)comboBox_Mode.SelectedIndex;VCI_InitCAN(m_devtype, m_devind, m_canind, ref config);}buttonConnect.Text = m_bOpen==1?"断开":"连接";timer_rec.Enabled = m_bOpen==1?true:false;}unsafe private void timer_rec_Tick(object sender, EventArgs e){UInt32 res = new UInt32();res = VCI_Receive(m_devtype, m_devind, m_canind, ref m_recobj[0],1000, 100);///IntPtr[] ptArray = new IntPtr[1];//ptArray[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * 50);//IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * 1);//Marshal.Copy(ptArray, 0, pt, 1);//res = VCI_Receive(m_devtype, m_devind, m_canind, pt, 50/*50*/, 100);if (res == 0xFFFFFFFF) res = 0;//当设备未初始化时,返回0xFFFFFFFF,不进行列表显示。String str = "";for (UInt32 i = 0; i < res; i++){//VCI_CAN_OBJ obj = (VCI_CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(VCI_CAN_OBJ))), typeof(VCI_CAN_OBJ));str = "接收到数据: ";str += "  帧ID:0x" + System.Convert.ToString(m_recobj[i].ID, 16);str += "  帧格式:";if (m_recobj[i].RemoteFlag == 0)str += "数据帧 ";elsestr += "远程帧 ";if (m_recobj[i].ExternFlag == 0)str += "标准帧 ";elsestr += "扩展帧 ";//if (m_recobj[i].RemoteFlag == 0){str += "数据: ";byte len = (byte)(m_recobj[i].DataLen % 9);byte j = 0;fixed (VCI_CAN_OBJ* m_recobj1 = &m_recobj[i]){if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[0], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[1], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[2], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[3], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[4], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[5], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[6], 16);if (j++ < len)str += " " + System.Convert.ToString(m_recobj1->Data[7], 16);}}listBox_Info.Items.Add(str);listBox_Info.SelectedIndex = listBox_Info.Items.Count - 1;}//Marshal.FreeHGlobal(ptArray[0]);//Marshal.FreeHGlobal(pt);}private void button_StartCAN_Click(object sender, EventArgs e){if (m_bOpen == 0)return;VCI_StartCAN(m_devtype, m_devind, m_canind);}private void button_StopCAN_Click(object sender, EventArgs e){if (m_bOpen == 0)return;VCI_ResetCAN(m_devtype, m_devind, m_canind);}unsafe private void button_Send_Click(object sender, EventArgs e){if(m_bOpen==0)return;VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();//sendobj.Init();sendobj.RemoteFlag = (byte)comboBox_FrameFormat.SelectedIndex;sendobj.ExternFlag = (byte)comboBox_FrameType.SelectedIndex;sendobj.ID = System.Convert.ToUInt32("0x"+textBox_ID.Text,16);int len = (textBox_Data.Text.Length+1) / 3;sendobj.DataLen =System.Convert.ToByte(len);String strdata = textBox_Data.Text;int i=-1;if(i++<len-1)sendobj.Data[0]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[1]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[2]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[3]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[4]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[5]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[6]=System.Convert.ToByte("0x" +strdata.Substring(i * 3, 2),16);if (i++ < len - 1)sendobj.Data[7] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);if(VCI_Transmit(m_devtype,m_devind,m_canind,ref sendobj,1)==0){MessageBox.Show("发送失败", "错误",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}private void button_Clear_Click(object sender, EventArgs e){listBox_Info.Items.Clear();}unsafe private void button3_Click(object sender, EventArgs e){if (m_bOpen == 0)return;VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();//sendobj.Init();sendobj.RemoteFlag = (byte)comboBox_FrameFormat.SelectedIndex;sendobj.ExternFlag = (byte)comboBox_FrameType.SelectedIndex;sendobj.ID = System.Convert.ToUInt32("0x" + textBox_ID.Text, 16);int len = (textBox_Data.Text.Length + 1) / 3;sendobj.DataLen = System.Convert.ToByte(len);String strdata = textBox_Data.Text;int i = -1;if (i++ < len - 1)sendobj.Data[0] = 0xff;if (i++ < len - 1)sendobj.Data[1] = 0xff;if (i++ < len - 1)sendobj.Data[2] = 0xff;if (i++ < len - 1)sendobj.Data[3] = 0xff;if (i++ < len - 1)sendobj.Data[4] = 0xff;if (i++ < len - 1)sendobj.Data[5] = 0xff;if (i++ < len - 1)sendobj.Data[6] = 0xff;if (i++ < len - 1)sendobj.Data[7] = 0xfc;if (VCI_Transmit(m_devtype, m_devind, m_canind, ref sendobj, 1) == 0){MessageBox.Show("发送失败", "错误",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}unsafe private void button4_Click(object sender, EventArgs e){if (m_bOpen == 0)return;VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();//sendobj.Init();sendobj.RemoteFlag = (byte)comboBox_FrameFormat.SelectedIndex;sendobj.ExternFlag = (byte)comboBox_FrameType.SelectedIndex;sendobj.ID = System.Convert.ToUInt32("0x" + textBox_ID.Text, 16);int len = (textBox_Data.Text.Length + 1) / 3;sendobj.DataLen = System.Convert.ToByte(len);String strdata = textBox_Data.Text;int i = -1;if (i++ < len - 1)sendobj.Data[0] = 0xff;if (i++ < len - 1)sendobj.Data[1] = 0xff;if (i++ < len - 1)sendobj.Data[2] = 0xff;if (i++ < len - 1)sendobj.Data[3] = 0xff;if (i++ < len - 1)sendobj.Data[4] = 0xff;if (i++ < len - 1)sendobj.Data[5] = 0xff;if (i++ < len - 1)sendobj.Data[6] = 0xff;if (i++ < len - 1)sendobj.Data[7] = 0xfd;if (VCI_Transmit(m_devtype, m_devind, m_canind, ref sendobj, 1) == 0){MessageBox.Show("发送失败", "错误",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}}}
}

代码里注意, CAN的传输速度必须设置为 1000K。只要速度设对了就可以通信上

使用这个汽车诊断卡,是可以接两路CAN信号的。所以虽然这两个电机的slave id 都是1,但我可以用不同的两个CAN通道来控制,两对CAN线。


记录一下自己踩过的坑:

ARDUINO 坑!
一开始参考的youtube上的瑞士网友skyentific的视频,使用arduin+can shield来做的:

我参照他的方式,买了几张 arduino can shield (因为买错了 can shield) ,都没有成功:

这张卡买来后,一不小心漏焊了SPI的排母,然后排母丢了,就一直都没用上,然后自己费了好大劲把SPI口给焊上:

结果还是不能用!

这是国内改造版本的 arduino seeedio studio 的 CAN shield v1.2 ,非官方原版,它的电子元件跟官方的不一样,我以为是我的焊接问题或国产版电子元件擅自改动的原因,所以又去淘宝买了其他的can shield

这个是skyentific网友在视频里用的sparkfun牌子的can-shield v2.0,拿到手焊接好调试了一个晚上还是没成功,最后发现这板子里的joystick针脚里的left up竟然是短接的,怒,找店家争论,店家说自己的板子绝对没问题,还说让我邮寄退回去,算了先放放,万一我自己把它修好了呢,毕竟只是短接而已……


然后又买了这块板子,依旧是 seeedstudio 的 can-shield v1.2 , 本来就是焊好针脚的,不需要我再焊(我焊接水平不好,另外我只有简单便宜的尖焊头没有刀焊头,所以这个排针对我而言还真不好焊)

这一次使用的时候,发现依然无法跟MIT电机通信,然后终于在seeedstdio官网找到了原因: can-shield v1.2 不支持 1000K的传输速度,

然后又查到了用sparkfun can shield v2.0 不能用的原因,当然有可能是板子本身哪里短接了,但另一方面是国内的大多数 arduino uno , 都是国内简化过的, 擅自把原来的ATMEGA16改成了CH340芯片
CH340芯片属于低速串口芯片,所以我调试不通。
CH340的arduino uno 才16块钱一块,而意大利原版的 ATMEGA16 的 arduino 要100多 , 哎, 心酸……

我放弃了用 arduino 驱动 MIT 电机的这种方式, 鬼知道还有其他哪些坑在这条道路上

2 USB串口调试坑
因为我并不是主职电子领域的,所以对串口不是很懂……
串口的什么 TTL SPI 232 485 协议区别我不太懂,我只知道硬件接线上的区别

智擎的电机,他们的串口我到现在都还没有接通,哎……
反正我调通了海泰电机的串口,就对智擎的放弃了。
他们的串口,搞成了一个USB口,然后发货的时候也没有附带USB线,我向智擎店家要USB口,他们竟然不给,甚至都不卖!我真服了! 然后我自己在淘宝上找了半天也找不到对应的USB口是啥样的,
于是我拆开了他们家的电机,打算自己焊线上去接,

看了一眼,放弃,就我这焊接水平,原指望着能找到一个很大的焊接区域去接线。
但这驱动板上,主控STM32的针脚跟旁边的串口针脚这么近,我要是不小心把主控针脚给连焊了那就完了……

调海泰电机串口时,我先用的 RS232 线来接, 呵呵,当然不行,
店家告诉我这个串口要用 USB2TTL,
然后就去买 USB2TTL,

这两个,便宜的那个是不能用的,因为CH340的速度太慢,无法支持. CP2102 的才行。

最终用 CP2102 的 USB2TTL 调试,才成功。 电机一上电,就会发 mini cheetah 的报文过来, 感动!
毕竟折腾我这么久

3 USB2CAN 的坑
淘宝上就有卖USB2CAN的模块,

这玩意儿是不行的,因为用的CH340芯片,最高速度只能5K,但是MIT电机的需要1000K

后来我买了这个, 还没到货,等到了之后再试试

自己写C#用汽车诊断卡对MIT电机做调试相关推荐

  1. 【图解UDS】UDS汽车诊断标准协议(ISO 14229)带你入门到精通

                                      [图解UDS]UDS汽车诊断标准协议(ISO 14229)带你入门到精通 目录 为了便于学习ISO 14229 UDS诊断协议,提供 ...

  2. UDS汽车诊断入门01 - 简介

    前言 ​ 一直想写一个关于UDS学习的系列文章,却一直没有动笔,一来是由于觉得自己学得还不够透彻,二来想一开始就把文章写得很完美,然而事实上真正要做到对协议非常透彻得话,又谈何容易,协议是死的,人是活 ...

  3. 14229汽车诊断协议学习笔记

    14229汽车诊断协议学习笔记 什么是14229协议 诊断服务基本知识 确认的服务 未确认的服务 请求原语格式 响应原语格式 诊断分层结构 诊断服务 诊断会话控制(0x10)服务 ECU 重置(0x1 ...

  4. 基于CAN总线的汽车诊断协议UDS (网络层 ISO 15765)

    上个月一个同事Z跳槽去了德赛西威,Z之前是完全不懂诊断的MCU工程师,去德赛后做诊断开发,让我感觉到,汽车嵌入式行业,CAN和诊断工程师还是比较稀缺的.之前我和Z共同负责一个项目,我负责CAN网络和诊 ...

  5. 主板诊断卡代码全解析

    主板诊断卡代码全解析 RUN灯功能介绍 该灯只用极少部件,故自身故障率极低,且只需极少的主板插槽信号,故即使插到一个坏的插槽中虽无法走代码,或其它的所有指示灯都不亮,但该灯很有可能照常工作,您可根据: ...

  6. 汽车诊断之UDS入门-UDS概述

    最近工作中涉及ECU刷写部分,作为一个没有接触过汽车诊断的小白,开始了边学边做的历程,对UDS做一个学习总结和复盘,希望可以帮助到各位小伙伴们. 应用层协议 UDS (Unified Diagnost ...

  7. 主板检测(诊断)卡错误代码含义

    诊断卡代码表 开机后主板测试卡直接显示"FF或00"的故障原因及排除方法(附:电脑主板故障诊断卡代码表)开机后主板测试卡直接显示"FF"或"00&qu ...

  8. 计算机测试工作原理,计算机(测试卡)诊断卡的工作原理

    计算机(测试卡)诊断卡的工作原理 (11页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 15.9 积分 简介 诊断卡的工作原理是      利用主板中BI ...

  9. 【Tiny4412】烧写Qt文件系统到SD卡

    00. 目录 文章目录 00. 目录 01. 烧写内核 02. 启动文件系统 03. 烧写Qt文件系统到SD卡 04. 问题讨论 05. 参考 01. 烧写内核 1.1 在minicom中输入如下命令 ...

  10. 谈谈汽车诊断之KWP2000/ISO14229/ISO15765/SAEJ1939

    最近在研究汽车诊断规范,其中涉及到好几个类似的国际规范,比如KWP2000.ISO-14229.ISO-15765.SAE-J1939等等.有的规范彼此之间相互引用,有的规范却又各自独立,简直就是一团 ...

最新文章

  1. AutoCAD .NET API 之——DimStyleTableRecord 的属性列表
  2. python中执行sql语句_Python执行sql语句
  3. MySQL绿色版5.7以上安装教程
  4. 用wxpython做ui_wxPython - 如何强制UI刷新?
  5. 给IT新人的15个建议:苦逼程序员的辛酸反省与总结
  6. 设置和清除LD_LIBRARY_PATH
  7. c语言删除行尾的空格,新人提问:如何将输出时每行最后一个空格删除
  8. Google搜索技巧终极收集
  9. 总结:抓包命令之linux抓包命令
  10. 如何用MATLAB编写FIR维纳滤波器,FIR维纳滤波器的Matlab仿真验证.ppt
  11. WIN7家庭版升级到旗舰版操作
  12. 百度一下网页简单html源码
  13. 基于机器学习算法的LTE高投诉小区预判方法
  14. XMPP与SIP-IM两大协议的对比
  15. GICv3软件overview手册之GICv3基本功能(3)
  16. 兔子生兔子循环python_python 实现兔子生兔子示例
  17. Eclipse Spring Boot STS安装及下载地址整理
  18. html mata头部标签详解
  19. pda扫描枪 按enter键下一个view不能获取焦点
  20. give me your love tonight

热门文章

  1. 怎么把视频变成GIF
  2. 何为挂载(mount)?
  3. 自定义指令,实现默认头像和用户上传头像的切换
  4. python自动视频剪辑_python剪切视频与合并视频的实现
  5. Troubleshooting Consolidation
  6. IPAM——IP地址管理
  7. Android微信撤回消息如何恢复?
  8. js判断图片加载完成后再执行代码
  9. php订单超过未支付,商城订单未支付30分钟自动取消
  10. 【笔记】下单但未支付的订单倒计时自动取消逻辑实现