【STM32】HAL库——串口中断通信(二)

2023-05-16

由于调试过程中发现Proteus 8有些许bug,串口中断采用STM32F103RCT6开发板进行讲解

前期准备:

  1. STM32CubeMX
  2. STM32F103RCT6开发板
  3. IDE Keil(MDK-ARM)

STM32CubeMX部分


1. 配置时钟

选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚
在这里插入图片描述

将HCLK设置为最大频率72MHz
在这里插入图片描述

2.配置USART

在这里插入图片描述
选择:
USART1串口1
Baud Rate(波特率):115200 Bits/s
Work Length(传输数据长度): 8 Bit
Parity(奇偶校验位) : 无
STOP Bits(停止位) :1
Data Direction(数据方向) : 发送和接收都使能

设置完之后就会自动配置USART1_RXUSART1_TX两个引脚

接着在NVIC Settings一栏设置使能全局中断
在这里插入图片描述

3.配置IO口

将PC4,PC5,PB0,PB1设置为:
高电平
Output模式
既不上拉也不下拉
响应速度高

3. 工程生成

在这里插入图片描述

在这里插入图片描述
工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成。



MDK 5部分

· HAL_UART_Transmit();串口发送数据,使用超时管理机制 
· HAL_UART_Receive();串口接收数据,使用超时管理机制
· HAL_UART_Transmit_IT();串口中断模式发送  
· HAL_UART_Receive_IT();串口中断模式接收
· HAL_UART_Transmit_DMA();串口DMA模式发送
· HAL_UART_Transmit_DMA();串口DMA模式接收
· HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  //串口中断处理函数
· HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);  //串口发送中断回调函数
· HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);  //串口发送一半中断回调函数(用的较少)
· HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  //串口接收中断回调函数
· HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
· HAL_UART_ErrorCallback();串口接收错误函数

讲两个常用的函数

  • HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)//串口中断接收数据
    UART_HandleTypeDef * huart:串口号
    uint8_t * pData:存放数据的数组
    uint16_t Size:接收的数据长度
    设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断,再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)

例:HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);

  • HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //中断回调函数
    中断进行完之后,并不会直接退出,而是会进入中断回调函数中,我们在其中写入代码即可

例:void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
用户自定义的代码
}

1. 重定义Printf函数

先在main.c添加

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

然后在stm32f1xx_hal.c中添加
在这里插入图片描述

#include "stm32f1xx_hal.h"
#include <stdio.h>
extern UART_HandleTypeDef huart1;   //声明串口

接着重写fgetc和fputc函数
在这里插入图片描述

/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

然后在while里就可使用Printf函数了
在这里插入图片描述

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		printf("测试\r\n");
		HAL_Delay(1000);
  }

编译下载时需要选择相对应的下载器,勾选以下
在这里插入图片描述

打开串口助手,设置
波特率:115200
停止位:1
数据位:8
奇偶校验:无
在这里插入图片描述
可以看到Printf能正常使用

2. 重写中断回调函数

在usart.c文件中添加如下代码

/* USER CODE BEGIN 0 */
#include "stdio.h"
#include "string.h"

#define RXBUFFERSIZE  256     //最大接收字节数

char RxBuffer[RXBUFFERSIZE];  //接收数据
uint8_t aRxBuffer;			      //接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0;     //接收缓冲计数
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
 
	if(Uart1_Rx_Cnt >= 255)  //溢出判断
	{
		Uart1_Rx_Cnt = 0;
		memset(RxBuffer,0x00,sizeof(RxBuffer));
		HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); 	
	}
	else
	{
		RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;   //
	
		if(aRxBuffer == '1')//当发送1时,翻转电平
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
		}
		else if(aRxBuffer == '2')//当发送2时,翻转电平
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
		}
		else if(aRxBuffer == '3')//当发送3时,翻转电平
		{
			HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_5);
		}
		else if(aRxBuffer == '4')//当发送4时,翻转电平
		{
			HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4);
		}
		
		
		if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
      	    while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
			Uart1_Rx_Cnt = 0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
		}
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //因为接收中断使用了一次即关闭,所以在最后加入这行代码即可实现无限使用
}
/* USER CODE END 1 */

接着去main.c中加入 extern uint8_t aRxBuffer;

/* USER CODE BEGIN Includes */
#include "stdio.h"
extern uint8_t aRxBuffer;	//声明变量
/* USER CODE END Includes */

接着开启接收中断
在这里插入图片描述

HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);

开启一次后进入中断回调函数,因为在中断回调函数中添加了此函数,即可一直等待发送数据以此进入中断



在这里插入图片描述
可以看到发送的数据被正常返回

接下来发送1 2 3 4看看灯是否能正常亮灭

本期工程文档——>Gitee

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【STM32】HAL库——串口中断通信(二) 的相关文章

  • 初始化 ST-Link 设备时出错 - 无法连接到设备

    我目前正在使用 ST Link 调试器对我的 STM32F3 Discovery 板进行编程 我使用的IDE是Atollic TrueStudio 5 5 2 现在我面临一个非常奇怪的问题 那就是我不断收到消息 初始化 ST Link 设备
  • 在地址“0xXXXXXX”处中断,没有可用的调试信息,或在程序代码之外

    配置 使用 Nucleo L476RG 使用 GNU ARM Eclipse 我从 STM32CubeMX 生成了一个极简代码 我已经在我的板载 ST Link 中刷新了 J link 驱动程序 一直在尝试为我的代码运行调试器 但我的程序计
  • GCC - 如何停止链接 malloc?

    我正在努力将我的代码缩减到最小的骨架大小 我使用的是只有 32k 闪存的 STM32F0 需要很大一部分闪存用于数据存储 我的代码已经有大约 20k 闪存大小 其中一些是由于使用了 STM32 HAL 函数 我可以在以后需要时对其进行解释和
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • rt-thread studio中新建5.02版本报错

    先吐槽一下 rt thread studio出现BUG真多 好多时间都是在找BUG 但里面用好多控件还是挺好用的 真是又爱又恨 所以一般使用功能不多的话还是用keil多一点 创建5 02版本工程之后直接进行编译 直接会报下面这个错误 资源
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • STM32F103概要

    The STM32F103x4 STM32F103x6 STM32F103xC STM32F103xD and STM32F103xE are a drop in replacement for STM32F103x8 B medium d
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • 库函数点亮Led

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • 通过JTAG恢复STM32 MCU磨掉的标记

    我有一块可能带有 STM32 MCU 的板 我想为该板制作定制固件 因为库存板有很多问题 不幸的是 电路板制造商很友善地磨掉了所有标记 有没有办法通过 jtag 获取设备 系列 ID 并将其交叉引用到型号 我能找到的一切都是关于获取芯片的唯
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后

随机推荐

  • 平常使用的小问题【Windows11开启不了热点,开启热点后连不上去】

    故障现象 xff1a xff08 1 xff09 连接设备一直显示obtaining ip address xff08 2 xff09 电脑没有显示连接的设备 解决措施 xff1a xff08 1 xff09 先转到设置 xff08 2 x
  • IOException: No such file or directory 问题解决

    文章目录 问题描述 xff1a 注册权限动态申请权限总结 xff1a 问题描述 xff1a Android开发 xff0c 在访问文件夹创建文件的时候 xff0c 报错IOException No such file or director
  • 2020(春)工程伦理MOOC期末考试答案

    单选题 多选题 判断题
  • Git中Fork使用

    GitLab或者GitHub中的Fork可以理解为一个物理副本 xff0c 用来管理代码的一种手段 在参与开源项目代码贡献时 xff0c 通常不会直接获得源代码仓库的Developer权限 这点和一般公司开发不太一样 xff0c 公司一般都
  • 在OK6410上运行QT程序找不到libQtGui.so.4的解决

    想在OK6410上运行自己经过交叉编译的QT程序 xff0c OK6410上烧写的是光盘所带的Linux系统 xff0c 运行程序时出现以下现象 xff1a qt server error while loading shared libr
  • Docker的安装

    这篇文章原文是我2016年10月份写的 xff0c 当时在研究docker xff0c 上周六不经意翻了出来 xff0c 由于3月换工作 xff0c 新环境比较忙 xff0c 没时间写些东西 xff0c 所以先把之前写的东西放一下 xff0
  • CRAZEPONY飞控学习(一)

    在不久前曾研究过最近最为流行的开源飞控Pixhawk的源代码 xff0c 但是由于在这之前没有接触过操作系统这个概念 xff0c 在不知道代码执行流程的情况下看了几个星期的时间 xff0c 脑子里还是一团乱 xff0c 所以决定还是从裸机开
  • PHP常用的设计模式

    php常用的设计模式 xff1a 1 单例模式 xff08 构造方法私有化 xff0c 对外提供实例化对象的静态调用方法 xff09 class Site span class token punctuation span public s
  • 003.多线程-主线程、守护线程、用户线程的区别

    对于线程的分类 xff0c 我们可以简单划分为 xff1a 主线程 xff08 每个进程只有一个主线程 xff09 子线程 主线程 xff1a main方法 子线程 xff1a 非主线程皆是子线程 子线程中可以简单划分为 xff1a 守护线
  • Ubuntu中在当前目录下打开终端

    在Ubuntu中 xff0c 打开终端可以通过Ctrl 43 Alt 43 T来打开 xff0c 但其打开的是 下的 xff0c 如果进入指定的目录 xff0c 便需要通过cd命令来进行切换 xff0c 故本文提供一个可以通过鼠标右键来在当
  • C语言经典面试题100道(校对详解版)

    题目非本人整理 xff0c 转载于https blog csdn net qq 42613510 article details 81225935 做了校对与详解 xff0c 方便大家参考 最后编程答案自己做的 xff0c 还没写完 xff
  • 浅谈FreeRTOS任务启动与切换流程

    一个轻量级操作系统最核心的地方就在于任务的执行与切换 xff0c 像FreeRTOS和ucOS 在任务启动与切换方面都差不多 xff0c 本文主要从枝干而省去了所有细枝末节让你最快的了解操作系统的任务创建与切换 以正点原子FreeRTOS移
  • 状态机编程思维学习笔记(C语言)

    前言 不摸鱼摆烂的第一天 目录 前言C语言面对对象特性引入函数指针结构体中套用函数指针宏定义中 纯替换 状态机概念状态机实现后文 C语言面对对象特性引入 众所周知 xff0c C 43 43 是由C语言编写而成 xff0c 因此 xff0c
  • stm32串口中断收发数据环形缓冲区的设计

    Function Name USART2 IRQHandler Description This function handles USART2 global interrupt request Input None Output None
  • 多线程的守护线程和等待线程结束方法

    守护线程的含义是 xff1a 如果当前运行的所有线程都是守护线程 xff0c 则程序直接结束 package thread 64 ClassName Test7 64 Author 瞿肖 64 Date 2022 7 11 14 32 pu
  • 用数学规划的方式求解优化问题

    本文介绍如何用数学语言对实际中的优化问题进行建模 通过建立数学模型 我们利用现成的求解器可以便捷地计算出最优解 或可行解 运输问题 考虑三个粮食储量分别是100 200 300的仓库 单位 吨 下文省略 我们需要把粮食运送给4个客户 其需求
  • 操作系统磁盘管理

    文章目录 01 知识概述部分02 课程知识回顾说明03 磁盘管理知识体系结构04 磁盘管理物理结构05 磁盘管理分区操作问题 xff1a 新添加硬盘无法识别 分区操作1 xff1a fdisk xff08 操作时可看10点的视频 xff09
  • ROS学习——Rviz(更新中)

    固定架 两个框架中最重要的是固定框架 固定框架是用于表示 世界 框架的参考框架 这通常是 地图 或 世界 或类似名称 xff0c 但也可以是例如里程表框架 如果将固定框架错误地设置为例如机器人的底座 xff0c 则机器人曾经见过的所有物体都
  • Boost型Ladrc控制双闭环电路 双闭环控制

    Boost型Ladrc控制双闭环电路 双闭环控制 xff08 1 xff09 电压外环采用简化Ladrc控制器 xff0c 简化线性自抗扰控制 xff0c 采用PD控制 43 三阶LESO状态观测器 xff0c xff08 2 xff09
  • 【STM32】HAL库——串口中断通信(二)

    由于调试过程中发现Proteus 8有些许bug xff0c 串口中断采用STM32F103RCT6开发板进行讲解 前期准备 xff1a STM32CubeMXSTM32F103RCT6开发板IDE Keil xff08 MDK ARM x