前段时间公司开发了一个安卓外设,主要是用某宝淘来的demo 在stm32F103的usb功能来和安卓设备的usb来通讯 叙述之前先来一个整体的框图吧:
需要准备的设备有:
①.安卓手机或者安卓pad,(手机必须支持otg功能,否则就得用host功能了) ②.otg转接线或者转接头 ③.安卓数据线(一定要是能通讯数据的线缆,有些山寨的这个线只有2根线,没有数据线) ④.带有usb功能的单片机(这个usb需要能支持用户自行定义)
usb功能看了一下主要是借助hid的标准协议上衍生而来的一个usb标准设备
/******************** (C) COPYRIGHT 2010 STMicroelectronics ******************** * File Name : usb_desc.c * Author : MCD Application Team * Version : V3.2.1 * Date : 07/05/2010 * Description : Descriptors for Mass Storage Device ******************************************************************************** * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. *******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "usb_desc.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Extern variables ----------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /* USB Standard Device Descriptor */ const u8 CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] = { 0x12, /*bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ 0x00,0x02, /*bcdUSB */ 0x00, /*bDeviceClass*/ 0x00, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/ 0x08, /*bMaxPacketSize40*/ 0x71,0x04, /*idVendor (0x0471)*/ 0x08,0x24, /*idProduct = 0x2408*/ 0x00,0x02, /*bcdDevice rel. 2.00*/ 1, /*Index of string descriptor describing manufacturer */ 2, /*Index of string descriptor describing product*/ 3, /*Index of string descriptor describing the device serial number */ 0x01 /*bNumConfigurations*/ } ; /* CustomHID_DeviceDescriptor */ /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ const u8 CustomHID_ConfigDescriptor[ENEPOINT_NUM*7+18] = { 0x09, /* bLength: Configuation Descriptor size */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ ENEPOINT_NUM*7+18, /*CUSTOMHID_SIZ_CONFIG_DESC, wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration*/ 0xC0, /* bmAttributes: Bus powered */ 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** Descriptor of Custom HID interface ****************/ /* 09 */ 0x09, /* bLength: Interface Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ ENEPOINT_NUM, /* bNumEndpoints */ 0x00, /* bInterfaceClass: HID=0X03,其他选0 */ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 0, /* iInterface: Index of string descriptor */ /********************以下只对HID的描述符 Descriptor of Custom HID HID ********************/ /* 18 */ // 0x09, /* bLength: HID Descriptor size */ // HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ // 0x10, /* bcdHID: HID Class Spec release number */ // 0x01, // 0x00, /* bCountryCode: Hardware target country */ // 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ // 0x22, /* bDescriptorType */ // CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */ // 0x00, /******************** Descriptor of Custom endpoints ******************/ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */ /* Endpoint descriptor type */ 0x01, /* bEndpointAddress: */ /* Endpoint Address (OUT) */ USB_ENDPOINT_TYPE_BULK,/* bmAttributes: Interrupt endpoint */ 0x10,0x00, /* wMaxPacketSize: 32 Bytes max */ 0x20, /* bInterval: Polling Interval (20 ms) */ /* 27 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */ 0x81, /* bEndpointAddress: Endpoint Address (IN) */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes: Interrupt endpoint */ 0x10, 0x00, /* wMaxPacketSize: 32 Bytes max */ 0x20, /* bInterval: Polling Interval (32 ms) */ /* 34 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */ /* Endpoint descriptor type */ 0x82, /* bEndpointAddress: */ /* Endpoint Address (OUT) */ USB_ENDPOINT_TYPE_BULK,/* bmAttributes: Interrupt endpoint */ 0x40,0x00, /* wMaxPacketSize: 512 Bytes max */ 0x20 /* bInterval: Polling Interval (20 ms) */ } ; /* USB String Descriptors (optional) */ const u8 CustomHID_StringLangID[CUSTOMHID_SIZ_STRING_LANGID] = { CUSTOMHID_SIZ_STRING_LANGID, USB_STRING_DESCRIPTOR_TYPE, 0x09, 0x04 } ; /* LangID = 0x0409: U.S. English */ const u8 CustomHID_StringVendor[CUSTOMHID_SIZ_STRING_VENDOR] = { CUSTOMHID_SIZ_STRING_VENDOR, /* Size of Vendor string */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/ /* Manufacturer: "STMicroelectronics" */ 'O', 0, 'T', 0, 'G', 0, }; const u8 CustomHID_StringProduct[CUSTOMHID_SIZ_STRING_PRODUCT] = { CUSTOMHID_SIZ_STRING_PRODUCT, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ 'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, 'A',0, 'n',0, 'd',0, 'r',0, 'o',0, 'i',0, 'd',0, ' ',0, 'U',0, 'S',0, 'B',0, ' ',0, 'O', 0, 'T', 0, 'G', 0, }; u8 CustomHID_StringSerial[CUSTOMHID_SIZ_STRING_SERIAL] = { CUSTOMHID_SIZ_STRING_SERIAL, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ 'T', 0, 'a', 0, 'o', 0, 'b', 0, 'a', 0, 'o', 0, '-', 0, 'B', 0, 'e', 0, 'i', 0, 'j', 0, 'i',0, 'n',0, 'g',0, 'Y',0, 'u',0, 'n',0, 'D',0, 'i',0, 'a',0, 'n',0, 'z',0, 'i',0, 'K',0, 'e',0, 'j',0, 'i',0, }; /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/usb主要功能就是在以上代码中配置的,如果配置正确,此时单片机可以直接连接pc的usb口了。 为什么要在pc下先使用?主要是为了验证单片机端的usb共功能是否正常,毕竟在pc下我们更好调试一些吧!
do(如果连接pc不能正常识别usb) while(请在继续修改);(如果出现感叹号之类的要进一步排除是不是驱动没安装好,这个demo是需要一个专门的驱动程序的)
如果这个时候连接在安卓端,不能正常识别了,那问题就很好定位了,就是安卓端有问题了?什么这么说呢???留给大家猜想吧!
安卓端主要利用 < usbManager > 类来实现的,当然了还有其他的实现方法。 首先我们需要打开usb设备
connection = usbManager.openDevice(mydevice); // 打开usb设备 if (connection == null) { // 不成功,则退出 //debug(" usb openDeivce() error."); return; }然后在获取 usb Interface 的数量,如果获取的数量小于1,那就是说获取错误,正常至少需要一个节点
if (mydevice.getInterfaceCount() != 1) { // "mydevice getInterfaceCount() error", Toast.LENGTH_SHORT).show(); return; }获取具体的节点:
my_interface = mydevice.getInterface(0); // 获取具体节点 if (my_interface == null) { //debug(" my_interface = mydevice.getInterface(0) error"); } connection.claimInterface(my_interface , true); // 独占接口然后就是开始获取当前节点的具体usb端点了:
int cnt = intf.getEndpointCount(); // 获取端点数 //如下获取的的具体端点可以根据实际的usb类型,来做进一步的赛选判断,最终选择自己想要的类型 for (int index = 0; index < cnt; index++) { UsbEndpoint ep = intf.getEndpoint(index); debug(" index = " + index); if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; // 针对主机而言,从主机 输出到设备,获取到 bulk的输出端点 对象 // Toast.makeText(getApplicationContext(), } if (ep.getDirection() == UsbConstants.USB_DIR_IN) { epIn = ep; // 针对主机而言,从设备 输出到主机 ,获取到 bulk的输入端点 对象 // Toast.makeText(getApplicationContext(), } }usb节点获取成功之后,接下来就是开始创建usb线程,来开始读取usb数据了:
// 创建线程 读取usb返回信息 usb_Msg_Thread = new usbMsgThread(connection, epIn, usbMessageHandle); // 创建线程 usb_Msg_Thread.start();然后就可以对usb来进行正常的读写操作了,主要用了如下两个方法:
int cnt = connection.bulkTransfer(epOut, buffer, length, timeout); //发送数据给下位机 int cnt = connection.bulkTransfer(epIn, InBuffer, length, timeout); // 接收数据从下位机如果安卓端的权限配置正常的话,此时就就可以正常挂在单片机啦… 如下图就是一个正常的运行实类: 如果还有不太明白的,欢迎继续给我交流哦