行情
HOME
行情
正文内容
nand flash fsmc usb 「正点原子STM32Mini板资料连载」第三十九章 USB 读卡器实验
发布时间 : 2025-02-25
作者 : 小编
访问数量 : 23
扫码分享至微信

「正点原子STM32Mini板资料连载」第三十九章 USB 读卡器实验

1)实验平台:正点原子STM32mini开发板2)摘自《正点原子 STM32 不完全手册(HAL 库版) 关注官方微信号公众号,获取更多资料:正点原子

第三十九章 USB 读卡器实验

上一章我们向大家介绍了如何利用 STM32 的 USB 来做一个触控 USB 鼠标,本章我们将利

用 STM32 的 USB 来做一个 USB 读卡器。本章分为如下几个部分:

39.1 USB 读卡器简介

39.2 硬件设计

39.3 软件设计

39.4 下载验证

39.1 USB 读卡器简介

ALIENTEK MiniSTM32 开发板板载了一个 SD 卡插槽,可以用来接入 SD 卡,另外

MiniSTM32 开发板板载了一个 8M 字节的 SPI FLASH 芯片,通过 STM32 的 USB 接口,我们可

以实现一个简单的 USB 读卡器,来读写 SD 卡和 SPI FLASH。

本章我们还是通过移植官方的 USB Mass_Storage 例程来实现,该例程在 STSW-STM32121\

STM32_USB-FS-Device_Lib_V4.0.0\Projects\Mass_Storage 下可以找到(STSW-STM32121 是官

方的 USB 库压缩包,在光盘:8,STM32 参考资料\STM32 USB 学习资料文件夹下),注意这

里并非完全照搬官网的例程,有部分代码是被我们修改过的,以支持我们的应用。

USB Mass Storage 类支持两个传输协议:

1)Bulk-Only 传输(BOT)

2)Control/Bulk/Interrupt 传输(CBI)

Mass Storage 类规范定义了两个类规定的请求:Get_Max_LUN 和 Mass Storage Reset,所有

的 Mass Storage 类设备都必须支持这两个请求。

Get_Max_LUN(bmRequestType= 10100001b and bRequest= 11111110b)用来确认设备支持

的逻辑单元数。Max LUN 的值必须是 0~15。注意:LUN 是从 0 开始的。主机不能向不存在的

LUN 发送 CBW,本章我们定义 Max LUN 的值为 1,即代表 2 个逻辑单元。

Mass Storage Reset(bmRequestType=00100001b and bRequest= 11111111b)用来复位 Mass

Storage 设备及其相关接口。

支持 BOT 传输的 Mass Storage 设备接口描述符要求如下:

接口类代码 bInterfaceClass=08h,表示为 Mass Storage 设备;

接口类子代码 bInterfaceSubClass=06h,表示设备支持 SCSI Primary Command-2(SPC-2);

协议代码 bInterfaceProtocol 有 3 种:0x00、0x01、0x50,前两种需要使用中断传输,最后

一种仅使用批量传输(BOT)。

支持 BOT 的设备必须支持最少 3 个 endpoint:Control, Bulk-In 和 Bulk-Out。USB2.0 的规

范定义了控制端点 0。Bulk-In 端点用来从设备向主机传送数据(本章用端点 1 实现)。Bulk-Out

端点用来从主机向设备传送数据(本章用端点 2 实现)。

ST 官方的例程是通过 USB 来读写 SD 卡(SDIO 方式)和 NAND FALSH,支持 2 个逻辑

单元,我们在官方例程的基础上,只需要修改 SD 驱动部分代码(改为 SPI),并将对 NAND

FLASH 的操作修改为对 SPI FLASH 的操作。只要这两步完成了,剩下的就比较简单了,对底

层磁盘的读写,都是在 mass_mal.c 文件实现的,所以我们只需要修改该函数的 MAL_Init、

MAL_Write、MAL_Read 和 MAL_GetStatus 等 4 个函数,使之与我们的 SD 卡和 SPI FLASH 对

应起来即可。

本章我对 SD 卡和 SPI FLASH 的操作都是采用 SPI 方式,所以速度相对 SDIO 和 FSMC 控

制的 NAND FLASH 来说,相对会慢一些。

39.2 硬件设计

本节实验功能简介:开机的时候先检测 SD 卡和 SPI FLASH 是否存在,如果存在则获取其

容量,并显示在 LCD 上面(如果不存在,则报错)。之后开始 USB 配置,在配置成功之后就

可以在电脑上发现两个可移动磁盘。我们用 DS1 来指示 USB 正在读写 SD 卡,并在液晶上显

示出来,同样我们还是用 DS0 来指示程序正在运行。

所要用到的硬件资源如下:

1) 指示灯 DS0 、DS1

2) 串口

3) TFTLCD 模块

4) SD 卡

5) SPI FLASH

6) USB 接口

这几个部分,在之前的实例中都已经介绍过了,我们在此就不多说了。不过还是要注意一

下 P13 的连接,要和上一章一样!

39.3 软件设计

本章,我们在第三十三章(实验 28)的基础上修改,首先打开实验 28 的工程,在

HARDWARE 文件夹所在的文件夹下新建一个 USB 的文件夹,并拷贝官方 USB 驱动库相关代

码到该文件夹下即拷贝:en.stm32cubef1\STM32Cube_FW_F1_V1.8.0\Middlewares\ST 文件夹下

的 STM32_USB_Device_Library 文件夹到该文件夹下面。

然后,在 USB 文件夹下面新建 CONFIG 文件夹,用来存放 USB 读卡器实现的相关代码,

拷贝自:STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Applications\USB_Device\

MSC_Standalone 文件夹。注意:部分代码是有修改的,并非完全照抄官方代码,具体代码我们

就不细说了(详见光盘本例程源码)。

最后,在 main.c 里面,我们修改 main 函数如下:

extern vu8 USB_STATUS_REG;

//USB 状态

extern vu8 bDeviceState;

//USB 连接 情况

extern USBD_HandleTypeDef hUsbDeviceFS;

int main(void)

{

u8 offline_cnt=0;

u8 tct=0; u8 USB_STA; u8 Divece_STA;

HAL_Init();

//初始化 HAL 库

Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M

delay_init(72);

//初始化延时函数

uart_init(115200);

//初始化串口

LED_Init();

//初始化 LED

LCD_Init();

//初始化 LCD

W25QXX_Init();

//初始化 W25Q64

mem_init();

//初始化内存池

POINT_COLOR=RED;

//设置字体为红色

LCD_ShowString(30,50,200,16,16,"Mini STM32");

LCD_ShowString(30,70,200,16,16,"USB Card Reader TEST");

LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

LCD_ShowString(30,110,200,16,16,"2019/11/16");

if(SD_Init())//SD 卡初始化

LCD_ShowString(30,130,200,16,16,"SD Card Error!");

//检测 SD 卡错误

else //SD 卡正常

{

LCD_ShowString(30,130,200,16,16,"SD Card Size: MB");

Mass_Memory_Size[1]=(long long)SD_GetSectorCount()*512;

//得到 SD 卡容量(字节),当 SD 卡容量超过 4G 的时候,需要用到两个 u32 来表示

Mass_Block_Size[1] =512;//因为我们在 Init里面设置了 SD 卡的操作字节为 512 个,

//所以这里一定是 512 个字节.

Mass_Block_Count[1]=Mass_Memory_Size[1]/Mass_Block_Size[1];

LCD_ShowNum(134,130,Mass_Memory_Size[1]>>20,5,16); //显示 SD 卡容量

}

if(W25QXX_TYPE!=W25Q64)

LCD_ShowString(30,150,200,16,16,"W25Q64 Error!");

//检测 W25Q64 错误

else //SPI FLASH 正常

{

Mass_Memory_Size[0]=4916*1024;//前 4.8M 字节

Mass_Block_Size[0] =512;//因为我们在 Init里面设置了 SD 卡的操作字节为 512 个,

//所以这里一定是 512 个字节.

Mass_Block_Count[0]=Mass_Memory_Size[0]/Mass_Block_Size[0];

LCD_ShowString(30,150,200,16,16,"SPI FLASH Size:4916KB");

}

LCD_ShowString(30,170,200,16,16,"USB Connecting...");//提示 USB 开始连接

USB_Reset();

MX_USB_DEVICE_Init();//usb 初始化

LCD_ShowString(30,190,200,16,16,"USB inited...");

delay_ms(1800);

while(1)

{

delay_ms(1);

if(USB_STA!=USB_STATUS_REG)//状态改变了

{

LCD_Fill(30,190,240,190+16,WHITE);//清除显示

if(USB_STATUS_REG&0x01)//正在写

{

LCD_ShowString(30,190,200,16,16,"USB Writing...");

//提示 USB 正在写入数据

}

if(USB_STATUS_REG&0x02)//正在读

{

LCD_ShowString(30,190,200,16,16,"USB Reading...");

//提示 USB 正在读出数据

}

if(USB_STATUS_REG&0x04)

LCD_ShowString(30,210,200,16,16,"USB Write Err ");//提示写入错误

else

LCD_Fill(30,210,240,210+16,WHITE);//清除显示

if(USB_STATUS_REG&0x08)

LCD_ShowString(30,230,200,16,16,"USB Read Err ");//提示读出错误

else LCD_Fill(30,230,240,230+16,WHITE);//清除显示

USB_STA=USB_STATUS_REG;//记录最后的状态

}

if(Device_STA!=USB_GetStatus())

{

Device_STA = USB_GetStatus();//记录新的状态

if(Device_STA==USBD_STATE_CONFIGURED)

{

POINT_COLOR=BLUE;

LCD_ShowString(30,170,200,16,16,"USB Connected ");

//提示 USB 连接成功

} else

{

POINT_COLOR=RED;

LCD_ShowString(30,170,200,16,16,"USB disConnected ");//提示 USB 断开

}

}

tct++;

if(tct==200)

{

tct=0;

LED0=!LED0;//提示系统在运行

if(USB_STATUS_REG&0x10)

{

offline_cnt=0;//USB 连接了,则清除 offline 计数器

bDeviceState=USBD_STATE_CONFIGURED;

} else//没有得到轮询

{

offline_cnt++;

if(offline_cnt>10)

{

bDeviceState=USBD_STATE_SUSPENDED;

//2s 内没收到在线标记,代表 USB 被拔出了

}

}

USB_STATUS_REG=0;

}

}

}

在 main 函数里面,我们将 SPI FLASH 的最开始 4.8M 地址范围用作 SPI FLASH Disk,也

就是文件系统管理的范围大小,这个我们在之前的 FATFS 也介绍过。

通过此部分代码就可以实现了我们之前在硬件设计部分描述的功能,这里我们用到了一个

全局变量 USB_STATUS_REG,用来标记 USB 的相关状态,这样我们就可以在液晶上显示当前

USB 的状态了。软件设计部分就为大家介绍到这里。

39.4 下载验证

在代码编译成功之后,我们通过下载代码到 MiniSTM32 开发板上,在 USB 配置成功后(假

设已经插入 SD 卡,注意:USB 数据线,要插在开发板侧面的 USB 口!不是 USB_232 端口!),

LCD 显示效果如图 39.4.1 所示:

图 39.4.1 USB 连接成功

此时,电脑提示发现新硬件如图 39.4.2 所示:

图 39.4.2 USB 读卡器被电脑找到

等 USB 配置成功后,DS1 不亮,DS0 闪烁,并且在电脑上可以看到我们的磁盘,如图 39.4.3

所示:

图 39.4.3 电脑找到 USB 读卡器的两个盘符

我们打开设备管理器,在通用串行总线控制器里面可以发现多出了一个 USB Mass Storage

Device,同时看到磁盘驱动器里面多了 2 个磁盘,如图 39.4.4 所示:

图 39.4.4 通过设备管理器查看磁盘驱动器

此时,我们就可以通过电脑读写 SD 卡或者 SPI FLASH 里面的内容了。在执行读写操作的

时候,就可以看到 DS1 亮,并且会在液晶上显示当前的读写状态。

注意,在对 SPI FLASH 操作的时候,最好不要频繁的往里面写数据,否则很容易将 SPI

FLASH 写爆!!

如何使用MM32F3270单片机FSMC驱动外部NOR Flash

在某些应用中,需要较大容量的存储空间用于存储数据;可以通过SPI 外扩NOR Flash,NAND Flash, 或者通过SDIO扩展SD Card或TF-Card。但有些需要高速存储数据,上述方式还是不够快速,这时可以使用MM32F3270系列的FSMC来外扩并行NOR Flash来实现。 并行NOR Flash与并行SRAM和PSRAM的读写接口大部分相同,但NOR Flash的写入速度与SRAM和PSRAM比较,相对较慢,需要通过NWAIT 信号检查NOR Flash的操作状态,并做一些等待,相应的时序需要根据不同的NOR Flash芯片所规定的参数而做相应的设置即可。

