久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4980|回復: 5
收起左側

PIC單片機USB MSC的應用:PC 利用 MMC/SD 卡作為儲存設備進行讀寫

[復制鏈接]
ID:406093 發表于 2018-10-30 18:10 | 顯示全部樓層 |閱讀模式
本帖最后由 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 卡進行讀/寫數據的簡單測試程序。希望大家能夠喜歡。
USB MSC.jpg
讓PC認為 MMC/SD 卡作為儲存設備 (Storage) 進行運作
主程序:
  1. /*
  2. * Project name:
  3.      MassStorageDevice.vtft
  4. * Generated by:
  5.      Visual TFT
  6. * Description:
  7.      Example using EasyPIC Fusion v7 board as mass storage device. Before using it, insert microSD card
  8.      in the card slot on EasyPIC Fusion v7 board and plug usb cable to connect with PC.
  9.      After connection with PC, mikromedia is detected as mass storage device wich size is
  10.      size of microSD card inserted.
  11. * Test configuration:
  12.      MCU:             P18F87J50
  13.      Dev.Board:       MikroMMB_for_PIC18FJ_hw_rev_1.10_9A
  14.                       http://www.mikroe.com/mikromedia/pic18fj/
  15.      Oscillator:      HS-PLL, 48.000MHz
  16.      SW:              mikroC PRO for PIC
  17.                       http://www.mikroe.com/mikroc/pic/
  18. */

  19. #include "__Lib_USB_Device.h"

  20. // MMC module connections
  21. sbit Mmc_Chip_Select           at LATD0_bit;  // for writing to output pin always use latch
  22. sbit Mmc_Chip_Select_Direction at TRISD0_bit;
  23. // eof MMC module connections

  24. void interrupt(){
  25.   USBDev_IntHandler();
  26. }

  27. void main() {

  28.   PLLEN_bit = 1;
  29.   Delay_ms(150);
  30.   WDTCON.B4 = 1;
  31.   ANCON0 = 0xF0; // All pins to digital
  32.   ANCON1 = 0xFF;
  33.   WDTCON.B4 = 0;

  34.   SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);

  35.   USBDev_MSCInit();
  36.   USBDev_Init();

  37.   IPEN_bit = 1;
  38.   USBIP_bit = 1;
  39.   USBIE_bit = 1;
  40.   GIEH_bit = 1;

  41.   while(1){
  42.     USBDev_MSCMain();
  43.   }

  44. }
