PIC单片机USB MSC的应用:用 MMC/SD 卡作为储存设备进行读写

发布者:RainbowJoy最新更新时间:2019-11-06 来源: 51hei关键字:PIC单片机  USB  MSC  储存设备  读写 手机看文章 扫描二维码
随时随地手机看文章

单片机的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 卡进行读/写数据的简单测试程序。希望大家能够喜欢。

USB MSC.jpg 

让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;

[1] [2]
关键字:PIC单片机  USB  MSC  储存设备  读写 引用地址:PIC单片机USB MSC的应用:用 MMC/SD 卡作为储存设备进行读写

上一篇:pic16f877 tm0使LED每隔10ms闪亮代码
下一篇:基于PIC单片机的24c02调试完成

推荐阅读最新更新时间:2024-10-18 04:17

PIC单片机USB MSC的应用:用 MMC/SD 卡作为储存设备进行读写
单片机的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等储存卡读卡器,数码相机,手机等等。 .......... 注意: 每
[单片机]
<font color='red'>PIC单片机</font><font color='red'>USB</font> <font color='red'>MSC</font>的应用:用 MMC/SD 卡作为<font color='red'>储存</font><font color='red'>设备</font>进行<font color='red'>读写</font>
如何利用PIC16F877A单片机读写AT24C系列储存
AT24C系列在增强型PIC实验板上编程的硬件原理图如下图所示,U7为实验板上24C02芯片,SDA与单片机的RB5口相连,SCL与单片机RB4相连,七段数码管D5、D7、D8组成了显示单元,字形码的数据通过RC口送入,各数码管的显示片选信号分别不同的RA口进行控制。 在MPLab IDE软件中新建工程,加入源程序代码,同时进行芯片型号的选择和配置位的设置,我们实验所用的芯片型号为PIC16F877A。 编写的程序代码如下,其中程序流程图如下图所示。 软件代码 编好程序后将编译好的HEX码通过ICD2仿真烧写器烧入单片机芯片,上电运行,主程序中在O×01地址写入了“O×55”,在O×0
[单片机]
如何利用PIC16F877A单片机<font color='red'>读写</font>AT24C系列<font color='red'>储存</font>器
PS5主机首次重大更新推出:支持外接的USB硬盘储存游戏
PlayStation宣布,PS5 主机的首次重大系统更新将在今日于全球推出,内含许多新功能与改进。以下为 PS5、PS4 和 PlayStation App 的新内容: PS5 储存空间扩充和管理 ●将 PS5 游戏储存至相容的外接式 USB 硬盘。有了此功能,您便可将 PS5 游戏从主机的内接式储存空间传输至 USB 扩充储存空间。这是扩充您 PS5 主机储存容量的绝佳方式,当您准备要游玩时,便可顺畅地将 PS5 游戏复制回主机的内接式储存空间。从 USB 扩充储存空间重新安装 PS5 游戏,速度比从光碟重新下载或复制更快。 ●由于PS5游戏旨在利用游戏机的超高速 SSD,目前无法从 USB 扩充储存空间游玩 PS
[手机便携]
STM32 基础系列教程 26 - USB_MSC
前言 学习stm32 USB接口使用,学会用CUBE工具快速创建USB设备工程及调试,关于usb的相关知道请读者提前准备并学习,当然如果不想深究其中原理的话,跟着本文来操作就可以实现基于USB的设备开发了。需要提示的是,stm32在使用usb接口功能是一般需要在DP引脚上上拉一个1.5K电阻到3.3V(部分MCU内部会上拉)。 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。 本示例所用的最小系统板原理图: 从本节开始,关于CUBEMX工具及KEIL工具的操作将不再细讲,如
[单片机]
STM32 基础系列教程 26 - <font color='red'>USB</font>_<font color='red'>MSC</font>
美高森美推出新款SAS/SATA配接器 储存设备效能增
美高森美(Microsemi)日前正式发布其全新智能型储存SAS/SATA配接器,内含完整印刷电路板层级解决方案,以及自定义嵌入式解决方案的Silicon Plus软件。整个产品组合包括美高森美Adaptec HBA 1100系列、SmartHBA 2100系列和SmartRAID 3100系列,皆采用该公司最新的28奈米SmartIOC 2100和SmartROC 3100储存控制器集成电路(IC ),专为各种服务器储存应用提供高效能、低耗电量、高可靠性、多功能的解决方案,适合软件定义储存(SDS)、冷储存和企业应用。 美高森美可扩展储存事业部产品管理及策略总监Mark Orthodoxou表示,目前中国所生产的服务器已经是全球
[半导体设计/制造]
PIC单片机对9346EEPROM数据的读写
实验目的:熟悉SPI总线以及9346EEPROM的读写 ;RBO键按下时把DATA和DATA2写入到EEPROM中以EE—ADDR为地址的单元内, ;完成后,单个数码观显示“9”做为完成标志 ;RB1键按下时,读取EEPROM中以EE—ADDR为地址的单元,并送数码管显示 ;硬件要求:S3、S5、S6拨码管置ON,S1第7、8位置ON。 LIST P=16F877A, R=DEC include “P16F877A.inc” ;包含头文件 __CONFIG _DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWR TE _ON&_WDT_OFF&_HS_OSC
[单片机]
<font color='red'>PIC单片机</font>对9346EEPROM数据的<font color='red'>读写</font>
PIC单片机对9346EEPROM程序的读写设计
由于在使用时,找了很久也没找到相关的程序,因此把自己后来编写的程序贴出来,希望能给后来者借鉴参考!;实验目的:熟悉SPI总线以及9346EEPROM的读写 ;RBO键按下时把DATA和DATA2写入到EEPROM中以EE—ADDR为地址的单元内, ;完成后,单个数码观显示“9”做为完成标志 ;RB1键按下时,读取EEPROM中以EE—ADDR为地址的单元,并送数码管显示 ;硬件要求:S3、S5、S6拨码管置ON,S1第7、8位置ON。 LIST P=16F877A, R=DEC include “P16F877A.inc” ;包含头文件 __CONFIG _DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_
[单片机]
<font color='red'>PIC单片机</font>对9346EEPROM程序的<font color='red'>读写</font>设计
PIC单片机读写93C46程序
; THIS ROUTE IS USED FOR 93C46 (Configue as ; 16 bits organizaTIo) READ & WRITE ROUTE RA EQU 5 RB EQU 6 BIT-COUNT EQU DATA_HI EQU 10H ; HI half of words DATA_LO EQU 11H ; LO half of words ROM_AD EQU 12H ; the address of 93c46 TEMR EQU 13H ; BIT_COUNT EQU 14H ; CM_EWEN EQU 30H CM_EWDS EQU 0H ;RA CS EQU 0 SK EQU 1 DI
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved