嵌入式软件--stm32 DAY 6 USART串口通讯(下)
1.寄存器轮询_收发字符串
通过寄存器轮询方式实现了收发单个字节之后,我们趁热打铁,争上游,进阶到字符串。字符串就是多个字符。很明显可以循环收发单个字节实现。
然后就是接收字符串。如果接受单个字符的函数放在while里,它也可以实现一个一个的接收字符串,在一定时间戳下,效果等同。
然后我们要想想如何整合,写成一个函数。
2.问题解答,状态位清零
我们的编程方式,一个是寄存器写法,一个是hal库写法。还有的就是实现思路。
//发送一个字符
void USART_SendChar(uint8_t ch)
{//判断TDR是否为空,必须等待TDR为空才能写入数据,也就是继续发送while((USART1->SR & USART_SR_TXE)==0){}//将要发送的数据写入TDRUSART1->DR = ch;
}
初始的时候,TDR的存储寄存器肯定为空
关于状态位清零,TXE和RXNE都可以自动清零。
只要发数据,就自动清零。
RXNE也是一样,只要读RDR,就会清零。
3.串口通讯 寄存器中断方式
复制上一个工程文件,把改删除的删掉。
主要配置中断管理NVIC
中断服务函数
main.c
#include "usart.h"
#include "delay.h"
#include <string.h>
//定义接收缓冲区和接收数据长度
uint8_t buff[100];
uint8_t size;
int main(void)
{//1.初始化USART_Init();//发送单个字符USART_SendChar('A');USART_SendChar('\n');//发送字符串uint8_t str[]="Hello World!\n";USART_SendString(str,strlen((char *)str));while(1){}}
usart.c
#include "usart.h"//初始化
void USART_Init(void)
{//开启时钟RCC->APB2ENR |= RCC_APB2ENR_USART1EN;RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;//GPIO工作模式// PA9:TX 复用推挽输出,CNF=10,MODE=11GPIOA->CRH |= GPIO_CRH_MODE9;GPIOA->CRH |= GPIO_CRH_CNF9_1;GPIOA->CRH &= ~GPIO_CRH_CNF9_0;// PA10:RX 浮空输入,CNF=01,MODE=00GPIOA->CRH &= ~GPIO_CRH_MODE10;GPIOA->CRH &= ~GPIO_CRH_CNF10_1;GPIOA->CRH |= GPIO_CRH_CNF10_0;//串口模块设置//设置波特率 115200USART1->BRR = 0x271;//使能串口和收发模块USART1->CR1 |= USART_CR1_UE;USART1->CR1 |= (USART_CR1_TE|USART_CR1_RE);//配置数据帧格式USART1->CR1 &=~ USART_CR1_M; //长度为8位的数据,没有校验位USART1->CR1 &=~ USART_CR1_PCE; //无校验,不使用校验位USART1->CR2 &=~ USART_CR2_STOP; //1位停止位//使能串口接收中断USART1->CR1 |= USART_CR1_RXNEIE;USART1->CR1 |= USART_CR1_IDLEIE;//配置NVICNVIC_SetPriorityGrouping(3);NVIC_SetPriority (USART1_IRQn,2);NVIC_EnableIRQ(USART1_IRQn);}//发送一个字符
void USART_SendChar(uint8_t ch)
{//判断TDR是否为空,必须等待TDR为空才能写入数据,也就是继续发送while((USART1->SR & USART_SR_TXE)==0){}//将要发送的数据写入TDRUSART1->DR = ch;
}//发送字符串,数组可以用指针表示,形参就是数组和字长
void USART_SendString(char *str,uint8_t size)
{uint8_t i = 0;for ( i = 0; i < size; i++){USART_SendChar(str[i]);}}//引入外部变量
extern uint8_t buff[100];
extern uint8_t size;//中断服务程序
void USART1_IRQHandler(void)
{//判断是RXNE=1还是IDLE=1if (USART1->SR & USART_SR_RXNE){//如果RXNE=1,表示接收到一个字符
buff[size]=USART1->DR;
size++;}else if (USART1->SR & USART_SR_IDLE){USART1->DR;//如果IDLE=1,表示检测到空闲帧,字符串接收完毕USART_SendString(buff,size);size=0;}}
usart.h
#ifndef __USART_H
#define __USART_H
#include "string.h"
#include "stm32f10x.h"
//初始化
void USART_Init(void);//发送一个字符
void USART_SendChar(uint8_t ch);//发送一个字符串,数组可以用指针表示,形参就是数组和字长
void USART_SendString(char *str,uint8_t size);#endif
我们可以将接收字符串的标志位在外面定义出来。
4.串口案例一串口通讯_hal库轮询方式
我们有usart1配置。
我们反正还得需要配,这个时候我们可以不管他,直接去左边框栏中点点点。图形化配置的精髓就是方便。
还是调用hal库简单。
轮询方式使用效率不是很高,中断方式才高。
5.HAL库中断方式—定长数据接收
记住USART1用异步模式,要打开中断实现
中断方式要和回调函数结合。
接收定长数据,会和之前接收的数据结合分析
6.HAL库中断方式--变长数据接收
接收变长数据,size是可接收的字长上限。
她的回调不一样,是下面这个。在函数面前加void,我忘了加,编译出错。
先检查是什么模块
7.重定向printf—寄存器方式
用printf输出调试信息,打印到屏幕,没有屏幕也可重定向printf,把数据打印到串口,从而在电脑端接收调试信息,这是一种有效调试手段。
printf大法对任何语言都是有用的。
printf的底层函数:fputc
把字符一个个发到控制台文件里。
重写也在usart.c里,记得引入<stdio.h>
8.重定向——hal
usart.c里
在main函数来随便打印。
相关文章:

嵌入式软件--stm32 DAY 6 USART串口通讯(下)
1.寄存器轮询_收发字符串 通过寄存器轮询方式实现了收发单个字节之后,我们趁热打铁,争上游,进阶到字符串。字符串就是多个字符。很明显可以循环收发单个字节实现。 然后就是接收字符串。如果接受单个字符的函数放在while里,它也可…...

问题处理——在ROS2(humble)+Gazebo+rqt下,无法显示仿真无人机的相机图像
文章目录 前言一、问题展示二、解决方法:1.下载对应版本的PX42.下载对应版本的Gazebo3.启动 总结 前言 在ROS2的环境下,进行无人机仿真的过程中,有时需要调取无人机的相机图像信息,但是使用rqt,却发现相机图像无法显示…...
69、微服务保姆教程(十二)容器化与云原生
容器化与云原生 在微服务架构中,容器化和云原生技术是将应用程序部署到生产环境的核心技术。通过容器化技术,可以将应用程序及其依赖项打包成一个容器镜像,确保在任何环境中都能一致运行。而云原生技术则通过自动化的容器编排系统(如 Kubernetes),实现应用的动态扩展、自…...

朱老师,3518e系列,第六季
第一节:概述。 首先是 将 他写好的 rtsp 源码上传,用于分析。 已经拷贝完。 第二节: h264 编码概念。 编解码 可以用cpu, 也可以用 bsp cpu 编解码的效果不好。做控制比较好。 h264 由 VCL, NAL 组成。 NAL 关心的是 压缩…...

ElasticSearch-集群
本篇文章依据ElasticSearch权威指南进行实操和记录 1,空集群 即不包含任何节点的集群 集群大多数分为两类,主节点和数据节点 主节点 职责:主节点负责管理集群的状态,例如分配分片、添加和删除节点、监控节点故障等。它们不直接…...

一文掌握工业相机选型计算
目录 一、基本概念 1.1 物方和像方 1.2 工作距离和视场 1.3 放大倍率 1.4 相机芯片尺寸 二、公式计算 三、实例应用 一、基本概念 1.1 物方和像方 在光学领域,物方(Object Space)是与像方(Image Space)相对的…...
记录心态和工作变化
忙中带闲的工作 其实工作挺忙的, 总是在赶各种功能点. 好巧的是iOS那边因为上架的问题耽搁了一些时间, 从而让Android的进度有了很大的调整空间. 更巧的是后端那边因为对客户端的需求不是很熟悉, 加上Android海外这块的业务他也是第一次接触. 所以需要给他留一些时间把各个环节…...
深入理解 TypeScript 中的 unknown 类型:安全处理未知数据的最佳实践
在 TypeScript 的类型体系中,unknown 是一个极具特色的类型。它与 any 看似相似,却在安全性上有着本质差异。本文将从设计理念、核心特性、使用场景及最佳实践等方面深入剖析 unknown,帮助开发者在处理动态数据时既能保持灵活性,又…...

LabVIEW机械振动信号分析与故障诊断
利用 LabVIEW 开发机械振动信号分析与故障诊断系统,融合小波变换、时频分布、高阶统计量(双谱)等先进信号处理技术,实现对齿轮、发动机等机械部件的非平稳非高斯振动信号的特征提取与故障诊断。系统通过虚拟仪器技术将理论算法转化…...
Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)
文章目录 Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)需求方法1:使用Helm覆盖值方法2: 在Lens中临时修改Deployment配置步骤 1: 创建 Docker Registry Secret步骤 2: 在 Deployment 中引用 Secret参考资料Helm配置之为特定Deployment配置特定Docker仓库(覆…...

【Spring】Spring中的适配器模式
欢迎来到啾啾的博客🐱。 记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。 欢迎评论交流,感谢您的阅读😄。 目录 适配器模式Spring MVC的适配器模式 适配器模式 适配器模式(Adapter Pattern&a…...
GO学习指南
GO学习指南 主题一 go语言基础知识讲解 go语言面向对象编程 go语言接口详解 go语言协程 主题二 web基础知识 后续内容请大家持续关注,每月一主题,让各位读者能零基础、零成本学习go语言...

2、ubuntu系统配置OpenSSH | 使用vscode或pycharm远程连接
1、OpenSSH介绍 OpenSSH(Open Secure Shell)是一套基于SSH协议的开源工具,用于在计算机网络中提供安全的加密通信。它被广泛用于远程系统管理、文件传输和网络服务的安全隧道搭建,是保护网络通信免受窃听和攻击的重要工具。 1.1…...
MySQL面试知识点详解
一、MySQL基础架构 1. MySQL逻辑架构 MySQL采用分层架构设计,主要分为: 连接层:处理客户端连接、授权认证等 服务层:包含查询解析、分析、优化、缓存等 引擎层:负责数据存储和提取(InnoDB、MyISAM等&am…...
小白入门:GitHub 远程仓库使用全攻略
一、Git 核心概念 1. 三个工作区域 工作区(Working Directory):实际编辑文件的地方。 暂存区(Staging Area):准备提交的文件集合(使用git add操作)。 本地仓库(Local…...

RPC与SOAP的区别
一.RPC(远程过程调用)和SOAP(简单对象访问协议)均用于实现分布式系统中的远程通信,但两者在设计理念、协议实现及应用场景上存在显著差异。 二.对比 1.设计理念 2.协议规范 3.技术特性 4.典型应用场景 5.总结 三.总结…...

Day11-苍穹外卖(数据统计篇)
前言: 今天写day11的内容,主要讲了四个统计接口的制作。看起来内容较多,其实代码逻辑都是相似的,这里我们过一遍。 今日所学: Apache ECharts营业额统计用户统计订单统计销量排行统计 1. Apache ECharts 1.1 介绍 A…...

Tomcat简述介绍
文章目录 Web服务器Tomcat的作用Tomcat分析目录结构 Web服务器 Web服务器的作用是接收客户端的请求,给客户端作出响应。 知名Java Web服务器 Tomcat(Apache):用来开发学习使用;免费,开源JBoss࿰…...

《从零开始:Spring Cloud Eureka 配置与服务注册全流程》
关于Eureka的学习,主要学习如何搭建Eureka,将order-service和product-service都注册到Eureka。 1.为什么使用Eureka? 我在实现一个查询订单功能时,希望可以根据订单中productId去获取对应商品的详细信息,但是产品服务和订单服…...
如何保证RabbitMQ消息的顺序性?
保证RabbitMQ消息的顺序性是一个常见的需求,尤其是在处理需要严格顺序的消息时。然而,默认情况下,RabbitMQ不保证消息的全局顺序,因为消息可能会通过不同的路径(例如不同的网络连接或线程)到达队列…...

FPGA学习知识(汇总)
1. wire与reg理解,阻塞与非阻塞 2. 时序取值,时钟触发沿向左看 3. ip核/setup debug 添加 ila 一、ila使用小技巧 二、同步复位、异步复位和异步复位同步释放 设计复位设计,尽量使用 异步复位同步释放;尽管该方法仍然对毛刺敏感…...
c语言 写一个五子棋
c语言 IsWin判赢 display 画 10 x 10 的棋盘 判断落子的坐标是否已有棋子 判断落子坐标范围是否超出范围 // 五子棋 #include <stdio.h> #include <stdlib.h>// 画棋盘 10 x 10的棋盘,len为行数 void display(char map[][10], int len) {system(&q…...

Redisson分布式锁-锁的可重入、可重试、WatchDog超时续约、multLock联锁(一文全讲透,超详细!!!)
本文涉及到使用Redis实现基础分布式锁以及Lua脚本的内容,如有需要可以先参考博主的上一篇文章:Redis实现-优惠卷秒杀(基础版本) 一、功能介绍 (1)前面分布式锁存在的问题 在JDK当中就存在一种可重入锁ReentrantLock,可重入指的是在同一线…...
Python爬虫实战:研究源码还原技术,实现逆向解密
1. 引言 在网络爬虫技术实际应用中,目标网站常采用各种加密手段保护数据传输和业务逻辑。传统逆向解密方法依赖人工分析和调试,效率低下且易出错。随着 Web 应用复杂度提升,特别是 JavaScript 混淆技术广泛应用,传统方法面临更大挑战。 本文提出基于源码还原的逆向解密方法…...
WordPress Relevanssi插件时间型SQL注入漏洞(CVE-2025-4396)
免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...
Adobe Illustrator学习备忘
1.移动画板:需按住空格键加鼠标一块才能拖动 2.放大缩小画板:按住Alt键加鼠标滚轮 3.撤回:CtrlZ 4.钢笔练习网站:The Bzier Game...
C#中的dynamic与var:看似相似却迥然不同
在C#编程的世界里,var和dynamic这两个关键字常常让初学者感到困惑。它们看起来都在定义变量时省略了显式类型声明,但实际上它们的工作方式和应用场景有着天壤之别。今天,让我们一起揭开这两个关键字的神秘面纱。 var:编译时的类型…...
求职困境:开发、AI、运维、自动化
文章目录 问:我的技术栈是web全栈(js,css,html,react,typscript),C开发,python开发,音视频图像开发,神经网络深度学习开发,运维&#…...

语言模型:AM-Thinking-v1 能和大参数语言模型媲美的 32B 单卡推理模型
介绍 a-m-team 是北科 (Ke.com) 的一个内部团队,致力于探索 AGI 技术。这是一个专注于增强推理能力的 32B 密集语言模型。 a-m-team / AM-Thinking-v1 是其旗下的一个语言模型,采用低成本的方式能实现和大参数模型媲美。 DeepSe…...

ChatGPT:OpenAI Codex—一款基于云的软件工程 AI 代理,赋能 ChatGPT,革新软件开发模式
ChatGPT:OpenAI Codex—一款基于云的软件工程 AI 代理,赋能 ChatGPT,革新软件开发模式 导读:2025年5月16日,OpenAI 发布了 Codex,一个基于云的软件工程 AI 代理,它集成在 ChatGPT 中,…...