用户工具

站点工具


icore3_arm_hal_22

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
icore3_arm_hal_22 [2020/04/20 10:37]
fmj 创建
icore3_arm_hal_22 [2022/03/18 15:10] (当前版本)
sean
行 2: 行 2:
 |技术支持电话|**0379-69926675-801** ​ ||| |技术支持电话|**0379-69926675-801** ​ |||
 |技术支持邮件|Gingko@vip.163.com ​ ||| |技术支持邮件|Gingko@vip.163.com ​ |||
-|技术论坛|http://​www.eeschool.org ​ ||| 
 ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^
 |  V1.0  |  2020-04-20 ​ |  gingko ​ |  初次建立 ​ | |  V1.0  |  2020-04-20 ​ |  gingko ​ |  初次建立 ​ |
行 10: 行 9:
 \\ \\
 \\ \\
 +
  
 ===== STM32CubeMX教程二十二_USBD_MSC实验--虚拟U盘 ===== ===== STM32CubeMX教程二十二_USBD_MSC实验--虚拟U盘 =====
行 25: 行 25:
 {{ :​icore3:​icore3_cube_22_5.png?​direct | }} {{ :​icore3:​icore3_cube_22_5.png?​direct | }}
 6. 引脚模式配置 6. 引脚模式配置
-{{ :icore3:icore3_cube_21_6.png?direct | }}+{{ :icore3:icore3_cube_22_6.png?direct | }}
 7. 配置USB_OTG_HS 7. 配置USB_OTG_HS
 {{ :​icore3:​icore3_cube_22_7.png?​direct | }} {{ :​icore3:​icore3_cube_22_7.png?​direct | }}
行 33: 行 33:
 {{ :​icore3:​icore3_cube_22_9.png?​direct | }} {{ :​icore3:​icore3_cube_22_9.png?​direct | }}
 10. 时钟源设置,选择外部高速时钟源,配置为最大主频 10. 时钟源设置,选择外部高速时钟源,配置为最大主频
-{{ :icore3:icore3_cube_21_11.png?direct | }}+{{ :icore3:icore3_cube_22_11.png?direct | }}
 11. 工程文件的设置,​ 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可 ​ IDE我们使用的是 MDK5 11. 工程文件的设置,​ 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可 ​ IDE我们使用的是 MDK5
 {{ :​icore3:​icore3_cube_22_12.png?​direct | }} {{ :​icore3:​icore3_cube_22_12.png?​direct | }}
行 62: 行 62:
 \\ \\
  
-===== STM32CubeMX教程二十——虚拟串口 ​=====+===== 实验二十二:USBD_MSC实验——虚拟U盘 =====
  
 ==== 一、 实验目的与意义 ==== ==== 一、 实验目的与意义 ====
   - 了解STM32 USB SLAVE结构。   - 了解STM32 USB SLAVE结构。
   - 了解STM32 USB SLAVE特征。   - 了解STM32 USB SLAVE特征。
-  - 掌握STM32 HAL库中USB SLAVE的配置方法。 +  - 掌握USB SLAVE MSC使用方法。
-  - 掌握USB SLAVE VCP使用方法。+
   - 掌握Keil MDK集成开发环境使用方法。   - 掌握Keil MDK集成开发环境使用方法。
  
行 80: 行 79:
   - 装有WIN XP(及更高版本)系统的计算机。   - 装有WIN XP(及更高版本)系统的计算机。
 ==== 三、 实验原理 ==== ==== 三、 实验原理 ====