復制代碼
MMC/SD卡驅動程序:
  1. #include <stdint.h>

  2. // Mode sense data
  3. static const uint8_t MODE_SENSE_6_DATA[8] = {
  4.   0x00,
  5.   0x00,
  6.   0x00,
  7.   0x00,
  8.   0x00,
  9.   0x00,
  10.   0x00,
  11.   0x00
  12. };


  13. // Standard Inquiry Data
  14. static const uint8_t STD_INQUIRY_DATA[36] = {
  15.   0x00, // Direct access block device
  16.   0x80, // RMB bit set to one indicates that the medium is removable
  17.   0x00, // ISO(7..6) ECMA(5..3) ANSI(2..0) Version
  18.   0x02, // Response Data Format
  19.   0x1F, // Additional length (31)
  20.   0x00, // Reserved
  21.   0x00, // Reserved
  22.   0x00, // Reserved
  23.   'M', 'I', 'K', 'R', 'O', 'E', ' ', ' ', // Vendor Information
  24.   'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product identification
  25.   'F', 'l', 'a', 's', 'h', ' ', ' ', ' ',
  26.   '1', '.', '0', '0'                      // Product Revision Level n.nn
  27. };

  28. // USB Mass storage Page 0 Inquiry Data
  29. static const uint8_t UNIT_SERIAL_NUMBER[7] = {
  30.   0x00, // Peripheral qualifier[7..5] device type[4..0]
  31.   0x80, // Page Code 80h
  32.   0x00, // Reserved
  33.   0x03, // Page Length
  34.   0x00, // Product Serial Nnumber
  35.   0x00,
  36.   0x00
  37. };

  38. static uint8_t tmpStorageBuff[36];

  39. // Storage callbacks
  40. static uint8_t StorageInit();
  41. static uint8_t StorageIsReady();
  42. static uint8_t StorageIsWriteProtected();
  43. static uint8_t StorageGetCapacity(uint32_t* blockNum, uint32_t *blockSize);
  44. static uint8_t StorageRead(uint8_t *buffer, uint32_t lba, uint16_t blockNum);
  45. static uint8_t StorageWrite(uint8_t *buffer, uint32_t lba, uint16_t blockNum);
  46. static uint8_t* StorageGetInquiryData(uint8_t vpd);
  47. static uint8_t* StorageGetStdInquiryData();
  48. static uint8_t* StorageGetModeSenseData();

  49. typedef struct {
  50.   uint8_t(*StorageInit)();
  51.   uint8_t(*StorageIsReady)();
  52.   uint8_t(*StorageIsWriteProtected)();
  53.   uint8_t(*StorageGetCapacity)(uint32_t *blockNum, uint32_t * blockSize);
  54.   uint8_t(*StorageRead) (uint8_t *buffer, uint32_t lba, uint16_t blockNum);
  55.   uint8_t(*StorageWrite)(uint8_t *buffer, uint32_t lba, uint16_t blockNum);
  56.   uint8_t * (*StorageGetInquiryData)(uint8_t vpd);
  57.   uint8_t * (*StorageGetStdInquiryData)();
  58.   uint8_t * (*StorageGetModeSenseData)();
  59. } TMSCStorageCB;

  60. TMSCStorageCB USBDev_MSCStorageCB = {
  61.   StorageInit,
  62.   StorageIsReady,
  63.   StorageIsWriteProtected,
  64.   StorageGetCapacity,
  65.   StorageRead,
  66.   StorageWrite,
  67.   StorageGetInquiryData,
  68.   StorageGetStdInquiryData,
  69.   StorageGetModeSenseData
  70. };

  71. // STORAGE IMPLEMENTATION

  72. static void StorageConstToRam(const uint8_t* fromBuffer, uint8_t* toBuffer, uint16_t len){
  73.   uint16_t i;
  74.   for(i = 0; i < len; i++){
  75.     toBuffer[i] = fromBuffer[i];
  76.   }
  77. }

  78. ////////////////////////////////////////////////////////////////////////////////
  79. // This is a wrapper for retrieving number of sector device implements.
  80. // It is used to get sector count of the device (for fat formatting purpose,
  81. // assumed sector size is 512 bytes).

  82. // MMC GetMmcSectorCount return codes
  83. static const uint8_t  MMC_OK     =   0,
  84.                       MMC_ERROR  =   255;
  85.                      
  86. static uint8_t GetMmcSectorCount(uint32_t *scCnt)
  87. {
  88.     uint8_t  csdbuf[16];
  89.     uint16_t c_size, c_size_mult, mult,
  90.            read_bl_len, block_len;
  91.     uint32_t size, blocknr;

  92.     // determine MMC/SD card size in MB
  93.     if (Mmc_Read_Csd(csdbuf) != MMC_OK)
  94.     {
  95.         return MMC_ERROR;
  96.     }

  97.     // is it version 2.0?
  98.     if (1 == ((csdbuf[0] & 0xC0) >> 6))
  99.     {
  100.         size  = 0;                  size <<= 8;
  101.         size += csdbuf[7] & 0x3F;   size <<= 8;
  102.         size += csdbuf[8];          size <<= 8;
  103.         size += csdbuf[9];          size <<= 0;

  104.         // size is in 0.5MB, get size in sectors (assumed 512 bytes sector size)
  105.         size *= 1024;
  106.     }
  107.     // if not, it's version 1.xx
  108.     else
  109.     {
  110.         c_size      = ((csdbuf[8] & 0xC0) >> 6) +
  111.                       ((unsigned) csdbuf[7] << 2) +
  112.                       (((unsigned) csdbuf[6] & 0x03) << 10);
  113.         c_size_mult = (csdbuf[10] & 0x80) +
  114.                       (((unsigned) csdbuf[9] & 0x03) << 8);
  115.         c_size_mult = c_size_mult >> 7;

  116.         read_bl_len = csdbuf[5] & 0x0f;

  117.         mult = 1;
  118.         mult = mult << (c_size_mult + 2);

  119.         blocknr = (c_size + 1) * (long) mult;
  120.         block_len = 1;
  121.         block_len = block_len << read_bl_len;

  122.         size = block_len * blocknr;

  123.         // size is in 1B, get size in sectors (assumed 512 bytes sector size)
  124.         size /= 512;
  125.     }

  126.     *scCnt = size;

  127.     return MMC_OK;
  128. }

  129. static uint8_t  storageInitStatus;   // storage initializtion status
  130. // Initializing storage
  131. static uint8_t StorageInit() {
  132.   // initialize a MMC card
  133.   storageInitStatus = Mmc_Init();
  134.   return storageInitStatus;
  135. }

  136. // Get storage capacity, number of blocks and block size
  137. static uint8_t StorageGetCapacity(uint32_t* blockNum, uint32_t *blockSize) {
  138.   GetMmcSectorCount(blockNum);
  139.   *blockSize = 512;
  140.   return 0;
  141. }

  142. // Read storage to buffer
  143. static uint8_t StorageRead(uint8_t *buffer, uint32_t lba, uint16_t blockNum) {
  144.   uint8_t status;
  145.   status = 0;
  146.   Mmc_Multi_Read_Start(lba);
  147.   while (blockNum) {
  148.     Mmc_Multi_Read_Sector(buffer);
  149.     buffer += 512;
  150.     blockNum--;
  151.   }
  152.   Mmc_Multi_Read_Stop();
  153.   return status;
  154. }

  155. // Return storage status
  156. static uint8_t StorageIsReady() {
  157.   if(storageInitStatus)
  158.     return 0; // storage is not ready
  159.   else
  160.     return 1;  // storage is ready
  161. }

  162. // Write to storage
  163. static uint8_t StorageWrite(uint8_t *buffer, uint32_t lba, uint16_t blockNum) {
  164.   uint8_t status;
  165.   status = 0;
  166.   while (blockNum) {
  167.     status |= Mmc_Write_Sector(lba, buffer);
  168.     lba++;
  169.     buffer += 512;
  170.     blockNum--;
  171.   }
  172.   return status;
  173. }

  174. // Get storage protection status
  175. static uint8_t StorageIsWriteProtected() {
  176.   return 0;
  177. }

  178. // Return storage inquiry data
  179. static uint8_t* StorageGetInquiryData(uint8_t vpd) {
  180.   StorageConstToRam(UNIT_SERIAL_NUMBER, tmpStorageBuff, 7);
  181.   return tmpStorageBuff;
  182. }

  183. // Get standard inquiry data
  184. static uint8_t* StorageGetStdInquiryData() {
  185.   StorageConstToRam(STD_INQUIRY_DATA, tmpStorageBuff, 36);
  186.   return tmpStorageBuff;
  187. }

  188. // Get mode sense data
  189. static uint8_t* StorageGetModeSenseData() {
  190.   StorageConstToRam(MODE_SENSE_6_DATA, tmpStorageBuff, 8);
  191.   return tmpStorageBuff;
  192. }

  193. // END OF STORAGE IMPLEMENTATION
