首页 STM32 U盘

STM32 U盘

举报
开通vip

STM32 U盘这段时间主要在搞usb通信,先用STM32+FLASH实现u盘。在做之前,先对usb的通信协议和STM32的usb控制器进行深入的学习和理解。 在看usb2.0协议的时候,经常看到端点这个词,所以我要先把端点的含义弄懂, usb通讯的最基本形式是通过一个称为端点的东西,端点可以被看做一个单向管道。 usb端点有4种不同的类型:1、控制端点:用来控制对usb设备的不同部分访问。2、中断端点:当usb主机向设备请求数据时,中断端点以固定速率传送小量数据。3、批量端点:用来传送大量数据。4、等时端点:也是传送大量数...

STM32 U盘
这段时间主要在搞usb通信,先用STM32+FLASH实现u盘。在做之前,先对usb的通信协议和STM32的usb控制器进行深入的学习和理解。 在看usb2.0协议的时候,经常看到端点这个词,所以我要先把端点的含义弄懂, usb通讯的最基本形式是通过一个称为端点的东西,端点可以被看做一个单向管道。 usb端点有4种不同的类型:1、控制端点:用来控制对usb设备的不同部分访问。2、中断端点:当usb主机向设备请求数据时,中断端点以固定速率传送小量数据。3、批量端点:用来传送大量数据。4、等时端点:也是传送大量数据,但不被保证能送达。 同时对枚举过程也要有深入的理解,枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序。调试USB设备,很重要的一点就是USB的枚举过程,只要枚举成功了,那么就已经成功大半了。 首先,USB主机检测到USB设备插入后,就会先对设备复位。设备复位后,USB 主机就会对地址为0的设备发送获取设备描述符的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 请求。所有的USB设备在总线复位后其地址都为0,这样主机就可以跟那些刚刚插入的设备通过地址0通信。主机在建立阶段发出获取设备描述符的输入请求,设备收到该请求后,在数据过程将设备描述符返回给主机。主机在成功获取到一个数据包的设备描述符后并且确认没有什么错误后(注意:有些USB设备的端点0大小不足18字节(但至少具有8字节),而标准的设备描述有18字节,在这种情况下,USB设备只能暂时按最大包将部分设备描述符返回,而主机在成功获取到前面一部分描述符后,就不会再请求剩下的设备描述符部分,而是进入设置地址阶段),就会返回一个0长度的状态数据包给设备。 然后主机再对设备复位一下,接下来就会进入到设置地址阶段。这时USB主机发出一个设置地址的请求(建立过程,设置地址无数据过程),地址包含在建立包中,具体的地址USB主机会负责管理,它会分配一个唯一的地址给新的设备。USB设备在收到地址后,返回0长度的状态包,主机收到0长度的状态包之后,会返回一个ACK给设备。设备在收到这个ACK之后,就可以启用新的地址了。这样设备就分配到了一个唯一的设备地址,以后主机就通过它来进行访问该设备。 在开发板上已有一个简易的游戏杆,其SELECTION、DOWN、RIGHT、LEFT 和UP键分别与处理器的PD12、PD14、PE1、PE0、PD8引脚相连; 由于USB协议及接口较为复杂,MDK所带的STM32F10X的BSP包中单独提供了USB的相关函数库,需要将这些目录包含到编译路径中去。 程序的结构比较复杂,介绍一下除了库文件以及USB函数库文件之外的几个源文件函数: main.c 该函数中主要包含2个函数,其中main函数初始化系统以及USB接口,之后不断查询游戏杆是否有动作,如果有动作则根据动作向USB缓冲器发出相关数据;Delay函数用于延迟。 usb_desc.c 该文件中没有任何函数,只是包含一些定义USB设备的描述符常数,由于游戏杆是标准USB设备,因此比较容易得到相关的参数。读者若要开发非标准的USB 设备,则还需要开发PC上运行的非标准设备的驱动程序。 usb_Istr.c 该文件中只有一个函数,即USB中断的USB_Istr函数,该函数对各类引起USB 中断的事件作轮询处理。 usb_prop.c 该文件用于实现相关设备的USB协议,例如初始化、SETUP包、IN包、OUT 包等等。 usb_pwr.c 该文件中包含处理上电、调电、挂起和恢复事件的函数, hw_config.c 该文件中包含系统配置的函数,和处理游戏杆动作的函数。其中,Set_System 函数用于配置时钟、通用端口;Set_USBClock函数用于配置USB端口时钟; USB_Interrupts_Config函数用于配置USB中断;USB_Cable_Config函数配置USB电缆状态;JoyState函数用于获取游戏杆的状态;Joystick_Send用于向USB端口传送游戏杆的事件。 使用Keil uVision3,通过jlink下载程序后,按下5个键可以观察到PC机屏幕上鼠标跟随按键动作而移动,实现了功能。 再学习了usb mass storage—usb 海量存储设备。 USB 对Memory 的操作: 在MASS STORAGE 中,USB 对MEMORY 的操作是以扇区(在FAT 中,一个扇区为512 字节)为单位的,而USB 端点的最大包长为64 字节,因此要 发送或接收的数据会先放到内存,假设是CPU 向端点1 写数据,则首先从FLASH或SD 卡中读取一扇区数据,再按最大包长分8 次向USB 端点发送。如果是端点2 输出数据,则CPU 将收到的数据先放至内存,并累加,当是512 字节的整数倍时,再将数据写入FLASH 或SD。 USB 对FLASH 的操作:FLASH芯片读写操作都要以扇区为单位进行,而对FLASH进行写操作前必须把写单元所在块擦除。因此写操作时,所要擦除块的数据必须事先保存,然后再对该块进行擦除,并把数据写到指定单元,最后把其余部分恢复过来。因此FLASH芯片的写操作比较复杂,需要开辟一定的缓冲区对要擦除的块进行保存。 在向NAND FLASH写数据时。首先要把要写扇区的数据保存好,再对扇区所在的数据块进行擦除,然后把需要的数据写到指定扇区。并把数据块中其他的数据保存,对NAND FLASH的写操作有以下几个步骤:1.开辟缓冲区 2.保存数据 3.写数据 4.把缓冲区的数据恢复到原来的数据块。 由于一个块比较大(128KB),无法在MCU 内开辟如此大的缓冲区。只好借助该NANDFLASH 内的页复制命令,将原来的块暂时复制到一个交换用的交换块中。但是如果仅用一个块作为交换的话,它就会被频繁擦写,因而寿命会大大降低。所以在该系统中,保留了10 个块用来作为交换区,轮流使用。 因为NAND FLASH 在生产和使用过程中,会产生坏块,所以必须增加坏块管理。 先是系统的初始化:1.设置系统时钟 2.初始化各外设时钟3.打开需要用的外设4.中断设置5.配置IO引脚、定义IO功能6.初始化存储器7.初始化USB。 接着便是系统时钟的配置,最后就是等待usb枚举成功以及等待SD卡准备。 程序运行时,当usb产生中断后,获取中断状态,进行判断。若是正确传输中断,则执行CTR-LP( ),判断是控制端点还是非控制端点,非控制端点只有EP1 (端点1输入即写数据至端点1,要读取SD或FLASH的数据)和EP2(端点2输出即MCU读取端点的数据。再写入SD或FLASH),其中经过SCSi-data.c 文件中的函数进行数据格式转换后从SD或FLASH中读写。若写SD或FLASH 则先将接入到端点的数据包经CBW-Decode()解码后再转换格式写入。这就是U盘的数据传输的过程。 经实验测试后,在PC上可以检测到可移动磁盘,当我打开U盘时,电脑提示我要格式化磁盘。但是格式化不成功,显示U盘的大小是120MB。 这个问题一直困扰着我,为什么格式化不了呢? PC机能识别出U盘。即是证明usb枚举成功了,但是读出来的容量不对。于是我就怀疑是读写SD卡或者FLASH的那部分出问题,于是我今天先试一下单是用SPI的方式来读FLASH。 使用AT45DB161D的默认页大小528个字节,读FLASH使用主存储器页读命令(Main Memory Page Read),写FLASH使用主存储器页编程通过缓冲区1命令(Main Memory Page Program Through Buffer 1),读Flash ID的命令定义如下: #define RDID 0x9F /* Read identification */ 擦除可以扇区擦除命令定义如下: #define SE 0x7C /* Sector Erase instruction */ 也可以页擦除命令义如下: #define PE 0x81 /* Page Erase instruction */ 运行下载程序,程序首先在断点1处中断,说明Flash ID校验通过,如下图所示: AT45DB161D的Flash ID为0x1F260000,如下图所示。 在第2个断点处中断,查看缓冲区Rx_Buffer与Tx_Buffer一致说明写入成功。在断点3处中断后,TransferStatus1 = 0x01说明Flash读写校验通过。 在断点4处中断后,变量TransferStatus2的值依旧为0x01说明,擦除成功读出全为0xFF。 实验成功,能用SPI的方式读写FLASH芯片AT45DB161D。 结果还是一样,连SD卡的容量都还没读出来,那肯定格式化失败啦。我下载了一个单独的读写SD卡校验程序,然后单步进行调试,结果读写都正常,这就让我开始觉得有点眉目了,应该是SD卡部分的程序出了问题,一下子范围就缩小了很多。 先分析一下读磁盘容量的过程,其实就是PC机通过通道(端点)发送一个包含读磁盘容量命令的数据包CBW,控制器将数据包通过CBW-Decode()函数进行解码并将固件分派为相应的SCSI命令。判断后,执行读磁盘容量函数,其中获取磁盘容量MAL-GetStatue()是关键,因为对SD卡的操作在里面进行。我在这个函数里面设断点进行单步调试,发现了SD卡的初始化失败了,所以便无法获取SD卡的信息,但奇怪的是我下载单独的SD卡校验程序初始化也没问题啊,为什么这里不成功。我就对比了一下SD-Init()这个函数。结果发现里面的SD-PowerON函数不一样,原来是控制时钟的配置不同,导致了命令响应超时。修改完以后,下载一试,果然不但能识别U盘,而且显示容量为982MB, 把一些文件拷贝进去也完全没问题。U盘终于实现了。 花了一整个星期的时间去查资料学习usb,终于在红牛的开发板上实现了U盘。
本文档为【STM32 U盘】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_995397
暂无简介~
格式:doc
大小:20KB
软件:Word
页数:0
分类:理学
上传时间:2019-09-19
浏览量:28