-=== 1、USB_VCP设备 ​=== +=== 1、SDMMC简介 ​=== 
-  * USB_VCP是属于USB_CDC类设备中一种,通过USB接口虚拟串口实现串口通讯的功能。 +  * USDMMC指的是SD、SDIO 、MMC卡主机接口,提供APB2外设总线和多媒体卡(MMCs),数字安全记忆卡(SD)和SDIO卡。 
-    USB虚拟串口,简VCP,Virtual COM Port的简写利用USB的CDC类来实现的一种通信接口。 +  MMC的全称是”Multi Media Card”――所以也通常被叫做”多媒体卡”,是一种小巧大容量的快闪存储卡,​特别应用于移动电话 和数字影像及其他移动终端中。 
-    USB虚拟串口属USB通信设备物理层通过USB总线采用虚拟串口的方式为主机提供个物理串口。在系统内部USB控制器提供了一个批量传输IN端和一个批量传输OUT端点,用于数据的接收和发送模拟串的RX和TX线。另外USB控制器还提供中断IN端点,发送当串口状态实现对串传输控制。串口设备的数据,由系统的串口采集,在芯片内完成USB包的封装,通过USB总线上传至主机,再由相应的串口应用程序进行处理对用户来说看到的是基于串口的数采集和传输,而实际上实现的是基于USB协议数据传输。 +  SD卡,数字安全记忆卡(Secure Digital Memory Card),是 用移动设备的标准记忆卡SD卡数据传送和物理规范由MMC发 展而来大小和MMC差不多。长宽和MMC比MMC稍微厚了一点。兼容性方面SD卡向下兼容多媒体卡(Multi Media Card)。 
-    * 我们可以利用STM32自带的USB功能来实现一个USB虚拟串,从而通过USB,实现电脑与STM32数据互传。上位机无需编写专门的USB程序只需要一个串口调试助手即可调试非常实用。 +  *SDIO是在SD内存卡接口基础上发展起来外设SDIO接 ​兼容以前的SD内存卡并且可以连接SDIO接口的设备。目前SDIO协议的SPECSDIO接支持设备总类有蓝牙网卡,电视卡等
-    * 本实验利用STM32自带的USB功能,连接脑USB,虚拟出一个USB串口,实现电脑和开发板的数据通信+
  
