单片机的USB接口,通常用法,
1)HID 是Human Interface Device的缩写,由其名称可以了解HID设备是直接与人交互的设备,例如键盘、鼠标与游戏杆等。不过HID设备并不一定要有人机接口,只要符合HID类别规范的设备都是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 // 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;
上一篇:pic16f877 tm0使LED每隔10ms闪亮代码
下一篇:基于PIC单片机的24c02调试完成
推荐阅读最新更新时间:2024-10-18 04:17