当前位置: 首页 > 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…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...