-=== 2、USB_CDC ​===   +=== 2、USB模块介绍 ​===   
-  * USB2.0标准下定义了很多子类,有音频类,CDC类,HID,打印,大容量存储类,HUB,智能卡等等,这些在usb.org官网上有具体的定义,这里要介绍通信类CDC。CDC(Communication Device Class)类是USB2.0标准下一个子类,定义通信相关设备的抽象集。 +  * USB模块为PC机和微控制器所实现功能之间提供合USB规范的通信连接。PC主机和微控制器之间数据传输通过共享一专用的缓冲区来完成的,该数据缓冲区能被USB外设接访问这块专用数据缓冲区大小由所使用端点数目每个端点最大的数据分组大小所决定,每个端点最大可使用512字节缓冲区最多可于16单向或8个双向点。 
-  * USB的CDC类是USB通信设备类(Communication Device Class)简称。CDC类USB组织定义的门给各种通信设备(电信通信设备和中速网络通信设备)使用的USB子类。根CDC类所针对通信设备不同CDC类又分成以下不同的模型:USB传统纯电话业务(POTS)模型,USBISDN模型和USB网络模型,其中USB传统纯电话业务模型又可分为线控制模型(Direct Line Control Model)、抽象模型、电话模型虚拟串口就属于USB传统纯电话业务模型下抽象控制模型。 +  * USB模块同PC主机通信,根据USB规范现令牌分组的检测数据发送/​接收的处理,和握手分组处理。整个传输的格式由硬件完成其中括CRC的生成和校验。个端点都有个缓冲区描述块描述该使用的缓冲区地址大小和需要传输的字节数。当USB模块识别出一个有效的功能/​端点的令牌分时,(需要传输数据并且端点已配置)随之发生相的数据传输。 
-  * USB CDC类通信部分主要包含三部分:枚举过程、虚拟串口操作和数据通信。其中虚拟串口操作部并不一强制需要因为若跳过这些虚拟串口的操作,实际上USB依然是以通信的。之所以会有虚拟串口操作,主要是我们通常使用PC作为Host端在PC端使串口工具来与其进行通信,PC的对应驱动将其虚拟成一个普通串口,这样一来,可以方便PC端软件通过操作串口的方式来与其进行通信,际上Host端与Device端物上是通过USB总线来进行通信的与串口没有关系,这一虚拟化过程,起决定性作用是对应驱动,包含如何将每一条具体的虚拟串口操作对应到实际上的USB操作。需要注意的是Host与Device端的USB通信速率并不受所谓的串口波特率影响,它就是标准的USB2.0全速(12Mbps)速度,实际速率取决于总线的实际使用驱动访问USB外设有效速率(两边)以及外部环境对通信本身造成干扰率等因素成。 +  * USB模块通一个内部16位寄存器实现端与专用缓冲区数据交换在所有的数据传输完成后如果需要,则根据传输的方向,发送接收适当的握手分组在数据传输结束时,USB模块将触发与端点相关的中断,通过读状态寄存器和/​或者利不同中断处理程序微控制器可以确定:哪端点需要得到服务;产生如位填充、格式、CRC、协议、缺失ACK、缓冲区溢出/​缓冲区未满等错误时,正在进行的是哪种传输。 
-  * CDC类软件框架 + 
-{{ :​icore3:​icore3_arm_hal_21_1.png?​direct |}} +=== 3、USB MSC简介 == 
-  * 上图所示,黄色USB Device Core部分为USB设备库文件,​属于中间件,​它为USB协议栈的核心源文件,一般不需要修改: +  * USB大容量存储设备(英语:USB mass storage device class也称为USB MSC或UMS)是一个协议,允许USB接口的设备与主计算设备相连接,以便在两者之间传输文件。对于主计算设备来说,USB设备看起来就像一个移硬盘,允许拖放型文件传送它实际上是由USB实施者论坛所通过许多通讯协议的汇总这一标准提供了许多设备的界面包括移动硬盘、闪存盘、移动光学驱动器、读卡器、数码相机、数码音乐播器、PDA及手机等等 
-  * USB Device Core中,​Log/​debug为打印/​调试开; +=== 4、USBD_MSC实验介绍: === 
-  * core为USB设备核心;​ +  * 对于iCore3想要变为一个U盘首先需要存储介质TF卡为iCore3开发板中的存储器,可以将TF卡虚拟为U盘iCore3设备的STM32核心作为协议载体承载着分别与TF卡和主机通信的任务。 
-  * USB request中定义了枚举程中各种标准请求处理; +  * USBD_MSC实验是用STM32F407的USB接口通过STM32_HAL库生成的代码达到iCore3上的TF卡虚拟成为一个U盘。 
-  * I/O request为底层针对USB通信接口的封装 +=== 5、实验介绍: === 
-  * 黄色USB Device Class部分为USB类文件,也属于中间件,​USB设备库,目前ST DEMO中支持的类HID, Customer HID, CDC, MSC, DFU, Audio, ST提供了这些类源码框架其他的Class或者是复合设备需要自己根据实际需求情况进行扩展定制如果用户需求只是需要一个标准类比如CDC信,那么最好就使现成代码不需要做任何修改就可以实现这CDC通信功能。 +  * 通过移植ST官方提供的代码来实现STM32将TF卡虚拟成U盘,然后就可以像操作U盘一样操作TF卡,本实验使用HAL库生成代码生成方法参考iCore3_CubeMX教程二十二_USBD_MSC。硬件连示意图如下图: 
-  * 蓝色USB Device HAL Driver为HAL库部分,是对USB外设接口的封装,属于底层驱动,不需要修改,它分为PCD和LL Driver,PCD处于LL Driver之上。 +{{ :icore3:icore3_arm_hal_22_1.png?direct |}}
-  * 洋红色USB Device Configuration为USB配置封装位于USB底层HAL层驱动与中间件USB协议栈之间,一方面向上层(USB设备库)提供各种操作调用另一方面向底层USB提供各种回调接口是由于它的存在,使得USB协议栈(USB设备库)与底层硬件完全分离从而使USB设备库具有更加兼容所有STM32通用性USB Device Configuration为开给用户的源文件,用户可根据自己的某些特殊需要进行修改,也可以使用默认的源文件,假如没有任何特殊要求的话,我们使用默认即可。 +
-  * Application应用层,USB Device Class有可能将自己对应该的操作接口封装在一个操作数据结构中由应用来具体实现这些操作在系统初始化时,由应用将已经定义好的操接口注册到对应的USB类,比如usbd_cdc_if, 就这样,使得应用层应用代码与属于中间层的USB协议栈分离,USB协议栈会将一些字符串描述符放到APP,当USB初始化时这些已经定义好的字符串通过指针初始化到USB协议栈中以便后续需要时获取。 +
-  * USB_CDC类详细内容可参考《USB_CDC类入门培训》。 +
-=== 3、USBD_VCP实验介绍 == +
-  * USBH_VCP实验是用STM32F407的USB接口通过STM32_HAL库生成的代码达到iCore3上的USB接口实现虚拟串口的功能。 +
-=== 4、实验内容: === +
-  * 通过移植STM32_HAL库提供的代码来实现STM32虚拟串口功能,然后就可以像操作串口一样操作USB,本实验实现终端发送数据STM32将收到的数据直接返回给终端,验证发送和接收。 +
-{{ :icore3:icore3_arm_hal_21_2.png?direct |}}+
 ==== 四、 实验程序 ==== ==== 四、 实验程序 ====
  
行 113: 行 103:
 <code c> <code c>
 int main(void)  ​ int main(void)  ​