復制代碼

USB MSC 驅動程序:
  1. #include <stdint.h>

  2. const uint8_t  _USB_MSC_MANUFACTURER_STRING[]  = "MikroElektronika";
  3. const uint8_t  _USB_MSC_PRODUCT_STRING[]       = "Mass Storage by Mikroe";
  4. const uint8_t  _USB_MSC_SERIALNUMBER_STRING[]  = "0x00000002";
  5. const uint8_t  _USB_MSC_CONFIGURATION_STRING[] = "Mass Storage Config Desc string";
  6. const uint8_t  _USB_MSC_INTERFACE_STRING[]     = "Mass Storage mscInterface Desc string";

  7. const uint8_t  _USB_MSC_STR_DESC_SIZE          = 4;
  8. const uint16_t _USB_MSC_STR_DESC_LANGID        = 0x409;

  9. const uint8_t _USB_MSC_CONFIG_DESC_SIZ  = 32;   // Configuration descriptor size
  10. const uint8_t _USB_MSC_PACKET_MAX_SIZE  = 64;   // Max packet size for endpoint
  11. const uint8_t _USB_MSC_IN_EP_NUM  = 1;          // IN endpoint number
  12. const uint8_t _USB_MSC_OUT_EP_NUM = 1;          // OUT endpoint number

  13. //String Descriptor Zero, Specifying Languages Supported by the Device
  14. const uint8_t USB_MSC_LangIDDesc[_USB_MSC_STR_DESC_SIZE] = {
  15.   _USB_MSC_STR_DESC_SIZE,
  16.   _USB_DEV_DESCRIPTOR_TYPE_STRING,
  17.   _USB_MSC_STR_DESC_LANGID & 0xFF,
  18.   _USB_MSC_STR_DESC_LANGID >> 8,
  19. };


  20. // device descriptor
  21. const uint8_t USB_MSC_device_descriptor[] = {
  22.   0x12, // bLength
  23.   0x01, // bDescriptorType
  24.   0x00, // bcdUSB
  25.   0x02,
  26.   0x00, // bDeviceClass
  27.   0x00, // bDeviceSubClass
  28.   0x00, // bDeviceProtocol
  29.   0x40, // bMaxPacketSize0
  30.   0x00, // idVendor
  31.   0x00,
  32.   0x02, // idProduct
  33.   0x00,
  34.   0x00, // bcdDevice
  35.   0x02,
  36.   0x01, // iManufacturer
  37.   0x02, // iProduct
  38.   0x03, // iSerialNumber
  39.   0x01  // bNumConfigurations

  40. };

  41. // Configuration descriptor with all interfaces and endpoints
  42. // descriptors for all of the interfaces
  43. const uint8_t USB_MSC_cfg_descriptor[_USB_MSC_CONFIG_DESC_SIZ] = {
  44.   // Configuration descriptor
  45.   0x09,                                   // bLength: Configuration Descriptor size
  46.   _USB_DEV_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType: Configuration
  47.   _USB_MSC_CONFIG_DESC_SIZ & 0xFF,        // wTotalLength: Bytes returned
  48.   _USB_MSC_CONFIG_DESC_SIZ >> 8,
  49.   0x01,                                   // bNumInterfaces: 1 interface
  50.   0x01,                                   // bConfigurationValue: Configuration value
  51.   0x04,                                   // iConfiguration: Index of string descriptor describing the configuration
  52.   0xC0,                                   // bmAttributes: self powered
  53.   0x32,                                   // MaxPower 100 mA: maximum power consuption of the device

  54.   // Mass Storage interface
  55.   0x09,                                   // bLength: interface descriptor size
  56.   0x04,                                   // bDescriptorType: interface descriptor type
  57.   0x00,                                   // bInterfaceNumber: Number of Interface
  58.   0x00,                                   // bAlternateSetting: Alternate setting
  59.   0x02,                                   // bNumEndpoints: Number of endpoints
  60.   0x08,                                   // bInterfaceClass: MSC
  61.   0x06,                                   // bInterfaceSubClass : SCSI transparent
  62.   0x50,                                   // nInterfaceProtocol
  63.   0x05,                                   // iInterface: Index of string descriptor

  64.   // Mass Storage Endpoints
  65.   0x07,                                   // bLength: Endpoint Descriptor size
  66.   _USB_DEV_DESCRIPTOR_TYPE_ENDPOINT,      // bDescriptorType: endpoint descriptor type

  67.   0x80 | _USB_MSC_IN_EP_NUM,              // bEndpointAddress: Endpoint Address (IN)
  68.   0x02,                                   // bmAttributes: Bulk endpoint
  69.   _USB_MSC_PACKET_MAX_SIZE,               // wMaxPacketSize: maximum packet size for endpoint
  70.   0x00,
  71.   0x00,                                   // bInterval: Polling Interval

  72.   0x07,                                   // bLength: Endpoint Descriptor size
  73.   _USB_DEV_DESCRIPTOR_TYPE_ENDPOINT,      // bDescriptorType: endpoint descriptor type
  74.   _USB_MSC_OUT_EP_NUM,                    // bEndpointAddress: Endpoint Address (OUT)
  75.   0x02,                                   // bmAttributes: Bulk endpoint
  76.   _USB_MSC_PACKET_MAX_SIZE,               // wMaxPacketSize: maximum packet size for endpoint
  77.   0x00,
  78.   0x00                                    // bInterval
  79. };
