完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在上一节我们介绍了MM32 MCU的CDC功能,CDC简单而且常用。 本节我们来讲解如何在MM32 MCU实现U盘功能。USB大容量存储设备(英语:USB mass storage device class,也称为USB MSC或UMS)是一个协议,允许一个USB接口的设备与主计算设备相连接,以便在两者之间传输文件。对于主计算设备来说,USB设备看起来就像一个移动硬盘,允许拖放型文件传送,用 USB 线连接 PC 机与开发板,在电脑上就可以像操作普通 U 盘那样来操作开发板中的 MicroSD 卡或者SPI FLASH。它实际上是由USB实施者论坛所通过许多通讯协议的汇总,这一标准提供了许多设备的界面,包括移动硬盘、闪存盘、移动光学驱动器、读卡器、数码相机、数码音乐播放器、Pad以及手机等等。 本次我们采用MM32L373 miniboard作为测试开发板。为了方便大家使用MM32 MCU的MSC功能,我们已经封装好全部代码,用户不需要自己配置以上的那些描述符等参数,只需要知道如何处理MSC的数据接收和发送即可。 软件资源如下: 对于MM32 MCU的MSC功能来说,在使用MSC功能之前先调用USB初始化函数来初始化USB协议栈。 int main(void) { // USB Device Initialization and connect u***d_init(); u***d_connect(__TRUE); while (!u***d_configured()) // Wait for USB Device to configure { } while (1) { …… if (flags & FLAGS_MAIN_90MS) { vfs_mngr_periodic(90); // FLAGS_MAIN_90MS } …… } } 在MM32 MCU 的MSC功能里面,增加了一个虚拟FAT,用户不需要了解,只需要了解MSC数据收发处理函数,USB数据处理函数如下: //MSC初始化函数 void u***d_msc_init(void) { sync_init(); build_filesystem(); vfs_state = VFS_MNGR_STATE_DISCONNECTED; vfs_state_next = VFS_MNGR_STATE_DISCONNECTED; time_u***_idle = 0; USBD_MSC_MediaReady = 0; } //MSC读函数 void u***d_msc_read_sect(uint32_t sector, uint8_t *buf, uint32_t num_of_sectors) { sync_assert_u***_thread(); // dont proceed if we're not ready if (!USBD_MSC_MediaReady) { return; } vfs_read(sector, buf, num_of_sectors); } //虚拟文件读函数 void vfs_read(uint32_t requested_sector, uint8_t *buf, uint32_t num_sectors) { uint8_t i = 0; uint32_t current_sector; // Zero out the buffer memset(buf, 0, num_sectors * VFS_SECTOR_SIZE); current_sector = 0; for (i = 0; i < ELEMENTS_IN_ARRAY(virtual_media); i++) { uint32_t vm_sectors = virtual_media.length / VFS_SECTOR_SIZE; uint32_t vm_start = current_sector; uint32_t vm_end = current_sector + vm_sectors; // Data can be used in this sector if ((requested_sector >= vm_start) && (requested_sector < vm_end)) { uint32_t sector_offset; uint32_t sectors_to_write = vm_end - requested_sector; sectors_to_write = MIN(sectors_to_write, num_sectors); sector_offset = requested_sector - current_sector; virtual_media.read_cb(sector_offset, buf, sectors_to_write); // Update requested sector requested_sector += sectors_to_write; num_sectors -= sectors_to_write; } // If there is no more data to be read then break if (num_sectors == 0) { break; } // Move to the next virtual media entry current_sector += vm_sectors; } } //MSC写函数 void u***d_msc_write_sect(uint32_t sector, uint8_t *buf, uint32_t num_of_sectors) { sync_assert_u***_thread(); if (!USBD_MSC_MediaReady) { return; } // Restart the disconnect counter on every packet // so the device does not detach in the middle of a // transfer. time_u***_idle = 0; if (TRASNFER_FINISHED == file_transfer_state.transfer_state) { return; } // indicate msc activity vfs_write(sector, buf, num_of_sectors); if (TRASNFER_FINISHED == file_transfer_state.transfer_state) { return; } file_data_handler(sector, buf, num_of_sectors); } //虚拟文件写函数 void vfs_write(uint32_t requested_sector, const uint8_t *buf, uint32_t num_sectors) { uint8_t i = 0; uint32_t current_sector; current_sector = 0; for (i = 0; i < virtual_media_idx; i++) { uint32_t vm_sectors = virtual_media.length / VFS_SECTOR_SIZE; uint32_t vm_start = current_sector; uint32_t vm_end = current_sector + vm_sectors; // Data can be used in this sector if ((requested_sector >= vm_start) && (requested_sector < vm_end)) { uint32_t sector_offset; uint32_t sectors_to_read = vm_end - requested_sector; sectors_to_read = MIN(sectors_to_read, num_sectors); sector_offset = requested_sector - current_sector; virtual_media.write_cb(sector_offset, buf, sectors_to_read); // Update requested sector requested_sector += sectors_to_read; num_sectors -= sectors_to_read; } // If there is no more data to be read then break if (num_sectors == 0) { break; } // Move to the next virtual media entry current_sector += vm_sectors; } } 如上,我们就完成MM32 MCU的MSC功能,将程序下载到板子中,USB插上电脑,电脑上会枚举出U盘,如下显示: 图1 MM32 MCU模拟U盘属性 U盘容量可以用户自定义,在本次程序中定义U盘64M,实际容量小于MCU flash容量,用户可以选择外扩SDRAM、MicroSD 卡或者SPI FLASH等其他存储单元,可以实现大容量数据存储功能,需要用户根据实际存储外设将USB通信和存储单元进行关联操作。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2255个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11848 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5980 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11130 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4598 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4336 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1357浏览 1评论
861浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 18:23 , Processed in 0.409782 second(s), Total 36, Slave 29 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号