用户工具

站点工具


icore4tx_33
银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-07-28 gingko 初次建立




STM32CubeMX教程三十三——USBD_MSC实验


1.在主界面选择File–>New Project 或者直接点击ACCEE TO MCU SELECTOR 2.出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置 在搜索栏的下面,提供的各 种查找方式,可以选择芯片内核,型号,等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32H750IBKx。 3.配置RCC,使用外部时钟源 4.时基源选择SysTick 5.将PA10,PB7,PB8设置为GPIO_Output 6.引脚模式配置 7.配置USB_OTG_HS 8.配置USB_DEVICE 9.配置QUADAPI 引脚配置 10.时钟源设置,选择外部高速时钟源,配置为最大主频 11.工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可 IDE我们使用的是 MDK V5.27 12.点击Code Generator,进行进一步配置

  • Copy all used libraries into the project folder
  • 将HAL库的所有.C和.H都复制到所建工程中
  • 优点:这样如果后续需要新增其他外设又可能不再用STM32CubeMX的时候便会很方便
  • 缺点:体积大,编译时间很长
  • Copy only the necessary library files
  • 只复制所需要的.C和.H(推荐)
  • 优点:体积相对小,编译时间短,并且工程可复制拷贝
  • 缺点:新增外设时需要重新用STM32CubeMX导入
  • Add necessary library files as reference in the toolchain project configuration file
  • 不复制文件,直接从软件包存放位置导入.C和.H
  • 优点:体积小,比较节约硬盘空间
  • 缺点:复制到其他电脑上或者软件包位置改变,就需要修改相对应的路径
  • 自行选择方式即可

13.然后点击GENERATE CODE 创建工程 创建成功,打开工程。


实验三十三:USBD_MSC实验——虚拟U盘(SPI FLASH)

一、 实验目的与意义

  1. 了解STM32 USB SLAVE结构。
  2. 了解STM32 USB SLAVE特征。
  3. 掌握USB SLAVE MSC的使用方法。
  4. 掌握STM32 HAL库中QUADSPI属性的配置方法。
  5. 掌握KEIL MDK 集成开发环境使用方法。

二、 实验设备及平台

  1. iCore4TX 双核心板点击购买
  2. JLINK(或相同功能)仿真器。
  3. Micro USB线缆。
  4. Keil MDK 开发平台。
  5. STM32CubeMX开发平台。
  6. 装有WIN XP(及更高版本)系统的计算机。

三、 实验原理

1.SPI FLASH简介

  • 串行接口设备spi flash就是通过串行的接口进行操作的flash存储设备。flash按照内部存储结构不同,分为两种:nor flash和nand flash。这里spi flash 属于 nor flash。SPI一种通信接口。那么严格的来说SPI Flash是一种使用SPI通信的Flash,即,可能指NOR也可能是NAND。但现在大部分情况默认下人们说的SPI Flash指的是SPI NorFlash。早期Norflash的接口是parallel的形式,即把数据线和地址线并排与IC的管脚连接。但是后来发现不同容量的Norflash不能硬件上兼容(数据线和地址线的数量不一样),并且封装比较大,占用了较大的PCB板位置,所以后来逐渐被SPI(串行接口)Norflash所取代。同时不同容量的SPI Norflash管脚也兼容封装也更小。,至于现在很多人说起NORflash直接都以SPI flash来代称。
  • NorFlash根据数据传输的位数可以分为并行(Parallel,即地址线和数据线直接和处理器相连)NorFlash和串行(SPI,即通过SPI接口和处理器相连)NorFlash;区别主要就是:1、SPI NorFlash每次传输一bit位的数据,parallel连接的NorFlash每次传输多个bit位的数据(有x8和x16bit两种);2、SPI NorFlash比parallel便宜,接口简单点,但速度慢。
  • NandFlash是地址数据线复用的方式,接口标准统一(x8bit和x16bit),所以不同容量再兼容性上基本没什么问题。但是目前对产品的需求越来越小型化以及成本要求也越来越高,所以SPI NandFlash渐渐成为主流,并且采用SPI NANDFlash方案,主控也可以不需要传统NAND控制器,只需要有SPI接口接口操作访问,从而降低成本。另外SPI NandFlash封装比传统的封装也小很多,故节省了PCB板的空间。

