嵌入式学习笔记——STM32的USART收发字符串及串口中断
USART收发字符串及串口中断
- 前言
- 字符串的收发
- 发送一个字符串
- 接收字符串
- 需求
- 利用串口实现printf
- 中断
- 中断是什么
前言
上一篇中,介绍了串口收发相关的寄存器,通过代码实现了一个字节的收发,本文接着上面的内容,通过功能函数实现字符串的收发,然后引入中断解决收发过程中while()死等的问题。
字符串的收发
发送一个字符串
根据昨天的字符发送函数,只需要稍作修改即可实现发送函数了,一个字符串的结尾会有一个’\0’作为结束符,所以再发送过程中,只需要判断当前发送的字符是不是结束符即可,如果不是结束符就将该位发送至电脑的串口调试助手,如果是结束符,那就意味着一个字符串发送完毕了。具体代码如下:
/*******************************************
*函数名 :Usart1_Send_Str
*函数功能 :串口1发送一个字符串函数
*函数参数 :u8 *str
*函数返回值:无
*函数描述 :
*********************************************/
void Usart1_Send_Str(u8 *str)
{while(*str != '\0'){Usart1_Send_Byte(*str);str++;}
}
接收字符串
发送字符串相对容易,接收这边,就需要借用C语言中的数组来帮忙了,因为数据是一个字符一个字符的发送过来的,每一次只能接收一个字符,所以需要使用一个数组来存接收到的位,而且串口助手在发送字符串的时候是不会给单片机发送结束符,所以还需要编程者自己规定结束符,当然,后面引入空闲中断之后就不需要这样操作了。这里笔者使用的是‘#’作为结束标志。具体实现代码如下:
/*******************************************
*函数名 :Usart1_Receive_Str
*函数功能 :串口1接收一个字节函数
*函数参数 :void
*函数返回值:u8 str
*函数描述 :
*********************************************/
void Usart1_Receive_Str(void)
{static u8 i=0;//等待接收完成while(!(USART1->SR & (1<<5)));//将数据寄存器的数据读取到数组Str_Buff[i] = USART1->DR;i++;if(Str_Buff[i-1]=='#')//如果检测到结束标志‘#’{Str_Buff[i-1]= '\0';//手动给字符串添加‘\0’结束符i=0;Usart1_Receive_Str_Flag=1;//接收完成的标志位置一Usart1_Send_Str(Str_Buff);//将接受的数组再发回串口助手}
}
需求
使用串口调试助手发送11打开1号小灯,10关闭一号小灯,21打开二号小灯,20关闭二号小灯。效果如下:

主函数代码:

利用串口实现printf
在C语言的学习中,使用频率最高的输出函数就是printf了,这个函数在单片机上也同样适用,只是要改一下输出的方向,所以也叫重定向。
在C中printf函数-----输出函数
输出方向:PC机------>屏幕
在单片机中printf-------输出函数
输出方向: 单片机---->PC机
关于具体的修改其实KEIL已经帮我们做好了,需要我们修改的只有一个,就是将“stdio.h”内的fputc,也就是字符输出函数,修改到和我们的字符串输出函数关联即可。具体代码如下:
//printf的重定向函数
//fputc-----专门发送字符的函数h
int fputc(int c, FILE * stream)
{Usart1_Send_Byte(c);return c;
}
将此代码放到USART1.c中即可,不需要调用也不需要声明。

然后就是勾选KEIL的库,如下图所示,依次选择魔法棒、Target、然后将3所在位置的复选框锁定。

然后再在USART1.h中添加stdio.h。

最后在主函数中调用printf即可,printf主要是方便我们的后期调试,实用语法与C一致。

实际输出效果:

到这里,已经实现了字符串的收发,但是存在两个问题,
1是上位机发送数据到板子上必须要设置结束符,类似笔者此处的‘#’;
2是此代码在接收时会阻塞在等待接受完毕的while,这会导致其他的模块工作不正常,在while(1)内,一定要尽力避免死等的出现。
很明显,现在这个代码还不太令人满意,那么要怎么修改呢,在修改代码之前,需要先去了解一个新的东西——中断。

