STM32-CubeIDE用串口通讯
USART串口通讯
一、轮询模式
1.设置所接引脚为UART异步模式
- 选择完成CTRL+S保存。
2.编写测试代码(自动发送hello world)
- 在mian函数里面编写代码
- 原函数
- 调用函数,需要数据类型一致,使用函数通过串口发送数组里面的数据
- 打开串口助手测试
- 选择对应的端口,波特率需要一致。
3.编写接收数据的代码
- 通过串口助手测试代码正常使用。
二、中断模式收发
1.打开URAT的中断功能,然后保存自动生成代码
2.使用中断发送数据
3.使用中断接收数据
- 串口使用中断模式来接收信息,没有等待时间,如果程序写在while循环中,会有这次数据还没有接收完成就去接收下次数据的情况,所以需要将对应程序写在中断函数的回调函数中。
- 在stm32f1xx_hal_uart.c文件中,有一个回调函数,我们可以重新定义其内容
- 将定义的数组改成全局变量
/* USER CODE BEGIN PV */
uint8_t receiveData[2];
/* USER CODE END PV */
- 复制回调函数到main.c文件中,重新定义回调函数
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {HAL_UART_Transmit_IT(&huart1, receiveData, 2);GPIO_PinState state = GPIO_PIN_SET; if (receiveData[1] == '1') {state = GPIO_PIN_RESET;if (receiveData[0] == 'L') {HAL_GPIO_WritePin(GPIOB, LED_MCU_Pin, state);}}if (receiveData[1] == '0') {state = GPIO_PIN_SET;if (receiveData[0] == 'L') {HAL_GPIO_WritePin(GPIOB, LED_MCU_Pin, state);}}HAL_UART_Receive_IT(&huart1, receiveData, 2); //每次执行完回调函数内容后,要继续为下次接收开启串口接收数据
}
/* USER CODE END 0 */
3.串口使用DMA模式接收发送数据
- 无论用上面哪种方式,询问或者中断,都会占用CPU,所以可以使用DMA来搬运数据,等搬运完成触发中断就可以去处理。减少了对CPU的占用率。
- 开启DMA功能。
- 将串口中断函数改成DMA函数,修改其后缀即可,其他不变。
- 下载调试发现程序正常,正常接收发送数据。
4.串口接收不定长数据
- 我们可以认为空闲(ldle)中断发生时,就是一帧数据包接收完成了,此时再对数据进行分析处理即可。
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData));/* 接收空闲中断,接收长度是最大长度。而不是接收数据的长度。可以设置为数组的长度。而数组的长度要尽量大。不至于溢出 */
- HAL_UARTEx_ReceiveToIdle_DMA对应的回调函数不是之前RxCpltCallback回调函数了,而是RxEventCallback这个回调函数了。
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {if (huart == &huart1) { //判断触发的中断是哪个中断HAL_UART_Transmit_DMA(huart, receiveData, Size); //将接收的数据发送回去HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData)); //重新启动接收函数}
}
- 下载代码,连接电脑发送数据,单片机可以正常接收到数据并且执行RxEventCallback()函数,而不是执行RxCpltCallback()这个回调函数。
- 上面虽然实现了功能,但是当接收数据达到接收数组的一半时,也会有产生中断,使得一半之后的数据接收不到,所以需要在接收数据之后将接收过半中断给关闭了
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData));/* 接收空闲中断,接收长度是最大长度。而不是接收数据的长度。可以设置为数组的长度。而数组的长度要尽量大。不至于溢出 */__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
5.蓝牙透传模块BT24
- BT24蓝牙透传模块可以通过串口收发数据,BT24蓝牙模块默认波特率为9600,所以需要将波特率设置为9600,手机可以下载DX-SMART这个APP连接蓝牙模块,并且进行数据的收发。
- 添加DMA通道:在 USART1 -> Configuration -> DMA Settings 标签卡中,点击 Add 按钮,分别添加 USART3_RX 和 USART3_TX 的 DMA 通道
- 使能串口中断:在 USART1 -> Configuration -> NVIC Settings 标签卡中,勾选 USART1 global interrupt 的 Enable
- 代码部分
- 定义全局变量 receiveData 作为串口接收数组,由于是不定长数据的接收,因此缓冲区大小可以根据实际需求调整,只能大不能小,否则可能会丢失数据。
/* USER CODE BEGIN PV */
uint8_t receiveData[50];
/* USER CODE END PV */
- 在 main 函数中,使用 HAL_UARTEx_ReceiveToIdle_DMA 函数开启不定长数据DMA接收,注意:需要关闭DMA传输过半中断,我们只需要接收完成中断,此函数是以空闲中断作为接收完成的标志,而不是接收长度,因此可以接收任意长度的数据。
/* USER CODE BEGIN 2 */HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData)); //通过DMA将数据接收并存到receiveData数组中__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); //关闭DMA传输过半中断,只需要接收完成中断。/* USER CODE END 2 */
- 在中断函数 HAL_UARTEx_RxEventCallback 中,处理接收到的数据,所有的串口接收和发送操作都在中断函数中进行,不会阻塞主程序。下面代码功能是接收到数据之后确人是蓝牙所连接口接收到的之后,发送回去,并对数据进行解析从而控制LED灯的亮或者灭。
- 数据包含了(包头,数据长度,功能数据,校验和)。包含由自己决定,下面例子包头是0xAA,第二位是长度,接着是控制LED的亮灭(0x00表示输出低电平,0x01表示输出高电平),之后是控制的哪个LED(0x01表示第一个LED,0x02表示第二个LED,0x03表示第三个LED),最后是前面所有数据的总和来当作一个验证方式。
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {if (huart == &huart1) {HAL_UART_Transmit_DMA(&huart1, receiveData, Size);if (receiveData[0] == 0xAA) {if (receiveData[1] == Size) {uint8_t sum = 0;for (uint8_t i = 0; i < Size - 1; i++) {sum = sum + receiveData[i];}if (sum == receiveData[Size - 1]) {for (uint8_t i = 2; i < Size - 1; i += 2) {GPIO_PinState state = GPIO_PIN_SET;if (receiveData[i + 1] == 0x00) {state = GPIO_PIN_RESET;} else {state = GPIO_PIN_SET;}if (receiveData[i] == 0x01) {HAL_GPIO_WritePin(GPIOA, LED1_Pin, state);} else if (receiveData[i] == 0x02) {HAL_GPIO_WritePin(GPIOA, LED2_Pin, state);} else if (receiveData[i] == 0x03) {HAL_GPIO_WritePin(GPIOA, LED3_Pin, state);}}}}}HAL_UARTEx_ReceiveToIdle_DMA(&huart1, receiveData, sizeof(receiveData));__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);}
}
- 手机通过蓝牙将数据发送到BT24模块,单片机通过串口连接蓝牙模块可以接收数据。
- 打开手机APP连接好蓝牙模块之后,发送0xAA, 0x09, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0xBC,单片机接收到之后发送回来,手机也会接收到这个数据,并且将LED1,LED2,LED3三个LED灯全部点亮,确认代码无误。
相关文章:

