STM32Cube系列教程10:STM32CubeIDE工程创建+串口DMA+IDLE+printf重定向+软中断处理串口数据+非阻塞延时任务

文章目录

  • 工程配置
    • 配置时钟
    • 配置Debug接口
    • 配置串口外设
    • 配置时钟树
    • 生成代码
  • 配置串口
    • 重定向printf
    • 配置串口,开启IDLE,开启软中断
  • 配置非阻塞延时任务调度函数
    • 编写任务调度函数
    • 延时任务创建
  • 编译,下载与测试
    • 编译
    • 下载
    • 测试

前两天收到了ST社区的NUCLEO-U083RC的评估板,这颗芯片中内置了硬件AES与RNG模块,准备对这两个模块做个测试,今天先配置个工程模板,主要开启串口收发,printf重定向,利用DMA与IDLE中断自动接收不定长的串口数据,在接收完毕后利用软中断触发中断处理串口数据,在编写一个简易的非阻塞延时功能。

全部代码以上传到github:https://github.com/what-sudo/stm32U083

工程配置

配置时钟

打开STM32CubeIDE环境,创建一个新项目,选择对应的芯片,打开STM32CubeMX代码生成工具。
打开System Core -> RCC,分别配置外部高速时钟与外部低速时钟源为晶体振荡器
在这里插入图片描述

打开System Core -> SYS,配置系统时基为SysTick。

vi

配置Debug接口

打开Trace and Debug -> Debug配置选项,选中Serial Wire。打开SWD功能。这里如果不打开,后期将无法使用swd功能烧写程序。
在这里插入图片描述

配置串口外设

打开Connectivity -> LPUART1配置选项,模式设置为异步串行接口,下面波特率设置为115200,检查右侧显示的串口管脚是否与硬件匹配,如果不匹配可重定向到别的管脚。

在这里插入图片描述
配置串口DMA通道
在这里插入图片描述
使能串口中断源
在这里插入图片描述

配置时钟树

为了获取更好的性能,这里选择使用外部时钟,注意设置外部晶体的频率,系统时钟源选择PLLCLK,HCLK时钟配置为48MHz。
在这里插入图片描述

生成代码

点击上方的Project manager,打开Code Generator,选中仅复制使用的库文件,生成单独的.c与.h文件。
在这里插入图片描述
设置完成后,Ctrl + S保存,将自动弹窗提示生成代码,或手动点击上方的小齿轮图标生成代码
在这里插入图片描述

配置串口

重定向printf

打开Core\Src\usart.c文件,在文件前部加入重定向printf的代码。

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(FILE *f)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
GETCHAR_PROTOTYPE
{uint8_t ch = 0;HAL_UART_Receive(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);if (ch == '\r'){__io_putchar('\r');ch = '\n';}return __io_putchar(ch);
}

在这里插入图片描述

配置串口,开启IDLE,开启软中断

打开usart.c文件,在文件中定义串口接收buffer,编写串口IDLE中断处理函数,串口DMA发送函数,串口接收数据处理函数,软中断处理函数。

volatile uint8_t rx1_len = 0;  //Received data length
volatile uint8_t rec1_end_flag = 0; //Received data over flag
uint8_t rx1_buffer[BUFFER_SIZE]={0};  //Received data buffer// IDLE中断处理
void Usart1_IDLE(void)
{uint32_t tmp_flag = 0;uint32_t temp;tmp_flag = __HAL_UART_GET_FLAG(&hlpuart1, UART_FLAG_IDLE);if ((tmp_flag != RESET)){__HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);HAL_UART_DMAStop(&hlpuart1);temp = __HAL_DMA_GET_COUNTER(&hdma_lpuart1_rx);rx1_len = BUFFER_SIZE - temp;rec1_end_flag = 1;EXTI->SWIER1 |= 1 << 0;}
}
// 串口发送
int DMA_Usart1_Send(uint8_t *buf, uint8_t len)
{if (len == 0)return 0;HAL_StatusTypeDef sta = HAL_UART_Transmit_DMA(&hlpuart1, buf, len);if (sta != HAL_OK)return -1;return 0;
}
// 串口数据处理
void Usart1_Handle()
{if (rec1_end_flag) {DMA_Usart1_Send(rx1_buffer, rx1_len);rx1_len = 0;rec1_end_flag = 0;HAL_UART_Receive_DMA(&hlpuart1, rx1_buffer, BUFFER_SIZE);}
}
// 软中断处理
void EXTI0_1_IRQHandler(void)
{if (EXTI->RPR1 & 1 << 0){EXTI->RPR1 |= 1 << 0;Usart1_Handle();}
}

打开stm32u0xx_it.c文件,找到void USART3_LPUART1_IRQHandler(void)函数,在函数体前部其中加入Usart1_IDLE函数调用。修改如下