中断
首先,需要知道中断是个什么东西,它有什么作用,具体怎么使用,下面一一来进行介绍。
中断是什么
中断嘛,按照名字的第一反应是终止一件事,打断某些东西的感觉,实际上也差不多是这个意思,它终止和打断的就是前面我们编写的main函数里面的东西。

也就是说在程序正常运行过程中,出现了不正常的事件(异常),CPU会去处理这个异常,处理完之后再回到正常的程序中。这个异常事件就是中断。
中断的目的:由外设或者CPU创造一个异常事件(紧急事件)
紧急事件发生的时间和地点:未知
紧急事件是实时响应的,紧急事件不能执行太久(里面不能有延时 循环 阻塞程序)
下面我们来看一张图:
代码正常运行的时候是如下图所示的蓝色箭头方向,首先会依次向下执行初始化代码,然后进入while循环;
如果我们在初始化中,初始化了中断,就会有一个对应的中断服务函数,当中断的条件满足了,程序就会暂时终止main函数里面的内容,去八中断服务函数里面的内容执行完毕了再回来运行main里面的内容。

同时,从上图可以看出,当中断被初始化后,任何时刻都可能满足中断的条件,也就是在任何位置都可能会跳出main里面的内容去执行中断服务函数里面的内容。因此说它产生的时间和地点是未知的。
相关文章:
嵌入式学习笔记——STM32的USART收发字符串及串口中断
USART收发字符串及串口中断前言字符串的收发发送一个字符串接收字符串需求利用串口实现printf中断中断是什么前言 上一篇中,介绍了串口收发相关的寄存器,通过代码实现了一个字节的收发,本文接着上面的内容,通过功能函数实现字符串…...
数据分析之Pandas(1)
3.Pandas 文章目录3.Pandas3.1 Pandas基本介绍3.1.1 Pandas的基本数据结构3.1.1.1 Pandas库的Series类型3.1.1.2 Pandas库的DataFrame类型DataFrame初始化DataFrame查看数据3.1.2 Pandas读取数据及数据操作行操作添加一行删除一行列操作增加一列删除一列通过标签选择数据条件选…...
17、江科大stm32视频学习笔记——USART串口协议和USART串口外设
目录 1、通信接口 2、 硬件电路 3、电平标准 4、串口参数及时序 5、USART简介 6、USART工作 (1)写操作 (2)读操作 (3)帧头和帧尾的添加和除由电路自动执行 (4)硬件数据控制…...
leetcode:有效地括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都…...
四等分list
Testpublic void s (){ int targ 4; List mList new ArrayList(); List<List> mEndList new ArrayList<>(); for (int i 0; i <34; i) { mList.add(“item” i); } // System.out.println(mList.toString()); if (mList.size() % targ ! 0) { for (int j …...
php连接sqlserver数据库
docker 安装sqlserver数据库sudo docker pull mcr.microsoft.com/mssql/server:2017-latestsudo docker run -e "ACCEPT_EULAY" -e "MSSQL_SA_PASSWORD<YourStrongPassw0rd>" -p 1433:1433 --name sqlserver --hostname sqlserver -d mcr.microsoft.…...
The 2019 China Collegiate Programming Contest Harbin Site F. Fixing Banners
Problem - F - Codeforces 翻译: 哈尔滨,这个名字最初是一个满语单词,意思是“晒渔网的地方”,从松花江边的一个小农村居民点发展成为中国东北最大的城市之一。1898年,随着中国东部铁路的到来,这座城市首先…...
Maven的下载和配置
一、前言 一般按要求下载jar ,但是jar 包版本不好控制。有时候就会jar版本不同导致项目运行的结果也有差异,这样在团队开发中,在多个项目开发的是,jar包还要进行拷贝,可能也会出现版本还jar损坏的情况,所以一个能统一…...
服务高并发、高性能、高可用实现方案
服务高并发、高性能、高可用实现方案 软件开发的三高指标:高并发、高性能、高可用。 高并发方面要求QPS 大于 10万;高性能方面要求请求延迟小于 100 ms;高可用方面要高于 99.99%(4个9) 一、高并发: 高并发是现在互联网分布式框架设…...
uniCloud在线升级APP配置教程
app在线升级背景实现思路流程流程背景 因用户需要添加手机h5页面来进数据操作实现思路流程 实现流程图流程 相关文档:帮助文档 https://uniapp.dcloud.net.cn/uniCloud/cf-functions.html 注册服务空间 https://unicloud.dcloud.net.cn/pages/login/login uni升级…...
idea常用的快捷键
idea常用的快捷键Alt回车 导入包,自动修正CtrlN 查找类CtrlShiftN 查找文件CtrlAltL 格式化代码CtrlAltO 优化导入的类和包AltInsert 生成代码(如get,set方法,构造函数等)CtrlE或者AltShiftC 最近更改的代码CtrlR 替换文本CtrlF 查找文本CtrlShiftSpace 自动补全代码Ctrl空格 代…...
全志V85x硬件设计大赛作品精选第一期,快来Pick你心目中的最佳方案
1、V853-智能交互摄像头开发板 该参赛作品基于全志V853开发板制作的一款类似眼镜外挂的小产品,可以对场景进行辅助识别,并通过云端交互实现物联网控制,进一步实现物联网与人机交互的融合。 开发板配置了摄像头和小屏幕接口,并外…...
博客系统(界面设计)
✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录实现博客列表页预期效果导航栏页面主体左右布局左侧区域右侧区域完整代码实现博客详情页预期效果导航栏 左侧右侧完整代码实现…...
素材要VIP咋整?看python大展神通
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 再我们缺少素材的时候,我们第一反应 我们肯定会去网上寻找,但是!! 有的素材需要VIP!这可咋整呢? 看我利用python大展神通,采集某图网图片…...
[ vulnhub靶机通关篇 ] 渗透测试综合靶场 DC-1 通关详解 (附靶机搭建教程)
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...
软件测试文档编写步骤
编写软件测试文档是软件测试中非常重要的一部分。以下是编写软件测试文档的一些常见步骤: 1.明确软件测试的目标和目的:在开始编写软件测试文档之前,需要明确测试的目标和目的。这包括定义测试的范围,测试的目标和测试的优先级。 …...
重新认识下网页水印
使用背景图图片 单独使用 css 实现,使用 backgroundImage,backgroundRepeat 将背景图片平铺到需要加水印的容器中即可。 如果希望实现旋转效果,可以借助伪元素,将背景样式放到伪元素中,旋转伪元素实现: &l…...
Unity脚本练习
在C# 中 class 是创建类的标志,要创建类的话得现有class上面这个的逻辑是 类的访问权限, 关键字,类名以及类继承的父类在Unity中创建一个脚本或者添加一个组件,就相当于在Unity命名空间中创建了一个可以访问的类。这些类能够直接在…...
二十分钟带你了解JVM性能调优与实战进阶
ZGC 诞生原因 Java生态非常强大,但还不够,有些场景仍处于劣势,而ZGC的出现可以让Java语言抢占其他语言的某些特定领域市场。比如 谷歌主导的Android手机系统显示卡顿。证券交易市场,实时性要求非常高,目前主要是C主…...
对比应用层和内核层区别
一、所使用的空间不同: 应用层使用的空间是0-3G的用户空间。 内核层使用的是3-4G的内核空间。 二、打印信息所用函数不同: 应用层使用printf打印信息。 printf("打印信息\n"); 内核层使用printk打印信息。 …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
python数据结构和算法(1)
数据结构和算法简介 数据结构:存储和组织数据的方式,决定了数据的存储方式和访问方式。 算法:解决问题的思维、步骤和方法。 程序 数据结构 算法 算法 算法的独立性 算法是独立存在的一种解决问题的方法和思想,对于算法而言&a…...
Unity基础-Mathf相关
Unity基础-Mathf相关 一、Mathf数学工具 概述 Mathf是Unity中封装好用于数学计算的工具结构体,提供了丰富的数学计算方法,特别适用于游戏开发场景。它是Unity开发中最常用的数学工具之一,能够帮助我们处理各种数学计算和插值运算。 Mathf…...
