| **银杏科技有限公司旗下技术文档发布平台** ||||
|技术支持电话|**0379-69926675-801**|||
|技术支持邮件|Gingko@vip.163.com|||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^
| V1.0 | 2020-03-14 | gingko | 初次建立 |
\\
\\
\\
===== STM32CubeMX教程三十三——USBD_MSC实验 =====
\\
1.在主界面选择File-->New Project 或者直接点击ACCEE TO MCU SELECTOR
{{ :icore4t:icore4t_cube_33_1.png?direct |}}
2.出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置
在搜索栏的下面,提供的各 种查找方式,可以选择芯片内核,型号,等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32H750IBKx。
{{ :icore4t:icore4t_cube_33_2.png?direct |}}
3.配置RCC,使用外部时钟源
{{ :icore4t:icore4t_cube_33_3.png?direct |}}
4.时基源选择SysTick
{{ :icore4t:icore4t_cube_33_4.png?direct |}}
5.将PA10,PB7,PB8设置为GPIO_Output
{{ :icore4t:icore4t_cube_33_5.png?direct |}}
6.引脚模式配置
{{ :icore4t:icore4t_cube_33_6.png?direct |}}
{{ :icore4t:icore4t_cube_33_7.png?direct |}}
7.配置USB_OTG_HS
{{ :icore4t:icore4t_cube_33_8.png?direct |}}
8.配置USB_DEVICE
{{ :icore4t:icore4t_cube_33_9.png?direct |}}
9.配置QUADAPI
{{ :icore4t:icore4t_cube_33_10.png?direct |}}
引脚配置
{{ :icore4t:icore4t_cube_33_11.png?direct |}}
10.时钟源设置,选择外部高速时钟源,配置为最大主频
{{ :icore4t:icore4t_cube_33_12.png?direct |}}
{{ :icore4t:icore4t_cube_33_13.png?direct |}}
11.工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可 IDE我们使用的是 MDK V5.27
{{ :icore4t:icore4t_cube_33_14.png?direct |}}
12.点击Code Generator,进行进一步配置
{{ :icore4t:icore4t_cube_33_15.png?direct |}}
* **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 创建工程
{{ :icore4t:icore4t_cube_33_16.png?direct |}}
创建成功,打开工程。
\\
\\
\\
===== 实验三十三:USBD_MSC实验——虚拟U盘(SPI FLASH) =====
==== 一、 实验目的与意义 ====
- 了解STM32 USB SLAVE结构。
- 了解STM32 USB SLAVE特征。
- 掌握USB SLAVE MSC的使用方法。
- 掌握STM32 HAL库中QUADSPI属性的配置方法。
- 掌握KEIL MDK 集成开发环境使用方法。
==== 二、 实验设备及平台 ====
- iCore4T 双核心板。
- JLINK(或相同功能)仿真器。
- Micro USB线缆。
- Keil MDK 开发平台。
- STM32CubeMX开发平台。
- 装有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.原理图 ===
{{ :icore4t:icore4t_arm_hal_33_1.png?direct |}}
{{ :icore4t:icore4t_arm_hal_33_2.png?direct |}}
* 本实验利用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 BK1/2/6 &OTHER]
axp152.set_dcdc2(1200);//[FPGA INT & PLL D]
axp152.set_aldo1(2500);//[FPGA PLL A]
axp152.set_dcdc4(3300);//[POWER_OUTPUT]
axp152.set_dcdc3(3300);//[FPGA BK4][Adjustable]
axp152.set_aldo2(3300);//[FPGA BK3][Adjustable]
axp152.set_dldo1(3300);//[FPGA BK7][Adjustable]
axp152.set_dldo2(3300);//[FPGA BK5][Adjustable]
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);
}
==== 五、 实验步骤 ====
- 把仿真器与iCore4T的SWD调试口相连(直接相连或者通过转接器相连);
- 把iCore4T通过Micro USB线与计算机相连,为iCore4T供电;
- 打开Keil MDK 开发环境,并打开本实验工程;
- 烧写程序到iCore4T上;
- 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。
==== 六、 实验现象 ====
* 在“我的电脑”中可以虚拟出一个磁盘进行文件操作,如下图。
{{ :icore4t:icore4t_arm_hal_32_3.png?direct |}}