woshi_ziyu
发表于: 2015-11-14 23:08:00 | 显示全部楼层

UM1860用户手册

适用于STM32L4系列的STM32CubeL4入门指南


前言

STMCube™ 计划源自意法半导体,旨在通过减少开发的工作量、时间和成本,使开发者收益。STM32Cube是涵盖STM32微控制器的STMCube™的实现。

STM32Cube 1.x 版包括:

•    图形软件配置工具STM32CubeMX,允许通过使用图形向导生成C语言的初始化代码。

•    针对每个系列提供综合的嵌入式平台(即STM32CubeL4用于STM32L4系列):

–    STM32抽象层嵌入式软件STM32Cube HAL,确保在STM32各个产品实现最大限度的可移植性。HAL可用于所有外设。

–    底层API(LL)提供了一个快速的、轻量级、面向专家的层,比HAL更接近硬件。LL的API只能用于一些外设。

–    一套一致的中间件,比如RTOS、USB、STMTouch™、FatFS和图形。

–    所有嵌入式软件使用工具均配备了一套完整的实例。

本用户手册描述了如何开始使用STM32CubeL4固件包。

第1节描述了STMCube™计划的一部分STM32CubeL4固件的主要特点。第2节和第3节 提供了STM32CubeL4架构和固件包结构的概况。


1    STM32CubeL4主要特点

STM32CubeL4集合了在STM32L4微控制器上开发应用所需的所有通用嵌入式软件组件,并以单个包装形式提供。和STMCube™的初衷一致,该套组件具有高度可移植性,不仅是在STM32L4系列,在其他STM32系列中也是这样。

STM32CubeL4完全兼容代码生成器STM32CubeMX,其允许生成初始化代码。包内包括涵盖微控制器硬件的底层(LL)和硬件抽象层(HAL)API,以及在意法半导体开发板上运行的一套广泛的例程。为了方便用户,HAL和LL的API可以在开源BSD许可证下获得。

STM32CubeL4包也包含一系列中间件组件并带有相应的例程。他们有免费的用户友好的许可条款:

•    完整的USB主机和设备栈,支持多种方式。

–    主机方式:HID、MSC、CDC、Audio、MTP

–    设备方式:HID、MSC、CDC、Audio、DFU、LPM、BCD。

•    专业图形栈解决方案StemWin,提供二进制格式,并且基于意法半导体合作解决方案商SEGGER emWin。

•    CMSIS-RTOS实现,使用FreeRTOS开源解决方案。

•    基于开源FatFS解决方案的FAT文件系统。

•    STMTouch触摸感应库解决方案。

在STM32CubeL4包中也提供一些实现所有这些中间件组件的应用和演示程序。


2    STM32CubeL4体系结构概述

STM32Cube固件解决方案建立在三个独立的层级,可以很容易的进行互动,如图2所示:

图 2. STM32CubeL4固件体系结构

2.1    层级0

这个层级分成3个子层:

•    板级支持包(BSP)

•    硬件抽象层(HAL)

–    HAL外设驱动

–    底层驱动

•    基本的外设应用例程。

2.1.1    板级支持包(BSP)

这一层提供了一组API,和硬件板的硬件组件相关(如LCD、Audio、microSD、MEMS驱动)。它由两部分组成:

•    组件

这个是和电路板上的外部器件相关的驱动,而不是STM32。该组件驱动提供到BSP驱动的外部组件的特定API,并且可以移植到其他任何电路板上。

•    BSP驱动程序

它允许连接组件的驱动程序到特定的电路板,并且提供一系列用户友好的API。该API的命名规则是BSP_FUNCT_Action()。

例如:BSP_LED_Init()、BSP_LED_On()

BSP基于模块化的结构,允许仅实现底层的程序就很容易移植到任何硬件。


2.1.2        硬件抽象层(HAL)和底层 (LL)

STM32CubeL4 HAL和LL是互补的,并且涵盖了广泛的应用程序需求:

•        HAL驱动高层次的、面向函数、高度可移植的API。他们向最终用户隐藏MCU和外设的复杂度。

HAL驱动提供通用的多实例、功能导向的API,通过提供准备使用的过程简化用户应用程序的实现。例如,对于通信外设(I2S、UART...),它提供了API,允许初始化及配置外设,基于轮询方式管理数据传输、中断或者DMA处理、处理在通信过程中产生的通信错误。

