本帖最后由 oldspring 于 2018-10-30 18:11 編輯
單片機的USB接口,通常用法, 1)HID 是Human Interface Device的縮寫,由其名稱可以了解HID設備是直接與人交互的設備,例如鍵盤、鼠標與游戲桿等。不過HID設備并不一定要有人機接口,只要符合HID類別規范的設備都是HID設備。(參考百度 https://baike.baidu.com/item/USB-HID)
2)CDC 虛擬串口,可與PC機直接聯機通訊,如同RS232。
3)USB MSC (Mass Storage class) MSC是一種計算機和移動設備之間的傳輸協議,它允許一個通用串行總線(USB)設備來訪問主機的計算設備,使兩者之間進行文件傳輸。設備包括:移動硬盤,移動光驅,U盤,SD、TF等儲存卡讀卡器,數碼相機,手機等等。 ..........
注意: 每一個USB設備,都需要一個獨立的身份編碼 (ID),它由 2 組數字組成,一個是開發商代碼(Vender ID),另一個是產品代碼(Product ID)。如果是PIC使用者,可以向Microchip公司申請獲得免費的身份編碼。
USB MSC 的應用與前面介紹的USB CDC 和 USB HID 相比較,USB MSC 的內容比較多,需要多花一些時間。 以下介紹一個簡單的從USB接口對 MMC/SD 卡進行讀/寫數據的簡單測試程序。希望大家能夠喜歡。 讓PC認為 MMC/SD 卡作為儲存設備 (Storage) 進行運作 主程序: - /*
- * Project name:
- MassStorageDevice.vtft
- * Generated by:
- Visual TFT
- * Description:
- Example using EasyPIC Fusion v7 board as mass storage device. Before using it, insert microSD card
- in the card slot on EasyPIC Fusion v7 board and plug usb cable to connect with PC.
- After connection with PC, mikromedia is detected as mass storage device wich size is
- size of microSD card inserted.
- * Test configuration:
- MCU: P18F87J50
- Dev.Board: MikroMMB_for_PIC18FJ_hw_rev_1.10_9A
- http://www.mikroe.com/mikromedia/pic18fj/
- Oscillator: HS-PLL, 48.000MHz
- SW: mikroC PRO for PIC
- http://www.mikroe.com/mikroc/pic/
- */
- #include "__Lib_USB_Device.h"
- // MMC module connections
- sbit Mmc_Chip_Select at LATD0_bit; // for writing to output pin always use latch
- sbit Mmc_Chip_Select_Direction at TRISD0_bit;
- // eof MMC module connections
- void interrupt(){
- USBDev_IntHandler();
- }
- void main() {
- PLLEN_bit = 1;
- Delay_ms(150);
- WDTCON.B4 = 1;
- ANCON0 = 0xF0; // All pins to digital
- ANCON1 = 0xFF;
- WDTCON.B4 = 0;
- SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
- USBDev_MSCInit();
- USBDev_Init();
- IPEN_bit = 1;
- USBIP_bit = 1;
- USBIE_bit = 1;
- GIEH_bit = 1;
- while(1){
- USBDev_MSCMain();
- }
- }
復制代碼 MMC/SD卡驅動程序:
- #include <stdint.h>
- // Mode sense data
- static const uint8_t MODE_SENSE_6_DATA[8] = {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00
- };
- // Standard Inquiry Data
- static const uint8_t STD_INQUIRY_DATA[36] = {
- 0x00, // Direct access block device
- 0x80, // RMB bit set to one indicates that the medium is removable
- 0x00, // ISO(7..6) ECMA(5..3) ANSI(2..0) Version
- 0x02, // Response Data Format
- 0x1F, // Additional length (31)
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- 'M', 'I', 'K', 'R', 'O', 'E', ' ', ' ', // Vendor Information
- 'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product identification
- 'F', 'l', 'a', 's', 'h', ' ', ' ', ' ',
- '1', '.', '0', '0' // Product Revision Level n.nn
- };
- // USB Mass storage Page 0 Inquiry Data
- static const uint8_t UNIT_SERIAL_NUMBER[7] = {
- 0x00, // Peripheral qualifier[7..5] device type[4..0]
- 0x80, // Page Code 80h
- 0x00, // Reserved
- 0x03, // Page Length
- 0x00, // Product Serial Nnumber
- 0x00,
- 0x00
- };
- static uint8_t tmpStorageBuff[36];
- // Storage callbacks
- static uint8_t StorageInit();
- static uint8_t StorageIsReady();
- static uint8_t StorageIsWriteProtected();
- static uint8_t StorageGetCapacity(uint32_t* blockNum, uint32_t *blockSize);
- static uint8_t StorageRead(uint8_t *buffer, uint32_t lba, uint16_t blockNum);
- static uint8_t StorageWrite(uint8_t *buffer, uint32_t lba, uint16_t blockNum);
- static uint8_t* StorageGetInquiryData(uint8_t vpd);
- static uint8_t* StorageGetStdInquiryData();
- static uint8_t* StorageGetModeSenseData();
- typedef struct {
- uint8_t(*StorageInit)();
- uint8_t(*StorageIsReady)();
- uint8_t(*StorageIsWriteProtected)();
- uint8_t(*StorageGetCapacity)(uint32_t *blockNum, uint32_t * blockSize);
- uint8_t(*StorageRead) (uint8_t *buffer, uint32_t lba, uint16_t blockNum);
- uint8_t(*StorageWrite)(uint8_t *buffer, uint32_t lba, uint16_t blockNum);
- uint8_t * (*StorageGetInquiryData)(uint8_t vpd);
- uint8_t * (*StorageGetStdInquiryData)();
- uint8_t * (*StorageGetModeSenseData)();
- } TMSCStorageCB;
- TMSCStorageCB USBDev_MSCStorageCB = {
- StorageInit,
- StorageIsReady,
- StorageIsWriteProtected,
- StorageGetCapacity,
- StorageRead,
- StorageWrite,
- StorageGetInquiryData,
- StorageGetStdInquiryData,
- StorageGetModeSenseData
- };
- // STORAGE IMPLEMENTATION
- static void StorageConstToRam(const uint8_t* fromBuffer, uint8_t* toBuffer, uint16_t len){
- uint16_t i;
- for(i = 0; i < len; i++){
- toBuffer[i] = fromBuffer[i];
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // This is a wrapper for retrieving number of sector device implements.
- // It is used to get sector count of the device (for fat formatting purpose,
- // assumed sector size is 512 bytes).
- // MMC GetMmcSectorCount return codes
- static const uint8_t MMC_OK = 0,
- MMC_ERROR = 255;
-
- static uint8_t GetMmcSectorCount(uint32_t *scCnt)
- {
- uint8_t csdbuf[16];
- uint16_t c_size, c_size_mult, mult,
- read_bl_len, block_len;
- uint32_t size, blocknr;
- // determine MMC/SD card size in MB
- if (Mmc_Read_Csd(csdbuf) != MMC_OK)
- {
- return MMC_ERROR;
- }
- // is it version 2.0?
- if (1 == ((csdbuf[0] & 0xC0) >> 6))
- {
- size = 0; size <<= 8;
- size += csdbuf[7] & 0x3F; size <<= 8;
- size += csdbuf[8]; size <<= 8;
- size += csdbuf[9]; size <<= 0;
- // size is in 0.5MB, get size in sectors (assumed 512 bytes sector size)
- size *= 1024;
- }
- // if not, it's version 1.xx
- else
- {
- c_size = ((csdbuf[8] & 0xC0) >> 6) +
- ((unsigned) csdbuf[7] << 2) +
- (((unsigned) csdbuf[6] & 0x03) << 10);
- c_size_mult = (csdbuf[10] & 0x80) +
- (((unsigned) csdbuf[9] & 0x03) << 8);
- c_size_mult = c_size_mult >> 7;
- read_bl_len = csdbuf[5] & 0x0f;
- mult = 1;
- mult = mult << (c_size_mult + 2);
- blocknr = (c_size + 1) * (long) mult;
- block_len = 1;
- block_len = block_len << read_bl_len;
- size = block_len * blocknr;
- // size is in 1B, get size in sectors (assumed 512 bytes sector size)
- size /= 512;
- }
- *scCnt = size;
- return MMC_OK;
- }
- static uint8_t storageInitStatus; // storage initializtion status
- // Initializing storage
- static uint8_t StorageInit() {
- // initialize a MMC card
- storageInitStatus = Mmc_Init();
- return storageInitStatus;
- }
- // Get storage capacity, number of blocks and block size
- static uint8_t StorageGetCapacity(uint32_t* blockNum, uint32_t *blockSize) {
- GetMmcSectorCount(blockNum);
- *blockSize = 512;
- return 0;
- }
- // Read storage to buffer
- static uint8_t StorageRead(uint8_t *buffer, uint32_t lba, uint16_t blockNum) {
- uint8_t status;
- status = 0;
- Mmc_Multi_Read_Start(lba);
- while (blockNum) {
- Mmc_Multi_Read_Sector(buffer);
- buffer += 512;
- blockNum--;
- }
- Mmc_Multi_Read_Stop();
- return status;
- }
- // Return storage status
- static uint8_t StorageIsReady() {
- if(storageInitStatus)
- return 0; // storage is not ready
- else
- return 1; // storage is ready
- }
- // Write to storage
- static uint8_t StorageWrite(uint8_t *buffer, uint32_t lba, uint16_t blockNum) {
- uint8_t status;
- status = 0;
- while (blockNum) {
- status |= Mmc_Write_Sector(lba, buffer);
- lba++;
- buffer += 512;
- blockNum--;
- }
- return status;
- }
- // Get storage protection status
- static uint8_t StorageIsWriteProtected() {
- return 0;
- }
- // Return storage inquiry data
- static uint8_t* StorageGetInquiryData(uint8_t vpd) {
- StorageConstToRam(UNIT_SERIAL_NUMBER, tmpStorageBuff, 7);
- return tmpStorageBuff;
- }
- // Get standard inquiry data
- static uint8_t* StorageGetStdInquiryData() {
- StorageConstToRam(STD_INQUIRY_DATA, tmpStorageBuff, 36);
- return tmpStorageBuff;
- }
- // Get mode sense data
- static uint8_t* StorageGetModeSenseData() {
- StorageConstToRam(MODE_SENSE_6_DATA, tmpStorageBuff, 8);
- return tmpStorageBuff;
- }
- // END OF STORAGE IMPLEMENTATION
復制代碼
USB MSC 驅動程序:- #include <stdint.h>
- const uint8_t _USB_MSC_MANUFACTURER_STRING[] = "MikroElektronika";
- const uint8_t _USB_MSC_PRODUCT_STRING[] = "Mass Storage by Mikroe";
- const uint8_t _USB_MSC_SERIALNUMBER_STRING[] = "0x00000002";
- const uint8_t _USB_MSC_CONFIGURATION_STRING[] = "Mass Storage Config Desc string";
- const uint8_t _USB_MSC_INTERFACE_STRING[] = "Mass Storage mscInterface Desc string";
- const uint8_t _USB_MSC_STR_DESC_SIZE = 4;
- const uint16_t _USB_MSC_STR_DESC_LANGID = 0x409;
- const uint8_t _USB_MSC_CONFIG_DESC_SIZ = 32; // Configuration descriptor size
- const uint8_t _USB_MSC_PACKET_MAX_SIZE = 64; // Max packet size for endpoint
- const uint8_t _USB_MSC_IN_EP_NUM = 1; // IN endpoint number
- const uint8_t _USB_MSC_OUT_EP_NUM = 1; // OUT endpoint number
- //String Descriptor Zero, Specifying Languages Supported by the Device
- const uint8_t USB_MSC_LangIDDesc[_USB_MSC_STR_DESC_SIZE] = {
- _USB_MSC_STR_DESC_SIZE,
- _USB_DEV_DESCRIPTOR_TYPE_STRING,
- _USB_MSC_STR_DESC_LANGID & 0xFF,
- _USB_MSC_STR_DESC_LANGID >> 8,
- };
- // device descriptor
- const uint8_t USB_MSC_device_descriptor[] = {
- 0x12, // bLength
- 0x01, // bDescriptorType
- 0x00, // bcdUSB
- 0x02,
- 0x00, // bDeviceClass
- 0x00, // bDeviceSubClass
- 0x00, // bDeviceProtocol
- 0x40, // bMaxPacketSize0
- 0x00, // idVendor
- 0x00,
- 0x02, // idProduct
- 0x00,
- 0x00, // bcdDevice
- 0x02,
- 0x01, // iManufacturer
- 0x02, // iProduct
- 0x03, // iSerialNumber
- 0x01 // bNumConfigurations
- };
- // Configuration descriptor with all interfaces and endpoints
- // descriptors for all of the interfaces
- const uint8_t USB_MSC_cfg_descriptor[_USB_MSC_CONFIG_DESC_SIZ] = {
- // Configuration descriptor
- 0x09, // bLength: Configuration Descriptor size
- _USB_DEV_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType: Configuration
- _USB_MSC_CONFIG_DESC_SIZ & 0xFF, // wTotalLength: Bytes returned
- _USB_MSC_CONFIG_DESC_SIZ >> 8,
- 0x01, // bNumInterfaces: 1 interface
- 0x01, // bConfigurationValue: Configuration value
- 0x04, // iConfiguration: Index of string descriptor describing the configuration
- 0xC0, // bmAttributes: self powered
- 0x32, // MaxPower 100 mA: maximum power consuption of the device
- // Mass Storage interface
- 0x09, // bLength: interface descriptor size
- 0x04, // bDescriptorType: interface descriptor type
- 0x00, // bInterfaceNumber: Number of Interface
- 0x00, // bAlternateSetting: Alternate setting
- 0x02, // bNumEndpoints: Number of endpoints
- 0x08, // bInterfaceClass: MSC
- 0x06, // bInterfaceSubClass : SCSI transparent
- 0x50, // nInterfaceProtocol
- 0x05, // iInterface: Index of string descriptor
- // Mass Storage Endpoints
- 0x07, // bLength: Endpoint Descriptor size
- _USB_DEV_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType: endpoint descriptor type
- 0x80 | _USB_MSC_IN_EP_NUM, // bEndpointAddress: Endpoint Address (IN)
- 0x02, // bmAttributes: Bulk endpoint
- _USB_MSC_PACKET_MAX_SIZE, // wMaxPacketSize: maximum packet size for endpoint
- 0x00,
- 0x00, // bInterval: Polling Interval
- 0x07, // bLength: Endpoint Descriptor size
- _USB_DEV_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType: endpoint descriptor type
- _USB_MSC_OUT_EP_NUM, // bEndpointAddress: Endpoint Address (OUT)
- 0x02, // bmAttributes: Bulk endpoint
- _USB_MSC_PACKET_MAX_SIZE, // wMaxPacketSize: maximum packet size for endpoint
- 0x00,
- 0x00 // bInterval
- };
復制代碼
詳細內容,請參考: http://www.zg4o1577.cn/bbs/dpj-138111-1.html
|