復制代碼

詳細內容,請參考:http://www.zg4o1577.cn/bbs/dpj-138111-1.html


回復

使用道具 舉報

ID:419199 發表于 2018-11-1 16:15 | 顯示全部樓層
樓主有完整的代碼分享嗎?我點了詳細內容轉成另一個帖子了。
回復

使用道具 舉報

ID:419199 發表于 2018-11-1 16:16 | 顯示全部樓層
樓主,求完整代碼
回復

使用道具 舉報

ID:406093 發表于 2018-11-4 20:11 | 顯示全部樓層
這個就是詳細代碼,連接的內容你仔細再看看。不知道你是用哪一種PIC單片機。8 位?16位?或者32位?
回復

使用道具 舉報

ID:419199 發表于 2018-11-5 13:46 | 顯示全部樓層
oldspring 發表于 2018-11-4 20:11
這個就是詳細代碼,連接的內容你仔細再看看。不知道你是用哪一種PIC單片機。8 位?16位?或者32位?

我用的是pic18f67j94,就是在主程序里面的所調用的USB函數只有函數名,求樓主分享函數內容,USBDev_IntHandler()、USBDev_MSCMain();
回復

使用道具 舉報

ID:419199 發表于 2018-11-5 13:50 | 顯示全部樓層
oldspring 發表于 2018-11-4 20:11
這個就是詳細代碼,連接的內容你仔細再看看。不知道你是用哪一種PIC單片機。8 位?16位?或者32位?