HAL驱动程序的API分为两大类:

–        通用API,向所有STM32系列提供共用和通用的函数

–        扩展API,对具体系列或者特定的零件编号提供具体且定制的函数。

•        底层API提供寄存器级别的低级别的API,具有更好的优化性能,但移植性较差。他们需要深入了解MCU及外设的规范。

底层(LL)驱动的设计目的是提供一个快速的、轻量级、面向专家的层,比HAL更接近硬件。LL的API只能用于一些外设。和HAL相反,LL的API并不向某些外设提供,如优化访问不是主要特征的外设,或者需要庞大的软件配置以及/或者复杂的上层栈(如FSMC、USB或SDMMC)的外设。

它们的特点是:

–        一组内联函数,用于直接以及原子寄存器的访问。

–        完全独立于HAL,并且能以单独模式使用(不使用HAL驱动)。

–        涵盖全部支持的外设特征。


2.1.3        基础外设的用法示例

该层包括建立在STM32外设的示例,这些示例使用HAL或者/以及底层驱动的API以及BSP资源。


2.2        层级 1

这个层级分为两个子层:

•        中间件组件

•        基于中间件组件的示例。


2.2.1        中间件组件

中间件是一组库,涵盖USB主机和设备库、STMTouch触摸感应、StemWin、FreeRTOS和FatFS。该层的组件之间的水平连接通过调用功能API直接实现,而与低层驱动的垂直交互则是通过在库的系统调用接口实现的特定回调函数及静态宏来完成。例如,FatFS实现了磁盘I/O驱动来访问microSD驱动或者USB Mass Storage类。

每个中间件组件的主要特点如下:

•        USB主机和设备库

–        支持几个USB类(Mass-Storage、HID、CDC、DFU、LPM和BCD)。

–        支持多包传输功能,允许发送大量数据,而不用将其分割成最大包大小的传输。

–        使用配置文件来改变内核及库的配置,不用更改库代码(只读)。

–        32位对齐的数据结构体处理高速模式下的基于DMA的传输。

–        从用户层面通过配置文件支持多USB OTG内核实例。这允许操作多于一个USB 主机/设备的外设。

–        RTOS和独立操作

–        通过抽象层使用配置文件链接至低层驱动,可以避免在库和低层驱动之间任何的依赖性。

•        StemWin图形栈

–        GUI开发的专业级别的解决方案,基于SEGGER的emWin解决方案。

–        优化的显示驱动程序。

–        软件工具,用于代码生成和位图编辑(STemWin Builder…)。

•        FreeRTOS

–        开源的标准。

–        兼容CMSIS层。

–        在低功耗模式下无滴答操作。

–        集成在所有的STM32Cube中间件组件。

•        FAT文件系统

–        FATFS FAT开源库。

–        支持长文件名。

–        支持动态多磁盘。

–        RTOS和独立操作。

–        使用microSD的例程。

•        STM32触摸感应库

强大的STMTouch电容式触摸感应解决方案支持感应、触摸键、线性和旋转传感器。该方案基于成熟的表面电荷转移采集的原理。


2.2.2        基于中间件组件的例程

每个中间件组件配有一个或者多个例程(也叫做应用程序)来说明如何使用它。也提供了使用几个中间件组件的集成的示例。


2.3        层级2

该层级由单个层组成,并包含在全局的实时和图形化演示程序,其基于中间件服务层、低层抽象层和根据板的功能的基本外设使用的应用程序。

跳转到指定楼层
天南地北客
发表于: 2015-11-18 21:39:40 | 显示全部楼层

3        STM32CubeL4固件包概览


3.1        支持的STM32L4器件和硬件

STM32Cube提供了高度可移植的硬件抽象层(HAL),建立在通用的架构。它允许以此为基础的层,如中间件层, 不用深入了解使用的MCU来实现他们的函数。这样提高了库代码的重用性并且保证在其他器件的易移植性。

另外,由于它的层级架构,STM32CubeL4提供完全支持所有STM32L4系列。用户只需要在stm2l4xx.h定义正确的宏。

表 1 列出了根据所使用的STM32L4器件需要定义的宏。这个宏也必须在编译器的预处理器定义。

