从STM32F103到ACM32F403的U盘程序移植工程

发布者:WhisperingWinds最新更新时间:2024-05-11 来源: elecfans关键字:STM32F103 手机看文章 扫描二维码
随时随地手机看文章

前言

本项目是以SPI Flash(如W25Q128等)存储元件作为存储单元,MCU主控完成USB接口通信并根据SCSI协议实现U盘功能。其结构如下图所示:

pYYBAGHEE_WAeyirAAAcvPlG0h4753.png

SPI Flash部分移植

SPI功能部分相对简单,ACM32F403的接口引脚和STM32F103的相同,可直接对接,按照ACM32F403的说明对SPI接口进行初始化,并对底层读写函数进行更改即可。

USB部分移植

1. STM32F103代码结构

在ST的芯片上,USB的数据是由两个中断,USB_LP_CAN1_RX0_IRQHandler和USB_HP_CAN1_TX_IRQHandler来进行,其中高优先级中断(USB_HP_CAN1_TX_IRQHandler)用于处理同步(Isochronous)模式传输或双缓冲块(Bulk)传输模式下的正确传输事件,而低优先级中断(USB_LP_CAN1_RX0_IRQHandler)用于处理其他传输时间。ST的USB数据处理如下图所示:

poYBAGHEFBSAABCJAAGBMBY2Rik368.png

由于USBFS协议的限制,一包数据中最多可携带64字节数据,因此,当存在大量数据需要进行传输(IN或OUT包)时,需要分批次进行传输。在ST的代码中,通过变量“Bot_State”来进行控制,以Read10指令为例,其读数据流程可如下图所示:

poYBAGHEFCiAPj79AAIZklrheBo449.png

需要注意的是,Read10指令解析完成之后(即上图左侧流程图)则进入数据传输阶段,此阶段是通过多次进入USB高优先级中断中,调用Read_Memory();来实现的。Read_Memory();函数内每次传输64字节数据。

2. ACM32F403代码移植要点

本文基于上海航芯官方USB例程进行移植,移植后的程序结构如下图所示:

poYBAGHEFDuAcaoMAADWiksCJaQ150.png

ACM32F403的USB是采用一个中断来进行数据处理。在官方例程中,USB的中断函数内判定接收数据类型,包括suspend,resume,reset,EP0_pack以及其他端点的接收数据。判定结束后,会调用USB_Monitor();函数来处理suspend,resume,reset以及EP0_pack数据。而其他端点数据会在usb_transfer_monitor();函数中进行解析,该函数由客户调用,一般在主函数的死循环中进行处理。在本文的移植中,主要需对USB的端点数据进行处理。

A. EP0_Pack

EP0接收的setup数据会被存放在SETIP_0_3_DATA和SETIP_4_7_DATA寄存器中 ,数据结构如下所示:

dev_req.bmRequestType=USBCTRL->SETIP_0_3_DATA &0xff;

dev_req.bRequest=(USBCTRL->SETIP_0_3_DATA>>8)&0xff;

dev_req.wValue=(USBCTRL->SETIP_0_3_DATA>>16)&0xffff;

dev_req.wIndex = USBCTRL->SETIP_4_7_DATA&0xffff;

dev_req.wLength=(USBCTRL->SETIP_4_7_DATA>>16)&0xffff;

该部分解析,可由用户在函数void usb_control_transfer(void)中添加需要的处理函数。该函数由航芯官方例程里提供。在做U Disk程序移植时,需添加GetMaxLun和Storage_Reset处理函数,如下图所示:

pYYBAGHEFEmAeQ_4AAAXy3Fvpe4520.png

B. EP1_Pack

在本文所述的代码中,ACM32F403采用EP1完成数据的收发工作。主要是完成对SCSI协议的解析工作。移植过程中,需要文件mass_mal.c、memory.c、scsi_data.c、usb_scsi.c、usb_bot.c及其头文件。本段主要就上述文件中代码需要改动的地方进行说明,部分参数需要重新定义,读者可自行解决。下表列出了ST和Aisino的USB收发功能函数,该部分移植时需要修改的主要部分:

pYYBAGHEFFaAZ_OdAAGrUNCnfJM199.png

a. void Mass_Storage_In (void)

在ST的工程代码中该部分主要用于处理SCSI的读指令。由于全速USB一包数据最大支持64字节,因此,当需要传输的数据个数大于该数值时,则需要分包传输。在使用ACM32F403时,可直接传送需要的数据长度,内部会进行分包处理,因此,该函数可省略。

b. void Mass_Storage_Out (void)

该函数用于处理SCSI指令解析以及发送指令,需在usb_transfer_monitor()中调用,并将函数内部的接收数据部分更改为:

“Data_Len = HAL_FSUSB_Receive_Data(Bulk_Data_Buff, 64, out_ep_index, 1);”