點擊詳細內容就會轉到:推薦一款PIC單片機編譯器
回復

使用道具 舉報

ID:406093 發表于 2018-11-6 09:38 | 顯示全部樓層
如果你使用的是8位單片機,仔細看MikroE公司的8位編譯器,在該軟件的Help里面有詳細說明。MikroE的函數只支持他們的編譯器。函數的內部Code也是不公開的。Microchip單片機的USB模塊技術是非常成熟的,如果你希望寫自己的USB函數,無論是CDC,HID或者MSC,都可以參考Microchip的相關Datasheet,應該不是很困難的,只是很費時間。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久精品69 | 日韩欧美国产精品综合嫩v 一区中文字幕 | 久久亚洲国产精品日日av夜夜 | 欧美一级黄色片在线观看 | 五月婷婷在线播放 | 欧美精品一区二区在线观看 | 国产精品久久影院 | 91国产视频在线观看 | 久久99蜜桃综合影院免费观看 | 日韩视频在线免费观看 | 一区二区三区国产在线观看 | 免费精品| 最新超碰 | 久久精品成人一区 | 久操亚洲 | av片在线免费看 | 欧美精品在线看 | a久久久久久 | 欧美精品一区二区三区在线 | 欧美国产精品 | 国产一二区视频 | 黄色网络在线观看 | 精品一级电影 | 一级毛片在线播放 | 亚洲网站在线观看 | 久久草在线视频 | 国产视频一二三区 | av大全在线观看 | 国产精品视频入口 | 国产午夜精品久久久久 | 成人深夜小视频 | 在线国产中文字幕 | 超碰在线观看97 | 国产目拍亚洲精品99久久精品 | 免费天天干 | 国产精品二区三区在线观看 | 日韩在线欧美 | 国产视频中文字幕在线观看 | 精品粉嫩aⅴ一区二区三区四区 | 国产性网 | 久久亚洲国产精品日日av夜夜 |