表1.用于STM32L4系列的宏

STM32CubeL4在所有层中都有一组丰富的例程和应用,使得其很容易理解和使用任何HAL驱动和/或中间件组件。这些例程运行在意法半导体的开发板,如表2中所列出的。


表 2. STM32L4系列开发板


对于所有其他的STM32 Nucleo板,NUCLEO-L476RG具有一组缩小版的硬件组件(一个用户按键和一个用户LED)。为了丰富STM32CubeL4固件包支持的中间件,使用了LCD显示屏Adafruit Arduino™板。该扩展板除了LCD还集成了一个microSD卡和一个操作杆。

在BSP组件中,提供了Arduino扩展板的专用驱动程序。它们的使用方法展示在提供的BSP例程,或者演示程序的固件,以及FatFS中间件的应用。

STM32CubeL4固件可以在任何兼容的硬件上运行。如果后者具有相同的硬件功能(LED、LCD显示、按钮等),用户仅仅需要更新BSP的驱动,根据自己的开发板修改提供的例程的端口设置。


3.2        固件包概述

STM32CubeL4固件解决方案以单个zip压缩包的形式提供,其结构如图3所示。


图3. STM32CubeL4固件包结构


对于每个开发板,都提供了一系列的例程,带有EWARM、MDK-ARM、SW4STM32和TrueSTUDIO工具链的预配置的工程。

图4展示了NUCLEO-L476RG开发板的工程结构图。

这些示例根据他们应用的STM32Cube层进行分类,并且命名规则如下:

•        层级0的例程被称为Examples、Examples_LL和 Examples_MIX。他们分别使用HAL驱动、LL驱动以及HAL和LL驱动的混合使用,不带任何的中间件组件。

•        层级1的例程被称为Applications。他们为每个中间件组件提供典型的应用案例。

Template文件夹下的模板工程允许快速创建基于特定开发板的固件应用程序。

所有的例程具有相同的结构:

•        \Inc 文件夹包含所有的头文件。

•        \Src文件夹包含所有的源代码。

•        \EWARM、\MDK-ARM、SW4STM32和\TrueSTUDIO文件夹包含每个工具链的预配置工程。

•        readme.txt 描述了示例的特性,以及使其正常工作所需的环境。

表3. 适用于每个开发板的示例数量




回复

使用道具 举报

天南地北客
发表于: 2015-11-19 21:36:43 | 显示全部楼层

4        STM32CubeL4使用入门


4.1        运行第一个例程

本节介绍了使用STM32CubeL4运行第一个例程是多么简单。 该例程说明了生成在STM32L476RG Nucleo板上运行的简单的切换LED例程:

1.        下载STM32CubeL4固件包。解压缩到你选择的目录。确保没有修改如图3所示的包结构。请注意,推荐将固件包复制到靠近根目录的文件夹(例如C\Eval或者G:\Tests),因为当路径太长时,一些IDE会遇到问题。

2.        浏览到 \Projects\STM32L476RG-Nucleo\Examples.

3.        打开 \GPIO,然后打开\GPIO_EXTI文件夹。

4.        使用你首选的工具链打开工程。以下给出了关于如何使用支持的工具链打开、编译和运行例程的快速概览。

5.        重新创建所有的文件,并加载镜像文件到目标的内存。

6.        运行该例程:每次按下USER按钮,LED2切换(闪烁的频率)(详细信息请参考例程的自述文件)。


若要使用支持的工具链打开、创建和运行例程,请按照下列步骤:

•        EWARM

a)        在该例程文件夹下,打开\EWARM子文件夹。

b)        启动例程的eww 工作区。

c)        重建所有的文件: Project->Rebuild all.

d)        加载工程的镜像文件: Project->Debug.

e)        运行程序Debug->Go(F5)。

•        MDK-ARM

a)        在该例程的文件夹下,打开\MDK-ARM子文件夹。

b)        启动例程的uvprojx工作区。

c)        重建所有的文件: Project->Rebuild all target files

d)        加载工程的镜像文件:Debug->Start/Stop Debug Session

e)        运行程序:Debug->Run (F5).

•        SW4STM32

a)        打开SW4STM32工具链。

b)        点击File->Switch Workspace->Other 然后浏览到SW4STM32工作区目录。