2.MSC简介

  • MSC是一种计算机和移动设备之间的传输协议,它允许一个通用串行总线(USB)设备来访问主机的计算设备,使两者之间进行文件传输。
  • MSC的通用性和操作简单使他成为移动设备上最常见的文件系统,USB MSC并不需要任何特定的文件系统, 相反,它提供了一个简单的界面来读写接口用于访问任何硬盘驱动器。操作系统可以把MSC像本地硬盘一样格式化,并可以与他们喜欢的任何文件系统格式它,当然也可以创建多个分区。

3.原理图

  • 本实验利用SPI FLASH虚拟U盘,用USB线连接PC机与开发板,在电脑上就可以像操作普通U盘那样来操作开发板的FLASH存储设备。

四、 实验程序

1.主函数

int main(void)
{
    HAL_Init();
    SystemClock_Config();
 
    i2c.initialize();
    axp152.initialize();
    axp152.set_dcdc1(3500);//[ARM & FPGA]
    axp152.set_dcdc2(1200);//[FPGA INT]
    axp152.set_dcdc3(3300);//[DCOUT3]
    axp152.set_dcdc4(3300);//[DCOUT4]
 
    axp152.set_aldo1(3300);//[BK3]
    axp152.set_aldo2(3300);//[ALDOOUT2]
    axp152.set_dldo1(3300);//[BK0]
    axp152.set_dldo2(3300);//[BK1]
 
    HAL_Delay(200);
    MX_GPIO_Init();
    MX_QUADSPI_Init();
    MX_USB_DEVICE_Init();
    LED_ON;
    BSP_QSPI_Init();
    while (1)
    {
    }
}
 

2.QUADSPI初始化函数

本实验中QSPI我们只是用到了配置的IO,参数没有用到。

uint8_t BSP_QSPI_Init(void)
{
  QSPIHandle.Instance = QUADSPI;
   /* 调用DeInit函数重置驱动程序 */  
  if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
  {
    return QSPI_ERROR;
  }
    /* 系统级初始化 */
  BSP_QSPI_MspInit(&QSPIHandle, NULL);
  /* QSPI初始化 */
  /* 时钟预分频器设置为1,因此QSPI时钟= 240MHz /(1 + 1)= 120MHz */
  QSPIHandle.Init.ClockPrescaler     = 1;
  QSPIHandle.Init.FifoThreshold      = POSITION_VAL(W25Q64_FLASH_SIZE) - 1;
  QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_NONE;
  QSPIHandle.Init.FlashSize          = POSITION_VAL(W25Q64_FLASH_SIZE) - 1;
  QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE;
  QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
  QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
  QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
  if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
  {
    return QSPI_ERROR;
  }
  return QSPI_OK;
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(qspiHandle->Instance==QUADSPI)
  {
    /* QUADSPI时钟使能 */
    __HAL_RCC_QSPI_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOF_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    /** QUADSPI GPIO配置    
    PB6     ------> QUADSPI_BK1_NCS
    PF7     ------> QUADSPI_BK1_IO2
    PB2     ------> QUADSPI_CLK
    PD13     ------> QUADSPI_BK1_IO3
    PD12     ------> QUADSPI_BK1_IO1
    PD11     ------> QUADSPI_BK1_IO0 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_12|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  }
}

3.STORAGE_Read_HS函数

#define BLK_NBR                  0x800     //块数量
#define BLK_SIZ                  0x1000    //块大小
int8_t STORAGE_Read_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
    BSP_QSPI_Read(buf, blk_addr * BLK_SIZ, blk_len * BLK_SIZ);
    return (USBD_OK);
}

4.STORAGE_Write_HS函数

int8_t STORAGE_Write_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
    BSP_QSPI_Write(buf, blk_addr * BLK_SIZ, blk_len * BLK_SIZ);
    return (USBD_OK);
}

5.STORAGE_GetCapacity_HS函数

int8_t STORAGE_GetCapacity_HS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)//获取存储容量
{
  *block_num  = BLK_NBR;
  *block_size = BLK_SIZ;
  return (USBD_OK);
}

五、 实验步骤

  1. 把仿真器与iCore4TX的SWD调试口相连(直接相连或者通过转接器相连);
  2. 把iCore4TX通过Micro USB线与计算机相连,为iCore4TX供电;
  3. 打开Keil MDK 开发环境,并打开本实验工程;
  4. 烧写程序到iCore4TX上;
  5. 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。

六、 实验现象

  • 在“我的电脑”中可以虚拟出一个磁盘进行文件操作,如下图。

icore4tx_33.txt · 最后更改: 2022/04/01 11:30 由 sean