/*** @brief This function handles USART3 (combined with EXTI 24) + LPUART1 global interrupt (combined with EXTI lines 28).*/
void USART3_LPUART1_IRQHandler(void)
{/* USER CODE BEGIN USART3_LPUART1_IRQn 0 */Usart1_IDLE();/* USER CODE END USART3_LPUART1_IRQn 0 */HAL_UART_IRQHandler(&hlpuart1);/* USER CODE BEGIN USART3_LPUART1_IRQn 1 *//* USER CODE END USART3_LPUART1_IRQn 1 */
}

打开main.c文件,在main()函数中,加入初始化软中断,开启IDLE中断,开启串口DMA接收的代码

  EXTI->IMR1 |= 1<<0;HAL_NVIC_SetPriority(EXTI0_1_IRQn, 3, 0);HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);__HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE);HAL_UART_Receive_DMA(&hlpuart1,rx1_buffer,BUFFER_SIZE);

在这里插入图片描述

配置非阻塞延时任务调度函数

编写任务调度函数

打开main.c文件,在user code的位置,定义task_scheduling函数。

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t task_scheduling(uint32_t *task, uint32_t time)
{uint32_t sys_ms_timer = HAL_GetTick();if ((sys_ms_timer > *task) && ((sys_ms_timer - *task) > time)){*task = sys_ms_timer;return 1;}else if (*task > sys_ms_timer){if (((0xffffffff - *task) + sys_ms_timer) > time){*task = sys_ms_timer;return 1;}}return 0;
}/* USER CODE END 0 */

延时任务创建