c)        点击 File->Import,选择General->Existing Projects into Workspace ,然后点击 Next

d)        浏览到SW4STM32工作区目录并且选中该工程。

e)        重建所有的工程文件:在Project explorer 窗口选择工程,然后点击Project->build project 菜单。

f)        运行程序: Run->Debug (F11)

•        TrueSTUDO

a)        打开TrueSTUDIO 工具链。

b)        点击File->Switch Workspace->Other 然后浏览到TrueSTUDIO 工作区目录。

c)        点击File->Import,选择General->Existing Projects into Workspace 然后点击Next。

d)        浏览到TrueSTUDIO 工作区目录,选中该工程。

e)        重建所有的工程文件:在Project explorer 窗口选择工程,然后点击Project->build project 菜单。

f)        运行程序:Run->Debug (F11)。


4.2        开发自己的应用程序

本节介绍了使用STM32CubeL4创建自己的应用程序所需的步骤:

1.        创建项目

要创建一个新的工程,你可以从\Projects\<STM32xxx_yyy>\Templates 目录下的为每个开发板提供的模板工程开始,也可以从\Projects\<STM32xxy_yyy>\Examples 或者 \Projects \ <STM32xx_yyy> \ Applications目录下开始( <STM32xxx_yyy> 代表开发板的名称,例如STM32L476G-EVAL)。

模板工程提供空的主循环函数,但是这是熟悉STM32CubeL4的工程设置的很好起点。该模板具有以下特点:

–        包含HAL、CMSIS和BSP驱动的源代码,这些是在具体开发板上开发代码所需的最小组件。

–        包含所有固件组件的include路径。

–        定义支持的STM32L4器件,从而允许配置相应的CMSIS和HAL驱动。

–        向为使用而读的用户提供如下的预配置文件:

使用基于ARM Core SysTick的默认时钟初始化的HAL。

SysTick ISR为了实现HAL_Delay()。

注意:        当复制现有的项目到其他位置时,请务必更新include路径。

2.        添加必要的中间件到你的工程(可选)

可用的中间件堆栈是:USB主机和设备库、STMTouch触摸感应、StemWin、FreeRTOS以及FatFS。要知道你需要在工程文件列表添加哪些源文件,请参考每个中间件提供的文档。你也可以看看\Projects\STM32xxx_yyy\Applications\<MW_Stack>(<MW_Stack>指的是中间件堆栈,如USB_Device)下的应用程序,了解需要添加哪些源文件以及哪些包含路径。

3.        配置固件的组件

HAL和中间件组件使用在头文件中声明的宏定义,提供了一组编译时间配置选项。在每个组件中提供了一个模板配置文件,它必须拷贝到工程文件夹(通常情况下,配置文件的名字是xxx_conf_template.h,当复制到工程文件夹时需要去掉 _template字)。该配置文件提供了足够的信息来解释每个配置选项的作用。详细信息请参考为每个组件提供的文档。

4.        启动HAL库

在跳转到主程序之后,应用程序代码必须调用HAL_Init() API来初始化HAL库,其做以下任务:

a)        配置闪存预读和SysTick中断的优先级(通过stm32l4xx_hal_conf.h 中定义的宏)。

b)        配置SysTick以stm32l4xx_hal_conf.h中定义的SysTick中断优先级产生一个每1毫秒的中断, 该时钟由MSI提供(在该阶段,时钟还没有配置,因此系统从内部4MHz的MSI运行)。

c)        NVIC组的优先级设置为4。

d)        调用在stm32l4xx_hal_msp.c用户文件中定义的HAL_MspInit()回调函数,执行全局的低层硬件初始化。

5.        配置系统时钟

通过调用以下描述的两个API来完成系统时钟的配置:

a)        HAL_RCC_OscConfig():该API配置内部和/或外部的晶振,以及PLL源和系数。用户可以选择配置一个晶振或者所有晶振。如果不需要在高频率下运行系统,可以跳过PLL配置。

b)        HAL_RCC_ClockConfig():该API配置系统时钟源、闪存的延迟时间以及AHB和APB预分频器。

6.        初始化外设

a)        首先写外设 HAL_PPP_MspInit函数。步骤如下:

–        使能外设时钟。