c.void Transfer_Data_Request(uint8_t* Data_Pointer, uint16_t Data_Len)

将USB发送函数更改为ACM32F403对应的发送函数。在ST的工程中,该函数用于传输完数据后,进入BOT_DATA_IN_LAST状态,并在下一次的Mass_Storage_In()函数调用时,回复CSW指令。而本文的移植代码中,省略了Mass_Storage_In()函数,因此,可在该函数的尾部增加CSW发送指令:

Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);

d.void Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission)

将USB发送函数更改为ACM32F403对应的发送函数。

e.void Bot_Abort(uint8_t Direction)

该函数主要对收发端点的STALL状态进行处理,在ACM32F403的收发库函数中,对端点的STALL已做出相应控制,因此,该函数可省略。

f.void Read_Memory(uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length)

Read_Memory函数用于收到PC端的IN包请求后将存储器中的数据读取并发送至PC端。而ACM32F403的USB发送库函数中,自行进行分包操作(一包最大数据为64字节),因此在数据缓冲区容量允许条件下,可直接发送完毕,该函数修改如下:

{

uint32_t Offset, Length;

Offset = Memory_Offset * Mass_Block_Size[lun];

Length = Transfer_Length * Mass_Block_Size[lun];

CSW.dDataResidue = CBW.dDataLength;

while(Transfer_Length --)

{

MAL_Read(lun ,

Offset ,

Data_Buffer,

Mass_Block_Size[lun]);

Length = min(Mass_Block_Size[lun], CSW.dDataResidue);

Offset += Mass_Block_Size[lun];

HAL_FSUSB_Send_Data((uint8_t *)(Data_Buffer), Length, in_ep_index);

CSW.dDataResidue -= Length;

}

Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);

}

g.void Write_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length)

写数据指令完成后,将Bot_State 值更改为 BOT_IDLE。ST的工程代码中,变量“Bot_State”收发状态机的状态值,其值如下表所示:

poYBAGHEFHCARKM7AAInEow6Qbw876.png

而基于ACM32F403的U Disk工程,IN包可由函数HAL_FSUSB_Send_Data()在其内部进行分包处理,不需要额外逻辑,因此,移植后Bot_State仅需要在BOT_IDLE、BOT_DATA_OUT、BOT_ERROR之间转换,其他对Bot_State的控制可省略。


关键字:STM32F103 引用地址:从STM32F103到ACM32F403的U盘程序移植工程

上一篇:基于STM32的远程预付费电能监测系统设计
下一篇:基于STM32的磁导航自主导引车通用驱动器设计

推荐阅读最新更新时间:2024-11-11 14:16

