本帖最后由 IQ110 于 2013-10-27 16:35 编辑
单片机是如何与PC进行通信的呢?目前很多电子产品会与PC进行通信,实现人性化界面,方便数据处理与采集。一个具有人性化界面的电子产品会更方便用户的使用。而且对于低端单片机来讲,由于硬件限制数据需要大量数学计算,那么很多人会想到将数据发送给PC来处理。或者在开发过程,如果能将一些数据实时的打印出来,岂不是很直观。比如,AD值,IO状态,还有程序执行状况等。 比较常用的是通过串口或者USB与PC进行通信。 串口方式: 如果是串口通信,那么在单片机编程时,只需加入 #ifdef DEBUG Prints("系统初始化!\r\n"); …… PrintV("AD值:",data); #endif 当你的开发时只需#define DEBUG,那么程序就会将数据通过串口打印出来,这些数据就可以从串口助手等相关软件端打印出来。当然也可以自己编写软件界面,主要看开发的需求。 开发过程完成之后,将#define DEBUG注释掉,就不会打印了。 其中,Prints、和PrintV是用来用户自己编写的,用于将数据通过串口的发送出去。 串口通信的单片机编程较为简单,可以用自带的UART接口或IO模拟UART,网上有横多例子可以参考,PC端采用串口助手等相关工具。 USB之HID设备: 如果是USB编程的话,那就比较麻烦了,首先你要去了解USB协议,够我们啃几个月了。还有USB的PC软件界面编程。不过现在的笔记本电脑基本很少带串口的,所以USB接口成为大家的首选,当然,很多朋友说我可以采用USB转串口,当然可以啊,没说不行的,不过USB转串口丢失数据的概率还是有的,呵呵!如果是大批量数据传输的话,那么串口就显得心有余而力不足。 大家比较常用的USB通信是将USB枚举成自定义HID设备,然后PC通过枚举对于的PID和VID来进行操作。 首先是单片机的HID描述符,个人觉得自定义HID比较重要的部分是报告描述符,因为枚举成功之后,都是通过报告描述符来打交道的,就像鼠标键盘一样,都是通过报告描述符来的。如下是“圈圈学USB”里的报告描述符: //USB报告描述符的定义 code uint8ReportDescriptor[]= { //每行开始的第一字节为该条目的前缀,前缀的格式为: //D7~D4:bTag。D3~D2:bType;D1~D0:bSize。以下分别对每个条目注释。 //这是一个全局(bType为1)条目,将用途页选择为普通桌面Generic Desktop Page。 //后面跟1字节数据(bSize为1),后面的字节数就不注释了,自己根据bSize来判断。 0x05, 0x01, // USAGE_PAGE (Generic Desktop) //这是一个局部(bType为2)条目,用途选择为0x00。在普通桌面页中, //该用途是未定义的,如果使用该用途来开集合,那么系统将不会把它 //当作标准系统设备,从而就成了一个用户自定义的HID设备。 0x09, 0x00,// USAGE (0) …… };打红色说明很重要,用于区分鼠标、键盘、自定义设备(特别是一些高级的鼠标键盘,可以通过PC端进行功能切换,所以要通过DeviceUsage来区分,我之前做的一款游戏鼠标就是用这种方式区分的,下面会讲到)
而PC软件方面,这边只讲操作思路, 步骤: 1、 使用HidD_GetHidGuid得到HID类的GUID 2、 使用SetupDiGetClassDevs获取HID设备类信息 3、 SetupDiEnumDeviceInterfaces枚举设备接口 4、 如果第3步成功,那么用SetupDiGetDeviceInterfaceDetail获取设备接口的详细信息 5、 用SetupDiGetDeviceInterfaceDetail获取到的设备路径信息,使用CreateFile打开设备 6、 HidD_GetAttributes获取PID和VID进行匹配 之后可以通过CreateFile所创建的句柄用 以下函数DDK: HidD_SetFeature HidD_GetFeature HidD_SetOutputReport HidD_GetInputReport 和window的API函数ReadFile 、WriteFile进行读写操作,具体函数使用请自行查阅 如果是鼠标键盘那么如何进行设备的操作,因为鼠标键盘是独占设备,不能有第三方软件进行操作的,那么市面上那些游戏鼠标键盘是怎么通过PC软件进行功能设置的呢? 你想想如果是键盘鼠标一体化的,那么只有一个PID和VID,那到底要怎么区分呢?这就要用到,当然也就可以区分自定义HID设备了。 如,DeviceUsage = (Capabilities.UsagePage * 256) + Capabilities.Usage; if (DeviceUsage == 0x102) { 这是"mouse"; } if (DeviceUsage == 0x106) { 这是"keyboard"; } if (DeviceUsage == USAGE_PAGE、USAGE(0)) { 这是"自定义HID设备"; } 所以说报告描述符很重要的。 最后,你就可以将你所接收到的数据进行处理,绘曲线、数**算、显示数值、保存…… |