在主循环中,添加一个led灯闪烁的任务,每隔1000ms执行一次。

  /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){if (task_scheduling(&task1, 1000)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */

编译,下载与测试

编译

代码编写完成后,点击工具栏的build按钮
在这里插入图片描述

下载

等待控制台完成编译后,控制台输出程序的空间占用,点击工具栏的下载按钮,等待完成下载。
在这里插入图片描述

测试

程序下载完成后,可以看到led灯每隔1s闪烁一下。
打开串口调试工具,发送数据,单片机将接收到的数据返回。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/842462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5.27周报

这两周邻近毕业故没有很多时间来学习课余内容&#xff0c;另外最近身体有些不舒服【偏头痛】&#xff0c;所以学的内容不多&#xff0c;包括SVM向量机和ResNet【不包括代码复现】 1.SVM支持向量机的大概内容 1、目的&#xff1a; 主要内容是如何找到分类的那条线【超平面】—…

我的世界开服保姆级教程

前言 Minecraft开服教程 如果你要和朋友联机时&#xff0c;可以选择的方法有这样几种&#xff1a; 局域网联机&#xff1a;优点&#xff1a;简单方便&#xff0c;在MC客户端里自带。缺点&#xff1a;必须在同一局域网内。 有些工具会带有联机功能&#xff1a;优点&#xff1a;一…

【GateWay】自定义RoutePredicateFactory

需求&#xff1a;对于本次请求的cookie中&#xff0c;如果userType不是vip的身份&#xff0c;不予访问 思路&#xff1a;因为要按照cookie参数进行判断&#xff0c;所以根据官方自带的CookieRoutePredicateFactory进行改造 创建自己的断言类&#xff0c;命名必须符合 xxxRout…

整理前端新出的操作工具好用又好玩(Custom Formatter,Oxlint,Nuxt DevTools,component-party)

1.使用Custom Formatter 使vue3中的reactive object 在Chrome在console中更易理解的方式展现 启用步骤&#xff1a; 1.打开控制台&#xff0c;然后打开console设置 2.前往proferences中的Console&#xff0c;勾选Enable custom formatters选项 3.刷新页面 2.使用css Overv…

FreeRtos进阶——关于任务的深入探究

创建任务函数 在我们创建任务中&#xff0c;会有几个比较神奇的参数&#xff0c;例如函数名称&#xff0c;以及栈大小。在我们创建任务时&#xff0c;也相应的要为每一个任务创建栈。这里面的栈除了用于任务数组开辟的空间外&#xff0c;还可以用于保存现场&#xff0c;例如有S…

手把手从0到1教你做STM32+FreeRTOS智能家居--第11篇之步进电机

一、硬件设计 步进电机介绍 本项目用到的是常见的也是控制起来最简单的步进电机&#xff1a;五线四项的步进电机28BYJ-48。 单片机IO口输出电流太小无法直接驱动电机运行&#xff0c;在这里我们需要另外加一个电机驱动板。可以选择ULN2003电机驱动板。 步进电机的控制原理 …

jmeter发送webserver请求和上传请求

有时候在项目中会遇到webserver接口和上传接口的请求&#xff0c;大致参考如下 一、发送webserver请求 先获取登录接口的token&#xff0c;再使用cookie管理器进行关联获取商品(webserver接口)&#xff0c;注意参数一般是写在消息体数据中&#xff0c;消息体有点像HTML格式 执…

windows 搭建 go开发环境

go语言&#xff08;或 Golang&#xff09;是Google开发的开源编程语言&#xff0c;诞生于2006年1月2日下午15点4分5秒&#xff0c;于2009年11月开源&#xff0c;2012年发布go稳定版。Go语言在多核并发上拥有原生的设计优势&#xff0c;Go语言从底层原生支持并发&#xff0c;无须…

字典的创建和删除

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中&#xff0c;字典与列表类似&#xff0c;也是可变序列&#xff0c;不过与列表不同&#xff0c;它是无序的可变序列&#xff0c;保存的内容…

pip换源ubuntu

到THU网站上有给定的教程 https://mirrors.tuna.tsinghua.edu.cn/help/pypi/ 方法1 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package然后在https://pypi.org/project/nvidia-cublas-cu12/#files 里面搜索你的包名 方法2 python -m pip install --upg…

决策树|随机森林 GBDT XGBoost|集成学习

文章目录 1 决策树模型1.1 决策树模型简介1.2 决策树模型核心问题1.2.1 分类划分标准1.2.1.1 信息增益1.2.1.2 增益率1.2.1.3 基尼系数 1.2.2 停止生长策略1.2.3 剪枝策略 1.3 决策树 - python代码1.3.1 结果解读1.3.2 决策树可视化1.3.3 CV - 留一法 2 集成学习2.1 Boosting2.…

cin-getline缓存区

更多资源请关注纽扣编程微信公众号 cin.sync()清除缓存区 如果需要输入如下内容 3 This is C language. This is JAVA language. This is Python language. 写如下程序 #include<bits/stdc.h> using namespace std; string str[100]; int main(){int n;cin>&…

4-主窗口

4-主窗口 1、简介2 菜单栏、工具栏、状态栏2.1 菜单栏2.2 QAction2.3 工具栏2.4 状态栏 3 混合方式UI设计 1、简介 QMainWindow是一个为用户提供主窗口程序的类&#xff0c;包含一个菜单栏、多个工具栏、多个停靠控件、一个状态栏以及一个中心控件&#xff0c;是许多应用程序&…

Visual Studio 下的Qt工程无法打开 “xxx.ui“ 文件和LNK1104 无法打开文件“Qt5Cored.lib”错误

一、问题&#xff1a; VS下Qt环境准备好后&#xff0c;创建了Qt工程然后点击 Form Files 下的 “xxx.ui” 文件&#xff0c;在弹出 Qt 设计师 界面后闪退并显示如下错误&#xff1a; 二、解决 1、工具栏处依次点击&#xff1a;扩展 一> Qt VS Tools 一> options 弹出选…

网络工程师---第四十二天

1、基于子网的vlan划分配置步骤是什么&#xff1f; 2、基于端口的vlan划分配置步骤是什么&#xff1f; 3、基于MAC地址的vlan划分配置步骤是什么&#xff1f; 4、请简述无线局域网的组网方式有哪几种&#xff0c;区别是什么&#xff1f; 5、请简述堆叠、级联和集群作用和区别是…

在kaggle中的notebook 如何自定义 cuda 版本以及如何使用自定义的conda或python版本运行项目(一)

问题 第一部分 当前kaggle中带有gpu的notebook 默认的cuda 是12.1版本&#xff0c;如果我要跑一个项目是11.3的&#xff0c;如何将默认的cuda 改为自己需要的cuda 11.3 方法 step1 从官网下载需要的版本cuda run 文件&#xff08;如cuda 11.3&#xff09; 在nvidia cuda 下…

基于Netty实现安全认证的WebSocket(wss)服务端

1.Netty服务端 服务端代码参考【基于Netty实现WebSocket服务端-CSDN博客】中的两种方式都可以&#xff1b;这里用的是第一种简单方式。 新增如下逻辑&#xff1a;添加SSLHandler SSLContext sslContext SslUtil.createSSLContext("JKS","D:\\workSpace\\day…

Web(数字媒体)期末作业

一.前言 1.本资源为类似于打飞机的网页游戏 2.链接如下&#xff1a;【免费】前端web或者数字媒体的期末作业&#xff08;类似于打飞机的2D网页小游戏&#xff09;资源-CSDN文库 二.介绍文档

SAP HCM 标准程序如何定位内表赋值 ABAP DEBUG SCRIPT

Complacency is the enemy of study 学习的敌人是自己的满足。 标准内表定位代码位置!!! 不知道大家有没有尝试体会过debug标准程序,debug过程中发现SAP标准的内表不知道什么时候赋值,或者类的静态属性什么时候改变的,本文通过ABAP DEBUG SCRIPT的方式快速定位内表赋值或者类…

VM中Ubuntu16.04的下载以及ROS—kinetic的版本下载

一、Ubuntu镜像地址 转载备份一下&#xff1b; 官方下载地址&#xff08;不推荐&#xff09; https://www.ubuntu.com/downloadhttps://www.ubuntu.com/download 中科大源 Index of /ubuntu-releases/16.04/http://mirrors.ustc.edu.cn/ubuntu-releases/16.04/ 阿里云开…