Proteus8.8版本+ STM32F103驱动LCD1602显示程序+按键+ADC+串口
STM32F103仿真驱动点亮LCD1602 一、开发环境介绍 proteus 8.8 版本+ STM32CubeMX 4.18.0 程序基于keil集成开发环境编写,基于ST官方的HAL库。 STM32CubeMX pack版本 STM32CubeMX的版本 二、项目功能介绍 该项目程序中实现了 1、程序实现了LCD1602的点亮显示 2、程序中实现了STM32的AD采样 3、程序中实现了串口通信 4、程序中实现了按键控制操作 通过滑动变阻器加放大器改变输入值。后边加上lcd1602,初始化显示“光节点检测系统” 然后加个按键按下开始 显示“光功率值:(多少)dbm 这里的范围就0-100 通过调节前边电位器每次只变化一
[单片机]
Proteus8.8版本+ <font color='red'>STM32F103</font>驱动LCD1602显示<font color='red'>程序</font>+按键+ADC+串口
海速芯32位MCU TM32F103K7可替代STM32F103C8T6用于太阳能控制器中,无需外置AD
太阳能的使用越来越普及,太阳能控制器使用了单片机和专业软件,实现了智能控制,利用蓄电池放电率特性修正的准确放电控制。以下为TM32F103K7应用于太阳能控制器的原理框图: 如上所示,TM32F103K7是海速芯(原“十速”)的32位MCU,该32位MCU采用高性能的ARM Cortex-M3内核,频率72MHz,最高集成128Kbytes flash和20Kbytes SRAM,并提供丰富的通信接口(I2C、SPI/USART)和7个定时器,具备可靠性高、精度高、功耗低等特点。 本文提到的太阳能控制器方案中,所有控制全部采用工业级芯片,能在寒冷、高温、潮湿环境运行自如。同时使用了晶振定时控制,定时控制精确;取消了电位器调
[单片机]
海速芯32位MCU TM32F103K7可替代<font color='red'>STM32F103</font>C8T6用于太阳能控制器中,无需外置AD
STM32F103】中断综述
一、中断内核: STM32的中断很强大,每个外设都可以产生中断,F103在内核水平上搭载了异常响应系统,系统异常有8个(算上RESET和HardFault也就10个),外部中断有60个,但是根据NVIC(嵌套向量中断控制器,控制整个芯片中断相关的功能),IP(中断优先级寄存器)数组中预留了240个位置(NVIC结构如上图),可见眼光之远,用于扩展,这是STM32F103用不到这么多。 如果以后要找跟内核相关的函数,都存在core_cm3.c和misc.c中,包括NVIC的函数的声明,但是其具体的库函数内容并不是和固件库头文件core_cm3.h一致(不在core_cm3.c),而是放在库函数的misc.c中,这点需要注
[单片机]
【<font color='red'>STM32F103</font>】中断综述
基于STM32f103的I2C通信接口的EPPROM模块(24C256)读写程序详解1
我看了很多网上的解释,都是先官方的说明I2C协议,再潦草的给出不完整的程序,导致你们又看不懂I2C原理又调试不出程序,所以我这篇文章先专门针对程序,先使你们的程序调试成功,再利用仿真或其他方式回去理解I2C的原理!我自己就是这么来的,所以把这种方法推荐给你们! 潦草的说明一下先,不懂不要紧!!! I2C 有四条连接线,SCL、SDA、VCC、GND。 I2C的通信协议: 数据若要传输,传输前必须由SCL、SDA线产生一个特定的电平组合,告诉模块接下来要开始传输数据了,此特定组合称为开始信号; 同理,数据传输结束了,也必须由SCL、SDA线产生一个特定的电平组合,此特定组合称为结束信号; 那我们如何知道数
[单片机]
基于<font color='red'>STM32f103</font>的I2C通信接口的EPPROM模块(24C256)读写<font color='red'>程序</font>详解1
STM32F103+RT-Thread从零开始(二)——RTT系统中点亮LED
上次的的推文简单说了下如何使用Keil创建STM32F103的工程,并且完成了LED点亮,及让LED等闪烁的功能,那是诸多同学学习单片机的起手式。本篇推文是继续上一篇推文的内容,依旧是点亮LED,不同的是,这次点亮LED等,是在RT-Thread操作系统中进行的。 创建工程 创建一个Keil工程,芯片依旧选择STM32F103C8T6,然后在Manage Run-Time Environment对话框中选择需要用的的软件组件,与上文不同的是,我们需要把RTT一起勾上。如下图: 上图中,红线框中即为RTT操作系统的组件,分别为设备驱动,系统内核以及shell。蓝线框中为Keil的RTX操作系统。我们现在要用的是RT
[单片机]
STM32F103 的晶振由8M改为了12M
看逻辑地址是否统一编址。 FLASH,RAM在同一个逻辑地址空间的,都是直接用用const,如arm,stm8,msp430等。 FLASH,RAM逻辑地址空间分开的,要用其它办法,通常是特殊关键字,__flash,__code等。 如AVR,8051等。 注:const本身并没有flash的意思。 如果flash,ram逻辑地址统一编址,那么编译器把全局或静态const变量分配到FLASH,RAM都可以。 为了节省ram,通常编译器会把全局或静态const变量分配到FLASH。 如果flash,ram逻辑地址分开编址,那么全局或静态const变量只能放到ram所在的逻辑地址空间,而无法放到FLASH。 注:逻辑地址统一编址,可以
[单片机]
STM32f103C8T6 bootloader设计
使用的是STM32f103C8T6:64Kflash,在应用程序中通过CAN把接受到的bin写到外置 flash的指定地址处。在bootloader中判断一个单独的标志位看程序是否需要升级,如果需要升级,则复制外置flash处的内容到STM32的内置flash的指定地址处。 如: bootloader地址:0x08000000UL 大小:10K——0x2800——STM32的内置flash 应用程序地址:0x08002800UL 大小:45K——0xB400——STM32的内置flash 升级信息表:0x720000UL 大小:8K——0x2000——外置flash 升级的bin文件地址:0x080124
[单片机]
STM32F103系列微控制器在应用编程技术研究
引言 STM32F103系列芯片下载程序主要通过JTAG以及ISP(In-System Programming)这两种方式。其中JTAG需要专门的下载器,这种方式主要用于软件调试。 ISP是在系统编程,指的是利用STM32F103中自带的Bootloader程序,通过通信接口擦除和下载用户代码。STM32F103系列芯片中引脚BOO T0和BOOT1置位为1和0时就会进入ISP模式,但下载程序完成后需要将BOOT0和BOOT1都置为0,才能进入正常工作模式。这就使得在下载程序完成后需要设置跳线帽等机械性的操作。而一个嵌入式产品的设计不得不考虑软件部分的更新,前面介绍的两种下载方式都不适合用来做软件更新,也就不适合用在嵌入式
[单片机]
<font color='red'>STM32F103</font>系列微控制器在应用编程技术研究
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved