STM32开发——串口通讯(第1篇)——蓝牙(非中断+中断)

news2024/11/25 20:48:34

目录

1.串口简介

2.非中断接收发送字符

3.中断接收字符


1.串口简介

通过中断的方法接受串口工具发送的字符串,并将其发送回串口工具。

串口发送/接收函数:

  • HAL_UART_Transmit(); 串口发送数据,使用超时管理机制
  • HAL_UART_Receive(); 串口接收数据,使用超时管理机制
  • HAL_UART_Transmit_IT(); 串口中断模式发送 
  • HAL_UART_Receive_IT(); 串口中断模式接收
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout)

作用:以阻塞的方式发送指定字节的数据
形参 1 :UART_HandleTypeDef 结构体类型指针变量
形参 2:指向要发送的数据地址(指针),(用数组时不用取地址)(用字符变量需要取地址&)
形参 3:要发送的数据大小,以字节为单位  strlen(ch)
形参 4:设置的超时时间,以ms单位,最大0xffff

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size)

作用:以中断的方式接收指定字节的数据
形参 1 是 UART_HandleTypeDef 结构体类型指针变量
形参 2 是指向接收数据缓冲区
形参 3 是要接收的数据大小,以字节为单位
此函数执行完后将清除中断,需要再次调用以重新开启中断。

串口中断回调函数:

  • HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
  • HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //发送中断回调函数
  • HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //接收中断回调函数

状态标记变量:
USART_RX_STA

从0开始,串口中断接收到一个数据(一个字节)就+1。当数据读取全部OK时候(回车和换行
符号来的时候),那么 USART_RX_STA的最高位置设置1。接收到0x0D(回车)设置第二位为1.

2.非中断接收发送字符

需求:
接受串口工具发送的字符串,并将其发送回串口工具。
硬件接线:
TX -- A10
RX -- A9

串口配置:
1. 选定串口

 2. 选择模式
异步通讯

 3. 串口配置

 4. 使用MicroLIB库
从魔术棒打开,这个勾勾一定要打上,否则 printf 无法重映射!

 编程实现:

#include <stdio.h>
#include <string.h>
unsigned char ch[20] = {0};
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
main函数里:
unsigned char ch[20] = {0};
HAL_UART_Transmit(&huart1, "hello world\n", strlen("hello world\n"), 100);
while(1)
{
HAL_UART_Receive(&huart1, ch, 19, 100);
//HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
printf(ch);
memset(ch, 0, strlen(ch));
}

3.中断接收字符

需求:
通过中断的方法接受串口工具发送的字符串,并将其发送回串口工具。

串口配置:
前4步同上
5. 打开中断

 编程实现:

#include <stdio.h>

uint8_t buf;
unsigned char ch[200] = {0};

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 100);
	return ch1;
}


//重写串口中断服务函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数据
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到过0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,开始下一次接收
					UART1_RX_STA|=0x8000;
				//如果这个数不是0x0a换行
				}else{
					//接收失败,数据清空
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到过0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状态为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不是0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
				}
	
			}
		}
		//重新开启串口中断接收
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}

//main函数中代码
//打开串口1接收中断  接收到的字符存在buf里,有一个字符 
HAL_UART_Receive_IT(&huart1, &buf, 1);

  while (1)
  {
    /* USER CODE END WHILE */
	
    /* USER CODE BEGIN 3 */
		//如果sta高位为1
		if((UART1_RX_STA & 0x8000)){
			//打印收到的数据,清空ch,情空sta
			printf("recevied word:");
			HAL_UART_Transmit(&huart1,ch,UART1_RX_STA & 0x3fff,0xffff);
			printf("\r\n");
			while(huart1.gState != HAL_UART_STATE_READY);
			//memset(ch,0,200);
			UART1_RX_STA=0;
		}
		printf("hello world.\r\n");
		HAL_Delay(1000);
		
  }

4.蓝牙插座_风扇_灯

项目需求:通过蓝牙透传功能控制IO口

 非中断代码

#include "string.h"
#include "stdio.h"

int fputc(int ch1,FILE *f)
{
	unsigned char temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return ch1;
}

//main函数中代码
	char ch[10]={0};


	HAL_UART_Transmit(&huart1, (const uint8_t *)"hello world.", strlen("hello world."), 100);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_UART_Receive(&huart1,(uint8_t *)ch,10,100);  //不能用strlen(ch)其是有效字符 可以用sizeof数组大小
		printf("%s",ch);
		if(!strcmp((const char *)ch, "open")) {
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
			printf("led1已经打开.\r\n");
		}else if(!strcmp((const char *)ch, "close")) {
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
			printf("led1已经关闭.\r\n");			
		}else{
			if(ch[0]!='\0')
				printf("输出指令错误:%s,其strlen(%s)为%d sizeof(为) %d \r\n",ch,ch,strlen(ch),sizeof(ch));
		}
		memset(ch,0,10);
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/630049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java+Springboot+Vue的二次元商城网站设计与实现

博主介绍&#xff1a;✌擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案…

手写nacos

目录 背景过程Demo1端Demo2端SDK端Serve端1、某一个服务启动&#xff0c;将此服务信息放到注册表中2、当注册表中有新添加的信息&#xff0c;遍历整个注册列表&#xff0c;每个服务都拉下来一份新的注册列表3、哪个服务中的配置文件发生过改变&#xff0c;就让哪个服务重新拉取…

微软的三门课程帮你入门AI

现在AI技术如火如荼的&#xff0c;还没有入门AI技术的&#xff0c;可能在找一些入门的资料&#xff0c;现在好很多大公司都推出了自己的学习课程&#xff0c;这里整理了三门微软推出的课程&#xff0c;希望能一步一步的带你进入AI的技术大门。 Getting started with Python 这…

Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合

1、Flume进阶 1.1 Flume事务 1.2 Flume Agent内存原理 1、ChannelSelector ChannelSelector的作用就是选出Event将要被发往哪个Channel。其共有两种类型&#xff0c;分别是Replicating&#xff08;复制&#xff09;和Multiplexing&#xff08;多路复用&#xff09;。 Replicat…

Django-入门

文章目录 一、Django框架介绍二、后台管理第一步:项目的创建与运行第二步:应用的创建和使用第三步: 项目的数据库模型第四步: 启用后台Admin站点管理 三、前台管理第一步: URLconf 路由管理第二步: 视图函数处理业务逻辑第三步: 模板管理实现好看的HTML页面&#xff08;可参考菜…

一文带你读懂:TCP连接的三次握手和四次挥手(下篇)

天下没有不散的宴席&#xff0c;对于 TCP 连接也是这样&#xff0c; TCP 断开连接是通过四次挥手方式。下面我们通过实操&#xff0c;来彻底理解四次挥手。 对TCP连接建立三次握手感兴趣的同学&#xff0c;可以看我上一篇文章&#xff1a;一文带你读懂&#xff1a;TCP连接的三次…

[环境配置]让sd自动翻译提示词插件sd-webui-prompt-all-in-one安装

安装方式 方式一&#xff08;使用git克隆&#xff09;&#xff1a; 此方法需要你的电脑上安装了 git&#xff0c;如果没有安装&#xff0c;可参考 git 官方文档 进行安装。 打开终端&#xff0c;进入到你的 stable-diffusion-webui 目录下。 使用 git 克隆 sd-webui-prompt…

RobinKarp(字符串哈希)---分析与实现(C++)

1. 简述 给定字符串pattern和串text。求串pattern在串text中出现的位置。 暴力比较是逐个字符比较来确定两个串是否相等&#xff0c;若当前比较失败 则回到开始字符对应字符的后一个字符重复过程。 哈希就是一个大范围到小范围的映射 字符串哈希则是通过比较两个串的哈希值相…

Leetcode 剑指 Offer II 030. 插入、删除和随机访问都是 O(1) 的容器

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 设计一个支持在平均 时间复杂度 O(1) 下&#xff0c;执行以下操作…

使用NLPAUG 进行文本数据的扩充增强

在机器学习中&#xff0c;训练数据集的质量在很大程度上决定了模型的有效性。我们往往没有足够的多样化数据&#xff0c;这影响了模型的准确性。这时数据增强技术就派上了用场。 数据增强可以通过添加对现有数据进行略微修改的副本或从现有数据中新创建的合成数据来增加数据量…