STM32-CubeIDE用串口通讯
USART串口通讯 一、轮询模式 1.设置所接引脚为UART异步模式 选择完成CTRLS保存。 2.编写测试代码(自动发送hello world) 在mian函数里面编写代码 原函数 调用函数,需要数据类型一致,使用函数通过串口发送数组里面的数据 打开串…...

FloodFill 算法(DFS)
文章目录 FloodFill 算法(DFS)图像渲染岛屿数量岛屿的最大面积被围绕的区域太平洋大西洋水流问题扫雷游戏衣橱整理 FloodFill 算法(DFS) 漫水填充(Flood Fi)算法是一种图像处理算法,在计算机图形学和计算机视觉中被广泛…...

计算机通信与网络实验笔记
1.LINUX通过版本号判断是否为稳定版本 2.计网基础 (CD),默认二层以太网交换机。 (10)物理层是均分(除以),数据链路层及以上是不除的。 3.传输介质: (1&…...

闲聊【干龙头】的重要性
市场面临转势,我们不知道谁会先涨,资金量大的操作必然会提前布局,而我们需要做的就是睁大眼睛,等待最强的那只股票出现,然后闭着眼睛进入就可以了。 追涨操作为什么都出现在大盘大涨情况下。原因简单,不能确…...

Ubuntu22.04安装RTX3080
Ubuntu22.04安装RTX3080 1 安装基础环境 更新依赖包 sudo apt-get update sudo apt-get upgrade2 安装驱动 (1)查看适合的显卡驱动 # 查看可用的驱动 sudo ubuntu-drivers devices# 返回值,推荐版本:nvidia-driver-550 ERROR…...

嵌入式学习-IO进程-Day04
嵌入式学习-IO进程-Day04 进程的函数接口 fork和Vfork 回收进程资源 wait waitpid 退出进程 获取进程号(getpid,getppid) 守护进程 守护进程的特点 创建步骤 exec函数族 线程 概念 线程和进程的区别 线程资源 线程函数接口 创建线程ÿ…...

RAII - 安卓中的智能指针
RAII - 安卓中的智能指针 概念 sp wp RefBase 是什么 system/core/libutils/RefBase.cpp system/core/libutils/include/utils/RefBase.hsystem/core/libutils/StrongPointer.cpp system/core/libutils/include/utils/StrongPointer.hAndroid在标准库之外,自定义…...

linux--库指令
ldd ldd 可执行文件路径 显示依赖的库的查找路径以及是否查找到了。...

展讯方案-内置多张开机logo
1. 开机图片的资源存放在logo分区中,这个分区中可以存放一个xx.bmp文件,也可以存放一个bin文件(1logo.bin,包含多张压缩的图片集合) 2.平台代码中logo.bin是由mk_1ogo_img.py脚本打包,具体如下(…...

Stable Diffusion模型资源合集(附整合包)
(模型资源在ComfyUI、WebUI以及ForgeUI中都通用) 之前的Stable Diffusion笔记受到了不少小伙伴的关注,很感谢大家的建议和支持。有很多小伙伴私信我问我一些AI绘画的模型资源在哪来下载,一般来说有两个网站比较常用,分…...

机器学习|Pytorch实现天气预测
机器学习|Pytorch实现天气预测 🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 电脑系统:Windows11 显卡型号:NVIDIA Quadro P620 语言环境:python 3.9.7 编译器&#x…...

【Kuberntes】k8s权限管理
文章目录 权限管理概述核心概念配置RBAC创建Role和ClusterRole创建RoleBinding和ClusterRoleBinding 默认角色和角色绑定权限的实现注意事项 如何在 Kubernetes 中实现 RBAC 的细粒度权限控制?1. Role和ClusterRole2. RoleBinding和ClusterRoleBinding3. 配置RBAC4.…...

C++,STL 033(24.10.15)
内容 queue容器(队列)的常用接口。 代码 #include <iostream> #include <string> #include <queue> // 注意包含queue容器(队列)的头文件using namespace std;class Person { public:string m_Name;int m_Age…...

AdmX_new
0x00前言 因为环境问题,此次靶场都放在vm上。都为NAT模式。 靶机地址: https://download.vulnhub.com/admx/AdmX_new.7z 需要找到两个flag文件。 0x01信息搜集 搜集IP 确认目标IP为172.16.8.131,进一步信息搜集 获取端口开放情况,版本信…...

【python3】函数注解
Python 函数注解 (Function Annotations) Python 函数注解 (Function Annotations)函数注解的基本语法基本语法格式示例 特殊类型注解注解信息的存储与访问函数注解的实际用途注意事项小结 函数注解是 Python 的一种特性,用于为函数的参数和返回值添加 元数据。注解…...

leetcode hot100 之【LeetCode 42. 接雨水】 java实现
LeetCode 42. 接雨水 题目描述 给定一个非负整数数组 height 表示柱状图中每个柱子的高度,请你计算按此排列的柱状图能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面的柱状图可以…...

10月18日,每日信息差
第一、现代汽车集团在上海举办了中国前瞻技术研发中心的发布及启新庆典,宣布成立其全资法人公司 —— 现代前瞻汽车技术开发(上海)有限公司。该中心是集团在海外建立的首个前瞻技术研发中心,专注于自动驾驶、智能座舱、共享出行等…...

Axure科技感元件:打造可视化大屏设计的得力助手
Axure,作为一款专业的原型设计工具,凭借其强大的设计功能、丰富的组件库和灵活的交互能力,成为了许多设计师打造科技感设计的首选工具。其中,Axure科技感元件更是以其独特的魅力和实用性,在数据可视化大屏、登录界面、…...

【模板】最近公共祖先(LCA)倍增
P3379 P3379 【模板】最近公共祖先(LCA) # 【模板】最近公共祖先(LCA) ## 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。 ## 输入格式 第一行包含三个正整数 $N,M,S$&#…...

我的JAVA项目构建
1.Maven maven就是pip 设置maven下载的的jar包位置 换源 下载插件maven-search 配置dependency 2.Tomcat 设置环境变量JAVA_HOME 设置编码方式 方框就是路径的前缀 3.Servlet 新建项目 写一个类继承HttpServlet,复写doGet(应对Get请求),doPost(应对…...

应用层协议 序列化
自定义应用层协议 例子:网络版本计算器 序列化反序列化 序列化:将消息,昵称,日期整合成消息-昵称-日期 反序列化:消息-昵称-日期->消息,昵称,日期 在序列化中,定义一个结构体…...

【HAD】Half-Truth: A Partially Fake Audio Detection Dataset
文章目录 Half-Truth: A Partially Fake Audio Detection Dataset背景key points研究数据集设计评价指标实验基线:utterance-level分类(话语级)基线:segment-level分类(片段级)Half-Truth: A Partially Fake Audio Detection Dataset 会议/期刊:Interspeech 2021 CCF-C…...

OpenAI Prompt generation - 生成和优化Prompt的Prompt
OpenAI Prompt generation - 生成和优化Prompt的Prompt 从头开始创建 Prompt 可能很耗时,所以快速生成 Prompt 可以帮助我们提高效率。 下面是 OpenAI 提供的协助生成 Prompt 的 Prompt。 from openai import OpenAIclient OpenAI()META_PROMPT ""&qu…...

Android技术探索:深入解析Android组件
Android系统以其开放性和多样性,成为了众多开发者的首选平台。在Android应用的开发中,组件(Components)是构建应用的基础元素。深入了解Android组件,对于开发者来说至关重要。本文将详细探讨Android的四大核心组件&…...

使用R-GCN处理异质图ACM的demo
加载和处理数据集 import torch from torch_geometric.datasets import HGBDataset from torch_geometric.transforms import RandomLinkSplit# 加载ACM数据集,这是一个包含论文(paper)、主题(subject)以及它们之间关…...

征程 6E DISPLAY 功能介绍及上手实践
01 功能概述 本文将带大家一起实现单路、多路 MIPI CSI TX 输出、IDU 回写、IDU oneshot 模式、绑定输出 VPS 数据等功能,此处主要介绍各 sample 的实现与使用方法。 02 软件架构说明 本文中绑定 VPS 输出功能基于 libvio API 实现,调用 libvio 提供的…...

安卓窗口wms/input小知识NO_INPUT_CHANNEL剖析
背景: 经常在学员的vip技术群里经常有很多学员会提问一些不太常见的窗口和input的相关的问题,虽然不太常见,但确实是工作中会遇到的一些问题,所以马哥有必要进行一下记录这些窗口技术知识点。 具体分享技术点: input中…...

【2024最新版】Win10下 Java环境变量配置----适合入门小白
首先,你应该已经安装了 Java 的 JDK 了(如果没有安装JDK,请跳转到此网址:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html) 笔者安装的是 jdk-8u91-windows-x64 接下来主要讲怎么配…...

Servlet 生命周期详解及案例演示(SpringMVC底层实现)
文章目录 什么是Servlet?Servlet生命周期简介1. 初始化阶段:init()方法示例代码: 2. 请求处理阶段:service() 和 doGet()、doPost()方法示例代码: 3. 销毁阶段:destroy()方法示例代码: Servlet生…...

2024 kali系统2024版本,可视化界面汉化教程(需要命令行更改),英文版切换为中文版,基于Debian创建的kali虚拟机
我的界面如下所示 1. 安装 locales sudo apt install locales 2. 生成中文语言环境 sudo locale-gen zh_CN.UTF-8 如果你希望安装繁体中文,可以加入: sudo locale-gen zh_TW.UTF-8 3. 修改 /etc/default/locale 文件 确保有以下内容 LANGzh_CN.UT…...