–        配置外设的GPIO。

–        配置DMA通道以及使能DMA中断(如果需要)。

–        使能外设中断(如果需要)。

b)        如果需要的话,编辑stm32xxx_it.c,调用需要的中断处理函数(外设及DMA)。

c)        如果计划使用外设中断或者DMA,编写处理完成的回调函数。

d)        在main.c 文件中,初始化外设句柄结构体,然后调用HAL_PPP_Init()函数初始化外设。

7.        开发应用程序

在这个阶段,系统已准备就绪,你可以开发应用程序代码。

–        HAL提供直观的且准备使用的API来配置外设。它支持轮询、中断和DMA的编程模式,以使用任何应用需求。有关如何使用每个外设的更多详细信息,请参考STM32CubeL4包中提供的丰富的例程集。

–        如果你的应用程序有一些实时的约束,你可以找到大量的例程展示了如何使用FreeRTOS,并且与STM32CubeL4提供的所有中间件栈集成。这可能是开发应用程序的一个很好的起点。


注意:        在默认的HAL实现中,SysTick作为时基使用:以固定的时间间隔产生中断。如果HAL_Delay()是由外设ISR处理函数调用,确保SysTick时钟比外设中断具有更高的优先级(数字上低于)。否则调用ISR的处理将会被阻止。影响时基配置的函数被声明为弱,使得在用户文件的其他实现下可以被覆盖(例如,使用通用的定时器或者其他时钟源)。欲了解更多详情,请参阅HAL_TimeBase例程。


4.3        使用STM32CubeMX生成初始化的C代码

一种替代4.2章节描述的步骤1到6的的方法包含在使用STM32CubeMX工具通过一步一步的过程来生成初始化系统、外设和中间件(上述的步骤1到6)的代码中:

1.        选择与所需的外设资源相匹配的意法半导体的STM32微控制器。

2.        配置每个所需的嵌入的软件,根据引脚冲突求解器、一个时钟树设置助手、一个功耗计算器以及执行MCU外设配置(如GPIO或USART)和中间件栈(如USB)的实用工具。

3.        生成基于选择的配置信息的初始化C代码。该代码在一些开发环境中是现成使用的。用户代码保持在下一次的生成代码。

有关更多信息,请参阅STM32CubeMX用户手册(UM1718)。


4.4        获取STM32CubeL4版本更新

STM32CubeL4固件包带有一个更新程序STM32CubeUpdater,也可以通过STM32CubeMX代码生成工具的菜单。

该更新程序可从www.st.com检测新的固件版本及补丁程序,并且建议将其下载到用户的计算机中。


4.4.1        安装和运行STM32CubeUpdater程序

按照下面的顺序来安装和运行STM32CubeUpdater:

1.        要启动安装,双击SetupSTM32CubeUpdater.exe文件。

2.        接受许可条款,并按照不同的安装步骤进行操作。

3.        一旦成功安装后,作为Program Files 下意法半导体的程序,STM32CubeUpdater变为可用的,并自动启动。STM32CubeUpdater图标将出现在系统托盘。右击更新程序图标,选择Updater Settings来配置跟新程序的连接以及是否进行手动或自动检查。有关更新程序配置的详细信息,请参考STM32CubeMX用户手册UM1718的第3章。

回复

使用道具 举报

天南地北客
发表于: 2015-11-24 23:07:37 | 显示全部楼层

5        常见问题解答


5.1        什么是STM32CubeL4固件的许可计划?

该HAL是在非限制性的BSD(伯克利软件发行版)许可协议下分发。

由意法半导体制作的中间件栈(USB主机和设备库、StemWin)带有一个授权模式,允许方便的重复使用,可以运行在意法半导体的器件上。

中间件基于著名的开源解决方案(FreeRTOS和FatFs),具有用户友好的许可条款。欲了解更多详细信息,请参阅各中间件的许可证协议。


5.2        STM32CubeL4固件包支持哪些板?

STM32CubeL4固件包为以下的STM32L4开发板提供BSP驱动程序以及准备使用的示例: STM32L476G - EVAL, 32L476GDISCOVERY和NUCLEO-L476RG。


5.3        是不是所有的例子都提供现成的工具链工程?

