当前位置: 首页 > news >正文

3.串口(UART)

串口理论部分可看51部分:链接

数据帧 = 帧头(2字节,例如AA、BB) + 数据长度(2字节)+ 数据 + CRC16校验(2字节) + 帧尾(2字节)

代码编写

串口一发送命令控制LED灯(PB5、PE5)

LED灯、串口、串口打印浮点数据、串口重定向配置

LED灯配置请看:链接

串口配置:

串口配置

配置中断NVIC(嵌套向量中断控制器)

配置中断NVIC

配置DMA:

配置DMA

Cube IDE中串口打印浮点数据配置方法(参考):进入“Project→Properties”;显示界面如下。按照图片中的设置完成即可!

打印浮点数配置

串口重定向配置:

uint8_t u_buf[256];	//usart.c,24行#include <stdio.h>	//usart.h,32行
extern uint8_t u_buf[256];	//usart.h,38行
#define printf(...)  HAL_UART_Transmit(&huart1, (uint8_t *)u_buf, sprintf((char*)u_buf, __VA_ARGS__), 0xffff)	//usart.h,39行

轮询方式

缺点:

    必须要等待数据发送完或者等待时间超时,代码才会往下走

    必须要等待数据接收到固定的字节长度,超时,代码才往下走

Cube IDE代码

mian.c

/* USER CODE BEGIN Includes */
#include <string.h>	//26行
#include <stdio.h>	//27
/* USER CODE END Includes *//* USER CODE BEGIN PV */
uint8_t UART_Recv[5];	//48行
char UART_Str[30];		//49行
/* USER CODE END PV *///参数1:UART 模块的配置信息的指针,参数2:数据缓冲区的指针,参数3:接收字节长度,参数4:接收超时时间(单位为毫秒)
HAL_UART_Receive(&huart1, UART_Recv, 4, 1000);	//接收数据函数
if(strcmp("LED1", (char *)UART_Recv) == 0)	//字符串比较函数
{HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);memset(UART_Recv,'\0',5);	//替换字符函数,常用于清除指定空间
}if(!strcmp("LED2", (char *)UART_Recv))	//字符串比较函数
{HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);memset(UART_Recv,'\0',5);
}sprintf(UART_Str, "%f\n", 666.6);
//参数1:UART 模块的配置信息的指针,参数2:发送的字符串或字符数组,参数3:发送字节长度,参数4:接收超时时间(单位为毫秒)
HAL_UART_Transmit(&huart1, (char *)UART_Str, strlen(UART_Str), 1000);	//发送数据
printf("xinzai\n");	//配置串口重定向后才可使用

中断(IT)方式

Cube IDE代码


HAL_UART_RxCpltCallback(huart);	//stm32f1xx_hal_uart.c,3660行//stm32f1xx_hal_uart.c,2619行
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)	//中断回调函数

main.c

/* USER CODE BEGIN Includes */
#include <string.h>	//26行
#include <stdio.h>	//27行
/* USER CODE END Includes *//* USER CODE BEGIN PV */
uint8_t UART_Recv_IT[5];	//48行
char UART_Str[30];	//49行
/* USER CODE END PV *//* USER CODE BEGIN 2 */
//参数1:UART 模块的配置信息的指针,参数2:数据缓冲区的指针,参数3:接收字节长度
HAL_UART_Receive_IT(&huart1, UART_Recv_IT, 4);	//串口中断接收函数,95行
/* USER CODE END 2 *///while函数里
sprintf(UART_Str, "%d\n", 666);	//102
HAL_UART_Transmit_IT(&huart1, UART_Str, strlen(UART_Str));	//串口中断发送函数,103
HAL_Delay(1000);	//104//151行开始
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)	//串口中断接收触发函数
{if(huart == &huart1)	//判断传进来的串口是哪个{if(strcmp("LED1", (char *)UART_Recv_IT) == 0)	//字符串比较函数{HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);memset(UART_Recv_IT,'\0',5);	//替换字符函数,常用于清除指定空间}if(!strcmp("LED2", (char *)UART_Recv_IT))	//字符串比较函数{HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);memset(UART_Recv_IT,'\0',5);}//因为只能接受一次串口中断,所以在串口中断触发函数需要重新调用HAL_UART_Receive_IT(&huart1, UART_Recv_IT, 4);}
}
/* USER CODE END 4 */

空闲中断(IDLE) + DMA

不受接收字符长度影响,可以随意接收字符长度并判断

空闲状态:在多个字节传输结束后,通信线路将会维持高电平,这个状态称为空闲状态(没有数据传输时的空闲状态,数据传输刚结束的空闲状态)

