stm32 usb和安卓手机的通讯过程

stm32 usb和安卓手机端的通讯流程

前段时间公司开发了一个安卓外设,主要是用某宝淘来的demo 在stm32F103的usb功能来和安卓设备的usb来通讯
叙述之前先来一个整体的框图吧:
stm32 usb和安卓手机的通讯过程_第1张图片

需要准备的设备有:

①.安卓手机或者安卓pad,(手机必须支持otg功能,否则就得用host功能了
②.otg转接线或者转接头
③.安卓数据线(一定要是能通讯数据的线缆,有些山寨的这个线只有2根线,没有数据线
④.带有usb功能的单片机(这个usb需要能支持用户自行定义

接下来就开始捣鼓stm32单片机的程序了,下面是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(请在继续修改);

在pc的设备管理器里可以查看usb是否正常如下图:

(如果出现感叹号之类的要进一步排除是不是驱动没安装好,这个demo是需要一个专门的驱动程序的)
stm32 usb和安卓手机的通讯过程_第2张图片

单片机端如果修改没问题了,然后在来安卓端开刀…

如果这个时候连接在安卓端,不能正常识别了,那问题就很好定位了,就是安卓端有问题了?什么这么说呢???留给大家猜想吧!

安卓端主要利用 < 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); // 接收数据从下位机

如果安卓端的权限配置正常的话,此时就就可以正常挂在单片机啦…
如下图就是一个正常的运行实类:
stm32 usb和安卓手机的通讯过程_第3张图片如果还有不太明白的,欢迎继续给我交流哦

你可能感兴趣的:(stm32 usb和安卓手机的通讯过程)