基于stm32的USB模拟UART的尝试F429

2024-04-30 01:44
文章标签 模拟 stm32 尝试 f429 usb uart

本文主要是介绍基于stm32的USB模拟UART的尝试F429,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 基于stm32的USB模拟UART的尝试F429
    • 实验目的
    • 场景使用原理图
    • USBX 组件
    • 移植USBX实现虚拟串口
    • 配置USB
    • 移植USBX源码
    • 工程中添加对应源码
    • 修改usb_otg.c
    • 创建 USBX 任务
    • 添加使用串口的代码
    • 上机现象
    • 本文中使用的测试工程

基于stm32的USB模拟UART的尝试F429

本文目标:基于stm32的USB模拟UART的尝试F429

按照本文的描述,没能跑通demo,仅做记录。

先决条件:拥有C语言基础,装有编译和集成的开发环境,比如:Keil uVision5

使用外设:USB、USART1、GPIO

HAL库版本:STM32F4xx HAL Driver version number 1.26.0

STMCubeMX版本:6.10.0

Keil uVision5版本:V5.38.0.0

实验目的

新手学习,在之前的H5的实验中,能够实现usb转串口的实验,但是移植到f103上时发现ram空间不够用,实验不成功,于是手里还有个f429的板子,想着也跟着移植试试看。学习USB虚拟UART编程,体验串口的高效接收,设计一个实验,实现基于usb模拟的串口实验。

场景使用原理图

在这个应用场景中,原理图的内容如下:

在这里插入图片描述

基于以上的原理设计,使用usb接口进行接口通讯实验。usb是一个复杂的外设,笔者并没有深入研究,我这里也只是进行简单记录,设计一个实验将USB发来的数据。

USBX 组件

使用一个开源的组件来辅助这次的实验。

参考:https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Introduction_to_USBX

关于USBX :USBX 是 Azure®RTOS USB 主机和 USB 设备嵌入式堆栈。它与 ThreadX 紧密耦合。在某些类中,它需要 FileX 和 NetX Duo 堆栈。它允许使用具有多种配置的 USB 设备、复合设备和USB OTG 进行操作。它支持 USB 电源管理。USBX 为 USB 主机和 USB 设备堆栈提供了大量的 USB 类。一旦低级驱动程序能够响应USBX 请求,模块化架构就可以更容易地移植到不同的 USB 硬件 IP 上。所有 STM32 USB IP(主机、设备、OTG、高速和全速)均由 USBX 通过通用 STM32 HAL驱动程序 API 透明支持。

USBX 分为三层,如下图所示:

① 控制器层:最底层,USB 设备控制器的驱动程序,通常是 HAL 库

② stack layer:实现 USB 设备的基本操作,比如描述符的操作、使用 endpoint 进行数据传输

③ Class layer:实现各类 USB 设备的操作,比如 HID 设备、音频设备、虚拟串口,给 APP

提供接口

在这里插入图片描述

在这里插入图片描述

在 STM32 的固件中,可以看到 USBX 目录,比如:

在这里插入图片描述

移植USBX实现虚拟串口

移植 Controller layer、stack layer、Class layer ,重点在于 2 点:

① 怎么初始化硬件以确保 Controller layer 可以正常运行

② 怎么编写 APP:提供设备信息、传输数据

配置USB

在这里插入图片描述

想添加USBX的代码,发现STMCubeMX没有这个组件,自己手动从源仓库进行移植添加。

在这里插入图片描述

解决一下时钟的报错问题

在这里插入图片描述

选择Yes,让上位机自行解决,顺便看一下系统时钟频率是否是自己需要跑的频率。

移植USBX源码

找到USBX的源码,将源码移植进工程路径中。

在这里插入图片描述

工程中添加对应源码

需要添加 USBX 的 3 层源码,按照模板来进行添加,我添加的文件结构如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

添加含有“ux_device_class_cdc_acm”前缀的 C 文件,需要先选择目录,然后用搜索的方式来进行添加,进行回车之后然后选择文件添加。

在这里插入图片描述

再添加“stack layer”源码,可以从文件名的前面看出它们的作用,比如

“ux_device_stack”表示这是 stack 源码,“ux_utility”表示这是辅助函数,“ux_system”表示是这是系统函数。

将相关的头文件路径添加进来,然后一顿猛的编译,还是报很多错,这个时候需要耐心的一个个解决。

在这里插入图片描述

经过一番的添加对应的文件之后,解决了编译问题解决。

修改usb_otg.c

使用 STM32CubeMX 配置 usb 后生成的 usb_otg.c 里,只是初始化了 USB 控制器,并未启动它,也没有跟 USBX 建立联系,需要修改代码。

void MX_USB_OTG_FS_PCD_Init(void)
{/* USER CODE BEGIN USB_OTG_FS_Init 0 *//* USER CODE END USB_OTG_FS_Init 0 *//* USER CODE BEGIN USB_OTG_FS_Init 1 */UINT MX_USBX_Device_Init(void);MX_USBX_Device_Init();/* USER CODE END USB_OTG_FS_Init 1 */hpcd_USB_OTG_FS.Instance = USB_OTG_FS;hpcd_USB_OTG_FS.Init.dev_endpoints = 4;hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USB_OTG_FS_Init 2 */HAL_PCDEx_PMAConfig(&hpcd_USB_OTG_FS, 0x00, PCD_SNG_BUF, 0x14);HAL_PCDEx_PMAConfig(&hpcd_USB_OTG_FS, 0x80, PCD_SNG_BUF, 0x54);HAL_PCDEx_PMAConfig(&hpcd_USB_OTG_FS, USBD_CDCACM_EPINCMD_ADDR, PCD_SNG_BUF, 0x94);HAL_PCDEx_PMAConfig(&hpcd_USB_OTG_FS, USBD_CDCACM_EPOUT_ADDR, PCD_SNG_BUF, 0xD4);HAL_PCDEx_PMAConfig(&hpcd_USB_OTG_FS, USBD_CDCACM_EPIN_ADDR, PCD_SNG_BUF, 0x114);ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS);HAL_PCD_Start(&hpcd_USB_OTG_FS);/* USER CODE END USB_OTG_FS_Init 2 */}

创建 USBX 任务

使用单独模式( STANDALONE ) 时 , 需 要 创 建 一 个 任 务 , 不 断 运 行

“_ux_system_tasks_run”函数。在默认任务中进行测试

void StartDefaultTask(void *argument)
{/* USER CODE BEGIN defaultTask *//* Infinite loop */for(;;){// HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);// vTaskDelay(100);ux_system_tasks_run();}/* USER CODE END defaultTask */
}

添加使用串口的代码

static void SPILCDTaskFunction( void *pvParameters ) 
{char buf[100];int cnt = 0;while (1){sprintf(buf, "LCD Task Test : %d", cnt++);int ux_device_cdc_acm_send(uint8_t *datas, uint32_t len, uint32_t timeout);ux_device_cdc_acm_send((uint8_t *)buf, strlen(buf), 1000);vTaskDelay(1000); }
}

在这个文件中usbx\app\ux_device_cdc_acm.c添加如下的代码片段实现接收

static UINT ux_device_class_cdc_acm_read_callback(struct UX_SLAVE_CLASS_CDC_ACM_STRUCT *cdc_acm, UINT status, UCHAR *data_pointer, ULONG length)
{// int Draw_String(uint32_t x, uint32_t y, char *str, uint32_t front_color, uint32_t back_color);HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);extern UART_HandleTypeDef huart1;if (status == UX_SUCCESS){data_pointer[length] = '\0';// Draw_String(0, 0, (char *)data_pointer, 0x0000ff00, 0);HAL_UART_Transmit_DMA(&huart1, (uint8_t *)data_pointer, length);}return 0;
}

解决了编译错误之后,一顿操作之后,工程终于0错误,0警告了。

上机现象

烧写运行程序后,接上 USB 线,在电脑上可以识别出 USB 串口,查看设备管理器,可以看到如下设备:

在这里插入图片描述

但是使用串口助手打开时,发现一直转圈,一直未响应,打不开。

在这里插入图片描述

所以本次实验失败,没教程很难坚持,后期深入研究时在进行解决。

本文记录到此,算是自己工程的一次实践,本文完!!感谢阅读,感谢关注。

本文中使用的测试工程

https://download.csdn.net/download/weixin_44317448/89244327

这篇关于基于stm32的USB模拟UART的尝试F429的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/947629

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类