FSMC控制器外部信号

结合MM32F3270 的FSMC外部接口信号,可使用异步方式访问Nor Flash,可以选用复用或非复用方式扩展NOR Flash,还可以通过配置实现外扩8位总线或16位总线接口的NOR Flash。

MM32F3270不同封装芯片与NOR Flash接口

MM32F3270系列MCU因为封装的原因,导致只有部分MCU产品可以通过硬件复用出全部或部分的FSMC接口的相关GPIO;外扩NOR Flash也只有使用 LQFP144引脚封装MCU芯片才能支持连接地址数据非复用和复用方式外扩并行NOR Flash;而LQFP100引脚封装芯片因地址线缩减,仅支持连接地址数据复用方式外扩并行NOR Flash。LQFP64因为无法引出足够的地址与数据总线,同样不支持外扩并行NOR Flash。目前市场上非复用型16位数据总线接口的NOR Flash也是较为普遍。 灵动微电子是本土领先的通用32位MCU产品及解决方案供应商。MCU产品以MM32为标识,基于Arm Cortex-M系列内核,自主研发软硬件和生态系统。代理商英尚微为客户提供从硬件芯片到软件算法、从参考方案全方位支持。

相关问答

nor flash 可以使用ubifs吗?

1.可以使用UBIFS。2.NORFlash是一种非易失性存储器,而UBIFS是一种用于闪存设备的文件系统。UBIFS可以在NORFlash上运行,因为它是为闪存设备设计的,可以提...

flash 插件是什么东西 - HM5xR9DT 的回答 - 懂得

场景式动画制作和播放软件什么是FLASHFLASH有三重意义:1)FLASH英文本意为“闪光”;2)它是全球流行的电脑动画设计软件;3)它代表用上述软件制作的流...

flash 的技术和特点?

FLASH的技术和特点如下:1.使用矢量图形和流式播放技术。与位图图形不同的是,矢量图形可以任意缩放尺寸而不影响图形的质量;流式播放技术使得动画可以边播放...

新买的U盘应注意些什么问题,怎么用?

以文件备份到闪盘后,应过一些时间再关闭相关程序,以防意外;同样道理,在系统提示“无法停止”时也不要轻易拔出U盘,这样也会造成数据遗失。注意将U盘放置在...

rtos能上文件系统吗?

rtos用的文件系统,根据设备介质,分为几种:1.RAM上文件系统RAMFS,ROMFS2.SPIFLASH/SDCARD上文件系统为fatfs,spiffs,RelianceEdge...

求助:谁能帮我看看这overflash是什么意思?-盖德问答-化工人...

overflash的意思其实已经用英文解释了,overflashisthevaporizationofcrudeoverandabovethecrudeoverheadand...

flash 中文字为什么要执行两次“分离”命令? - nWthM7 Fs 6K 的...

比如“大家好”如果只按一次分离,会分成三个字“大”“家”“好”他们还是文字不是图形所以,第二次分离就是将分开的三个字再分别打散一次现在就都...

电脑能联接网络 但是不能看视频-ZOL问答

(1)首先检查电话线有无问题(可以拨一个电话测试),如果正常,接着检查信号分频器是否连接正常(其中电话线接Line口,电话机接Phone口,ADSLModem接Modem口)。(2)...

装完系统后提示grub,该怎么处理?谢谢。-ZOL问答

另外,如果能够进入现在的系统或开机时按F8能够进入命令行模式,可搜索WINDOWS版或DOS版的GHOST.exe程序和GHO系统文件,然后手工运行GHOST程序装载系统GHO文件也能...

如何烧写u-boot到SD卡?

1.安装SD卡格式化工具3.把SD卡通过读卡器接入PC4.运行HPUSBFW工具,会扫描到您的SD卡注意:请确认HPUSBFW工具扫描到的SD卡就是您的...1....

 返乡潮  龙岗玫瑰海岸 
王经理: 180-0000-0000(微信同号)
10086@qq.com
北京海淀区西三旗街道国际大厦08A座
©2025  上海羊羽卓进出口贸易有限公司  版权所有.All Rights Reserved.  |  程序由Z-BlogPHP强力驱动
网站首页
电话咨询
微信号

QQ

在线咨询真诚为您提供专业解答服务

热线

188-0000-0000
专属服务热线

微信

二维码扫一扫微信交流
顶部