空闲中断产生条件:在数据传输过程中,当CPU检测到通信线路处于空闲状态时,且空闲状态的持续时间大于一个字节传输时间时,空闲状态标志IDLE将由硬件置1,产生空闲中断

Cube IDE代码

//stm32f1xx_hal_uart.h,2710行
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)	//空闲中断接收回调函数

main.c

/* USER CODE BEGIN Includes */
#include <string.h>		//27行
/* USER CODE END Includes *//* USER CODE BEGIN PD */
#define RECV_Size 100	//37行
/* USER CODE END PD *//* USER CODE BEGIN 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, UART_Recv_IDLE, RECV_Size);	//空闲中断接收函数,94行
//数据接收RECV_Size一半时会重新触发中断,需要关闭DMA接收中断使能
HAL_NVIC_DisableIRQ(DMA1_Channel5_IRQn);	//96行
/* USER CODE END 2 *///150行
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)	//空闲中断接收触发函数
{if(huart == &huart1)	//判断传进来的串口是哪个{if(strcmp("LED1", (char *)UART_Recv_IDLE) == 0)	//字符串比较函数{HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);memset(UART_Recv_IDLE,'\0',Size);	//替换字符函数,常用于清除指定空间}if(!strcmp("LED2ON", (char *)UART_Recv_IDLE))	//字符串比较函数{//HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0);memset(UART_Recv_IDLE,'\0',Size);}else if(!strcmp("LED2OFF", (char *)UART_Recv_IDLE)){HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1);memset(UART_Recv_IDLE,'\0',Size);}//因为只能接受一次串口中断,所以在串口中断触发函数需要重新调用HAL_UARTEx_ReceiveToIdle_DMA(&huart1, UART_Recv_IDLE, RECV_Size);}}

相关文章:

3.串口(UART)

串口理论部分可看51部分&#xff1a;链接 数据帧 帧头(2字节&#xff0c;例如AA、BB) 数据长度&#xff08;2字节&#xff09; 数据 CRC16校验&#xff08;2字节&#xff09; 帧尾&#xff08;2字节&#xff09; 代码编写 串口一发送命令控制LED灯(PB5、PE5) LED灯、串口、…...

macOS Sonoma 14.6.1 (23G93) Boot ISO 原版可引导镜像下载

macOS Sonoma 14.6.1 (23G93) Boot ISO 原版可引导镜像下载 2024 年 8 月 8 日凌晨&#xff0c;macOS Sonoma 14.6.1 发布&#xff0c;本更新包含了重要的错误修复&#xff0c;并解决了导致高级数据保护无法启用或停用的问题。同时带来了 macOS Ventura 13.6.9 安全更新。 本…...

论企业私域流量运营中的玩法创新与开源 AI 智能名片 O2O 商城小程序的应用

摘要&#xff1a;本文旨在探讨企业在构建私域流量池时的多种玩法策略&#xff0c;并着重分析如何针对不同类型客户制定个性化方案。同时&#xff0c;引入开源 AI 智能名片 O2O 商城小程序这一工具&#xff0c;阐述其在私域流量运营中的重要作用和价值&#xff0c;为企业提升运营…...

nginx.conf alias 静态资源 别名 nginx配置

Linux系统Bug 报权限不足错误 user root; 解决server_name太长时报错的问题 #解决server_name太长时报错的问题server_names_hash_bucket_size 64; 解决文件上传默认限制1M的问题 #解决文件上传默认限制1M的问题client_max_body_size 100m; 监听所有端口 server_name _; a…...

pve虚拟机使用

文章目录 1.pve 直通硬盘 1.pve 直通硬盘 查看硬盘号&#xff1a; ls /dev/disk/by-id -lqm set 101 --virtio1 /dev/disk/by-id/usb-HIKSEMI__93963907-0:0挂载sata类型&#xff1a; qm set 101 --sata1 /dev/disk/by-id/ata-ST4000DM004-2U9104_WFN7TMVV可以将一个硬盘挂…...

Linux:进程概念详解

1. 冯诺依曼体系结构 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 。 【注意】&#xff1a; a. 这里的存储器指的是内存 b. 不考虑缓存情况&#xff0c;这里的CPU能且只能对内存进行读写&#xff0c;不能访问外设(输入或输出设备) c.外…...

cms框架cookice注入漏洞

目录 一、环境 二、开始分析 2.1代码审计&#xff08;未授权访问&#xff09; 一、环境 环境私聊获取 二、开始分析 2.1代码审计&#xff08;未授权访问&#xff09; 我们可以看到构造函数ip是通过X_FORWARDED_FOR来获取的&#xff0c;而这个刚好可以伪造&#xff0c;那我…...

RabbitMQ高级特性 - 非持久化 / 持久化(交换机、队列、消息)

文章目录 RabbitMQ 持久化机制概述实现非持久化(交换机、队列、消息)实现持久化(交换机、队列、消息)RabbitMQ 持久化机制 概述 前面讲到了 生产者消息确认机制 和 消费者消息确认机制,保证了消息传输的可靠性,但是这还不够,试想如果 Broker 突然崩溃,那么所有的 交换…...

OpenGL ES->工作机制

渲染流程 渲染目的&#xff1a;输入3D立体坐标&#xff0c;输出绘制后的2D平面像素工作流程&#xff1a;顶点着色器->图元装配->几何着色器->光栅化->片段着色器->测试与混合&#xff0c;整个工作流程被封装在GPU内部&#xff0c;无法改变。运行在CPU的代码调用…...

ue4.27 C++ 解析内容为json的字符串

json字符串为 R"({"x": -1870.0, "y": -11400.0})"&#xff0c;里面内容是个json对象。 const FString& Message R"({"x": -1870.0, "y": -11400.0})"; TSharedRef<TJsonReader<>> Reader TJs…...

图论③ | Java | 孤岛的总面积、沉没孤岛、水流问题 、建造最大岛屿

101. 孤岛的总面积 卡玛 101. 孤岛的总面积 https://kamacoder.com/problempage.php?pid1173 孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。 本题要求找到不靠边的陆地面积&#xff0c;那么我们只要从周边找到陆地然后 通过 dfs或者bfs 将周边靠陆地且相邻的陆地都…...

基于VEH的无痕HOOK

这里的无痕HOOK指的是不破坏程序机器码,这样就可以绕过CRC或MD5的校验。 VEH利用了Windows的调试机制和异常处理,人为抛出异常,从异常的上下文中获取寄存器信息。 DLL入口 // dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "pch.h" #include "CHoo…...

芯片内部如何实现过欠压功能?

大家好,这里是大话硬件。 在前面通过推送《芯片内部如何实现VREF参考稳压源?》实现了芯片内部VREF功能,今天分享一下芯片内部是如何实现过欠压保护。 UC3842芯片系列的数据手册如下: 从上面的描述可知,芯片在工作时,需要电压达到16V,但是电压跌落到10V后,芯片就不能工…...

Basic‘ attribute type should not be a container解决方法

在使用Spring Data JPA的时候&#xff0c;实体类中定义一个用List修饰的成员ip&#xff0c;IDEA会提示Basic‘ attribute type should not be a container错误&#xff0c;导致编译不通过。 查阅一些博客和文档说是Spring Data JPA这个框架会把实体类的属性当做是MySQL数据库中…...

Linkis-RPC的设计思想

我的技术网站 java-broke.site&#xff0c;有大厂完整面经&#xff0c;工作技术&#xff0c;架构师成长之路&#xff0c;等经验分享 Linkis-RPC的设计目标是提供一种灵活、可扩展的微服务间通信机制&#xff0c;支持以下功能&#xff1a; 异步请求与响应&#xff1a;支持请求方…...

31 - memmove()函数

文章目录 1 函数原型2 参数3 返回值4 示例 1 函数原型 memmove()&#xff1a;移动内存块&#xff0c;函数原型如下&#xff1a; void * memmove ( void * destination, const void * source, size_t num );cstring库描述如下&#xff1a; Move block of memory 1. Copies th…...

【深度学习】创建和训练Transformer神经网络模型,将葡萄牙语翻译成英语

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. 安装2. 数据处理2.1 下载数据集2.2 设置标记器2.3 使用tf.data设置数据管道 3. 测试数据集4. 定义组件4.1 嵌入和位置编码层4.2 添加并规范化4.3 基础注意力…...

[Qt][多元素控件]详细讲解

目录 0.前言1.List Widget2.Table Widget3.Tree Widget 0.前言 Qt中提供的多元素控件有&#xff1a; 列表&#xff1a; QListWidgetQListView 表格&#xff1a; QTableWidgetQTableView 树形&#xff1a; QTreeWidgetQTreeView Widget和View之间的区别&#xff0c;以QTableWi…...

/var/log/里面的文件具体是什么?linux的登录文件

1&#xff0c;什么是登录文件&#xff1f; linux系统官方对登录文件的定义解释我就不说了&#xff0c;我个人理解登录文件其实就是记录系统活动信息的几个文件&#xff0c;登录文件其实就是系统的日志文件。 比如linux系统默认是不会安装nginx的&#xff0c;nginx的日志为/var…...

JVM知识总结(双亲委派机制)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 双亲委派机制 双亲委派类加载过程 当App尝试加载一个类时&#x…...

【微知】Mellanox网卡配置异常?mlxconfig reset全解与实战场景指南

1. Mellanox网卡配置异常&#xff1f;先别慌 遇到Mellanox网卡配置异常时&#xff0c;很多工程师第一反应是重装驱动或者更换硬件。其实在大多数情况下&#xff0c;用对mlxconfig reset这个神器就能快速解决问题。我处理过上百台配备Mellanox网卡的服务器&#xff0c;发现80%的…...

利用 Worker Threads 优化 Vite 构建性能的实战

背景在我们的前端工程化实践中&#xff0c;随着项目规模的扩大&#xff0c;构建效率问题逐渐凸显。特别是在生产环境构建流程中&#xff0c;为了保护源码逻辑&#xff0c;我们通常会引入 JavaScript 混淆工具&#xff08;如 javascript-obfuscator&#xff09;。这一步虽然必要…...

快马AI一键生成:Mac系统OpenClaw自动化工具安装与原型验证脚本

今天在折腾一个自动化工具OpenClaw的安装&#xff0c;发现Mac系统下的配置过程有点繁琐&#xff0c;正好用InsCode(快马)平台快速生成了一个原型验证脚本&#xff0c;整个过程比想象中顺畅很多。记录下这个轻量级解决方案的实现思路&#xff0c;特别适合需要快速验证工具功能的…...

DistroAV技术解析:NDI网络视频传输的OBS插件解决方案

DistroAV技术解析&#xff1a;NDI网络视频传输的OBS插件解决方案 【免费下载链接】obs-ndi DistroAV (formerly OBS-NDI): NDI integration for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-ndi 在当今的直播和内容创作领域&#xff0c;网络视频传输技…...

LoRaFi库详解:面向SX1272/SX1273的Arduino LoRa通信开发指南

1. 项目概述LoRaFi 是一款面向 Arduino 平台的 LoRa 无线通信库&#xff0c;专为基于 Semtech SX1272/SX1273 射频芯片的硬件平台设计&#xff0c;核心适配对象为 LoRaFi 开发板&#xff08;含配套扩展板/模块&#xff09;。该库并非通用 LoRa 协议栈&#xff0c;而是聚焦于物理…...

SOLIDWORKS自定义属性模板制作全攻略:从零开始驱动模型参数

SOLIDWORKS自定义属性模板制作全攻略&#xff1a;从零开始驱动模型参数 在机械设计领域&#xff0c;SOLIDWORKS作为主流的三维CAD软件&#xff0c;其自定义属性功能往往被初学者低估。想象一下这样的场景&#xff1a;当你需要批量修改上百个零件的材料规格时&#xff0c;是否还…...

八股文的终结:为什么2026年大厂面试开始大规模考察“内存安全”?

在2026年的北美IT求职市场中&#xff0c;底层系统开发&#xff08;Infrastructure, Backend, Systems Engineering&#xff09;岗位的技术面试逻辑正在经历一场深刻的底层范式转换。过去几年中&#xff0c;候选人凭借熟练背诵C虚函数表、STL底层源码剖析、以及各类设计模式等标…...

2026年局部放电检测技术:全场景应用效能分析与绝缘诊断演进报告

摘要在2026年全球能源互联网纵深发展的背景下&#xff0c;电力系统及关键基础设施的绝缘安全已由“被动响应”全面转向“主动预警”。局部放电&#xff08;Partial Discharge, PD&#xff09;检测作为绝缘诊断的“哨兵”技术&#xff0c;其在多元化场景中的表现已成为衡量电力运…...

Halcon点云拼接实战:如何用特征模板搞定3D扫描缺失问题?

Halcon点云拼接实战&#xff1a;特征模板技术在工业3D扫描中的应用 在工业检测和逆向工程领域&#xff0c;3D扫描常常面临一个棘手问题——单次扫描无法完整捕获复杂物体的所有表面细节。想象一下&#xff0c;当您需要检测一个汽车发动机缸体的内部结构&#xff0c;或者重建一…...

Go语言中的网络编程

Go语言中的网络编程 1. 网络编程的基本概念 网络编程是指编写在网络上进行通信的程序。在Go语言中&#xff0c;网络编程主要通过net包来实现&#xff0c;支持TCP、UDP、HTTP等多种协议。 2. TCP服务器 2.1 基本TCP服务器 package mainimport ("fmt""net" )…...