是的。STM32CubeL4提供了一套丰富的示例和应用程序。它们都带有用于IAR、Keil以及GCC工具链的预配置工程。


5.4        和标准外设库有没有一些联系?

STM32Cube的HAL和LL驱动代替了标准外设库:

•        HAL驱动程序提供了比标准外设API更高的抽象层。它们专注于外设的常见特性而不是硬件。它们更高的抽象层允许定义一组用户友好的API,可以方便的从一个产品移植到另一个产品。

•        LL驱动程序提供了低层的寄存器级的API。


5.5        HAL驱动程序有没有有效利用中断或DMA?这又如何控制?

是的,它们有这样做。HAL层支持三种API编程模式:轮询、中断和DMA(有或没有中断产生)。


5.6        如何管理产品/外设的特定功能?

HAL驱动程序提供扩展API,即特定的函数,附加到通用的API以支持仅可用于某些产品/线的功能。


5.7        STM32CubeMX如何产生基于嵌入式软件的代码?

STM32CubeMX内置有STM32微控制器的知识,包括其外设和软件,这样就允许向用户提供一个图形化显示,并且根据用户的配置生成*.h/*.c文件。


5.8        我怎样才能获得最新STM32CubeL4固件版本的定期更新?

STM32CubeL4固件包带有一个更新程序STM32CubeUpdater,可以配置成自动或者按需检查是否有新的固件包更新(新版本或/和修补程序)。

STM32CubeUpdater也集成在STM32CubeMX工具中。当使用该工具用于STM32L4配置和初始化C代码生成时,用户可以从STM32CubeMX自我更新以及STM32CubeL4固件包更新中获益。

欲了解更多详情,请参阅第4.4节。


5.9        什么时候应该使用HAL而不是LL驱动?

HAL驱动程序提供高层的以及功能导向的API。具有更高水平的可移植性。产品/IP的复杂性向最终用户隐藏。

LL驱动提供低层的寄存器级别的API,具有更好的优化,但较低的可移植性。它们需要深入了解产品/IP的规范。


5.10        怎样在我的开发环境中包含LL驱动程序?有没有类似HAL的LL配置文件?

没有配文件。源代码应该直接包含必要的stm32l4xx_ll_ppp.h文件。


5.11        可不可以同时使用HAL和LL驱动程序?如果可以,有什么限制?

可以同时使用HAL和LL驱动程序。可以使用HAL处理IP的初始化,然后使用LL驱动程序管理I/O操作。

HAL和LL之间的主要区别在于,HAL驱动程序需要创建和使用手柄进行操作管理,而LL驱动程序直接操作外设寄存器。HAL和LL的混合使用在Examples_MIX例子中进行了展示。


5.12        有没有LL的API不适用于HAL?

是的,有。

例如,一些已在stm32l4xx_ll_cortex.h增加的 Cortex® 的API,用于访问SCB或SysTick 寄存器。


5.13        为什么在LL驱动程序没有启用SysTick中断?

当以独立模式使用LL驱动程序时,你不需要启用SysTick中断,因为它们在LL的API没有使用,而HAL函数需要SysTick中断来管理超时。


回复

使用道具 举报

天南地北客
发表于: 2015-11-26 21:15:41 | 显示全部楼层

6     修订历史记录


表4.文档修订历史记录

  日期
  版本号
  修改内容
2015-02-16
1
  最初版本。
   
   
   
   
   
   
  2015-09-15

  
   
   
   
   
   
   
  2

  
  在表1.用于STM32L4系列的宏新增STM32L475xx和 STM32L485xx。
  新增低层(LL)驱动在前言, 第一部分:STM32CubeL4主要特点,第二部分:STM32CubeL4架构概述 以及 第三部分:STM32CubeL4固件包概述。
  新增Examples_LL 和Examples_MIX 示例在第3.2章节:固件包概述。
  新增SW4STM32工具链在第3.2章节:固件包概述和第4.1章节:运行你的第一个示例。
  更新 第五部分:常见问题与解答,添加低层驱动程序。  

回复

使用道具 举报

gyg12321
发表于: 2016-4-26 12:15:06 | 显示全部楼层

这个整理挺实用的,多谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 33 | 回复: 100



手机版|

GMT+8, 2024-4-24 02:21 , Processed in 0.087234 second(s), 7 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表