- +  ​
   HAL_Init();  ​   HAL_Init();  ​
   SystemClock_Config();  ​   SystemClock_Config();  ​
   MX_GPIO_Init();  ​   MX_GPIO_Init();  ​
   MX_USB_DEVICE_Init();  ​   MX_USB_DEVICE_Init();  ​
-  ​LED_GREEN_ON;  ​ +  ​MX_SDIO_SD_Init();  ​
-      ​+
   while (1)  ​   while (1)  ​
   {  ​   {  ​
- +        LED_RED_ON; ​  
 +        LED_GREEN_OFF; ​  
 +        LED_BLUE_OFF; ​  
 +        HAL_Delay(500); ​  
 +        LED_RED_OFF; ​  
 +        LED_GREEN_ON; ​  
 +        LED_BLUE_OFF; ​  
 +        HAL_Delay(500); ​  
 +        LED_RED_OFF; ​  
 +        LED_GREEN_OFF; ​  
 +        LED_BLUE_ON; ​  
 +        HAL_Delay(500); ​  
   }  ​   }  ​
 +}
 +</​code>​
 +  * Main函数中对SDIO与USB分别进行了初始化,在while循环中用三色灯循环点亮表明程序正在运行。
 +=== 2. 初始化函数 ===
 +<code c>
 +void MX_SDIO_SD_Init(void) {  ​
 +  hsd.Instance = SDIO;  ​
 +  hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;  ​
 +  hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;  ​
 +  hsd.Init.ClockPowerSave=SDIO_CLOCK_POWER_SAVE_DISABLE;​
 +  hsd.Init.BusWide = SDIO_BUS_WIDE_1B;  ​
 +  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;  ​
 +  hsd.Init.ClockDiv = 0;  ​
 +  if (HAL_SD_Init(&​hsd) != HAL_OK) ​  ​{ ​
 + ​Error_Handler();  ​
 + ​}  ​
 +  if (HAL_SD_ConfigWideBusOperation(&​hsd,​ SDIO_BUS_WIDE_4B) != HAL_OK) ​ {  ​
 +     ​Error_Handler();  ​
 +  }  ​
 +}  ​
 +
 +</​code>​
 +=== 3. 接口函数 === 
 +  * 在usbd_storage_if.c文件中是USB_MSC初始化与读写相关函数。需要在这个文件下编写相关读写SDIO的相关函数,分别为STORAGE_GetCapacity_HS获取容量信息函数STORAGE_Read_HS读SDIO函数与STORAGE_Write_HS写SDIO函数。分别引入SD卡的接口函数。HAL_SD_GetCardInfo获取SD卡信息函数,HAL_SD_ReadBlocks读取SD卡函数,HAL_SD_WriteBlocks写SD卡函数以及HAL_SD_GetCardState获取SD卡状态信息函数。
 +  * 获取容量信息函数
 +<code c>
 +int8_t STORAGE_GetCapacity_HS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)  ​
 +{  ​
 +  /* USER CODE BEGIN 10 */  ​
 +  HAL_SD_GetCardInfo(&​hsd,&​SDCardInfo);  ​
 +
 +  *block_num ​ = STORAGE_BLK_NBR;  ​
 +  *block_size = STORAGE_BLK_SIZ;  ​
 +  return (USBD_OK);  ​
 +  /* USER CODE END 10 */  ​
  
 </​code>​ </​code>​
-  * 主程序主要打开了LED_GREEN,在while循环中并没有写任何内容,接受发送处理文件主要在usb_cdc_if.c中。 +  *  ​读SDIO函数
-=== 2. 接受回调函数: ===+
 <code c> <code c>
-static ​int8_t ​CDC_Receive_HS(uint8_t* ​Buf, uint32_t ​*Len +int8_t ​STORAGE_Read_HS(uint8_t lun, uint8_t *buf, 
 + uint32_t ​blk_addr, uint16_t blk_len
 {  ​ {  ​
-  /* USER CODE BEGIN 11 */   +  /* USER CODE BEGIN 13 */   
-  ​USBD_CDC_SetRxBuffer(&hUsbDeviceHS&Buf[0])  +uint32_t timeout = 10000; ​  
-  ​USBD_CDC_ReceivePacket(&​hUsbDeviceHS)  + 
-   CDC_Transmit_HS(Buf,​(uint16_t)(*Len));  ​+    if(HAL_SD_ReadBlocks(&hsd,buf,​blk_addr,​(uint32_t)blk_len, timeout) == USBD_OK){ ​  
 +            while(HAL_SD_GetCardState(hsd)!= HAL_OK)   
 +            ​{ ​  
 +                if (timeout-- == 0  
 +                {   
 +                    return -1;  ​ 
 +                }   
 +            }   
 +    }     
   return (USBD_OK);  ​   return (USBD_OK);  ​
-  /* USER CODE END 11 */   +  /* USER CODE END 13 */   
- +}
  
 </​code>​ </​code>​
-=== 3. 发送函数 ​=== +  * 写SDIO函数
 <code c> <code c>
- ​uint8_t CDC_Transmit_HS(uint8_t* ​Buf, uint16_t ​Len)  ​+int8_t STORAGE_Write_HS(uint8_t lun, uint8_t *buf,  
 +uint32_t blk_addr, uint16_t ​blk_len)  ​
 {  ​ {  ​
-  ​uint8_t result = USBD_OK; ​  +  /* USER CODE BEGIN 14 */   
-  ​/* USER CODE BEGIN 12 */   +    ​uint32_t timeout = 10000; ​  
-  ​USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceHS.pClassData; ​  +       
-  if (hcdc->TxState != 0){   +    if(HAL_SD_WriteBlocks(hsd,​buf,​ blk_addr, blk_len, timeout) ​== USBD_OK){ ​  
-    return ​USBD_BUSY;   +            while(HAL_SD_GetCardState(hsd)!= HAL_OK)   
-  }   +            ​{ ​  
-  ​USBD_CDC_SetTxBuffer(&​hUsbDeviceHS,​ Buf, Len);   +                ​if (timeout-== 0)   
-  ​result = USBD_CDC_TransmitPacket(&​hUsbDeviceHS);   +                ​{   
-  /* USER CODE END 12 */   +                    return ​-1;   
-  return result; ​  +                }   
-  +            ​} ​  
 +    }      
 +  ​return ​(USBD_OK);   
 +  /* USER CODE END 14 */   
 +}
 </​code>​ </​code>​
-  * CDC_Transmit_HS是发送函数,指定数据首地址和字节长度,数据就会发送到串口,底层是USB库实现的。CDC_Receive_HS是接收到收据后的回调函数,数据是收到一帧后才调用的CDC_Receive_HS,所以每次的字节长度不一定相同,传入的两个参数是数据缓存首地址和数据长度。这里简单的将接收到的数据原样返回,实现数据回环,只需要在CDC_Receive_HS函数添加一行调用CDC_Transmit_HS函数即可。 
 ==== 五、 实验步骤 ==== ==== 五、 实验步骤 ====
   - 把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连);   - 把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连);
-  - 将跳线帽插在USB_UART; +  - 将跳线帽插在USB OTG; 
-  - 把iCore3通过Micro USB线与计算机相连,为iCore3供电;+  - 将Micro SD卡插入TF卡座里面; 
 +  - 把iCore3(USB OTG)通过Micro USB线与计算机相连,为iCore3供电;
   - 打开Keil MDK 开发环境,并打开本实验工程;   - 打开Keil MDK 开发环境,并打开本实验工程;
   - 烧写程序到iCore3上;   - 烧写程序到iCore3上;
-  - 打开Commix串口终端(注:Commix使用方法见附录); +  - 在电脑上操作磁盘
-  - 也以进入Debug 模式,单步运行或设置断点验证程序逻辑+
  
 ==== 六、 实验现象 ==== ==== 六、 实验现象 ====
-  * 终端发送“Hello,I’M ​iCore3.”STM32将接收的消息又直接返回给终端,现象如下: +  * 下载程序到iCore3上之后可以从设备管理器内查看USB大容量存储设备。同时可以看到设备和驱动器里面多了一个磁盘。可以对该磁盘进行操作,即可读写Micro SD卡。 
-{{ :​icore3:​icore3_arm_hal_21_3.png?​direct |}} +{{ :icore3:icore3_arm_hal_22_2.png?direct |}}
- +
- +
- +
- +
- +
-**附录:** +
-  * 1、驱动安装:打开本实验文件夹中的驱动文件夹双击VCP_V1.4.0_Setup.exe,​开始安装虚拟串口驱动。按照顺序安装即可。 +
-{{ :icore3:icore3_arm_hal_21_4.png?​direct |}} +
-  * 2、安装完成后并下载程序设备上将会显示相应的端口 +
-{{ :​icore3:​icore3_arm_hal_21_5.png?direct |}}+
  
  
  
icore3_arm_hal_22.1587350248.txt.gz · 最后更改: 2020/04/20 10:37 由 fmj