前段时间公司开发了一个安卓外设,主要是用某宝淘来的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); // 接收数据从下位机
如果安卓端的权限配置正常的话,此时就就可以正常挂在单片机啦…
如下图就是一个正常的运行实类:
如果还有不太明白的,欢迎继续给我交流哦