代码随想录训练营Day53|1143.最长公共子序列;1035.不相交的栈;53.最大子序和

1143.最长公共子序列 class Solution {public int longestCommonSubsequence(String text1, String text2) {int[][] dp new int[text1.length()1][text2.length()1];for(int i1;i<text1.length();i){for(int j1;j<text2.length();j){if(text1.charAt(i-1)text2.charAt(…

12性能提升:如何提升gRPC系统性能

这篇文章我们来一起学习下如何提升gRPC系统服务的性能。 gRPC 是一个高性能、开源的 RPC 框架,设计目标是支持多种编程语言和多种平台。它基于 Google 发布的 Protobuf(Protocol Buffers)序列化协议,可以在不同的应用程序之间传输数据。gRPC 具有高效率和可扩展性的特点,…

python3 爬虫相关学习7:使用 BeautifulSoup下载网页图片到本地文件夹

目录 1 一个爬图片pic的代码的例子 1.1 学习的原文章 1.2 原始代码的问题总结 问题1 问题2 问题3 其他问题 1.3 原始代码 2 直接在cmd里 python运行报错 和 处理 2.1 运行报错 2.2 报错原因&#xff1a; 没有提前安装这个bs4 模块 2.3 如何提前知道我的python环境…

【微信小程序】wxml、wxss、js、json文件介绍

&#x1f609;博主&#xff1a;初映CY的前说(前端领域) ,&#x1f4d2;本文核心&#xff1a;微信小程序的入门介绍 【前言】书接上回&#xff0c;我们知道了一个小程序的构成结构&#xff0c;接下来我们来进一步学习小程序的目录结构中的.wxml、.wxss、.js、.json。 目录 ⭐ 一…

一学就会-----链表中倒数第K个节点

文章目录 题目描述思路一代码示例思路二代码示例 题目描述 输入一个链表&#xff0c;输出该链表中倒数第k个结点。 图片示例&#xff1a; 思路一 由于这道题目并没有要求时间复杂度&#xff0c;我们完全可以先遍历一遍链表&#xff0c;得到链表的结点总数&#xff08;count&am…

利用Zookeeper实现集群选举

什么是Zookeeper 分布式开源协调系统&#xff0c;数据模型简单&#xff0c;可以实现同步&#xff0c;配置管理&#xff0c;分组管理&#xff0c;分命名空间管理等。 技术本质 一个原子消息传递系统&#xff0c;它使所有服务器保持同步 FLP(3个科学家名字命名) 理论角度&…

【Spring Security】的RememberMe功能流程与源码详解,基础-进阶-升级-扩展,你学会了吗?

文章目录 前言原理 基础版搭建初始化sql依赖引入配置类验证 源码分析 进阶版集成源码分析疑问1疑问2 鉴权 升级版集成初始化sql配置类验证 源码分析鉴权流程 扩展版 前言 之前我已经写过好几篇权限认证相关的文章了&#xff0c;有想复习的同学可以查看【身份权限认证合集】。今…

OpenAI官方提示词课(三)如何总结文章

现在是信息爆炸时代&#xff0c;打开手机&#xff0c;各种文章扑面而来。我们的精力是有限的。如果有人帮忙把文章总结好给我们&#xff0c;这不就节省了很多时间嘛&#xff01;我们也就可以阅读更多的文章了。 恰好大语言模型在总结文章方面非常有天赋。 下面来看看示例。 …

数学基础第二天

介绍 对于Hissian矩阵是正定的&#xff0c;在这一点是整个范围内的最小值&#xff0c;y在各个方向的二阶导数都是>0的 对于Hissian矩阵是负定的&#xff0c;在这一点是整个范围内的最大值&#xff0c;y在各个方向的二阶导数都是<0的, 对于Hissian矩阵是不定的&#xff…

有了这个工具,支付宝商家多个账号下的账单管理更方便了

大家好&#xff0c;我是小悟 为方便拥有多个支付宝账号的商家获取自身业务、资金数据及下载对账单的能力&#xff0c;为商家提供了商家账单产品&#xff0c;商家可以通过该产品系统化接入账单数据&#xff0c;实现支付宝商家多个账号账单管理的功能。 为拥有多个支付宝账号的…