stm32 笔记 UART读取及HAL库应用

这篇具有很好参考价值的文章主要介绍了stm32 笔记 UART读取及HAL库应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 基本流程图

hal_uart_rxcpltcallback,# stm32,硬件,stm32,单片机,嵌入式硬件

 由此图可知:
采用HAL库,中断方式接收串口,只有当RxXferCount == 0 时,也就是调用这个函数,接收指定量的数据大小完成时,才会调用回调函数HAL_UART_RxCpltCallback()。

而且,RxXferCount == 0 后,也会使得中断退出,此时需要从新设置 HAL_UART_Receive_IT() 开启中断。

这里还需要注意下面两个函数的区别,HAL_UART_Receive_IT()HAL_UART_Receive()
分别为为非阻塞模式下接受数据,和阻塞模式下接受数据。

初始化 UART

void uart_init()
{
    UART_HandleTypeDef usart1_handler;
	//UART 初始化设置
	usart1_handler.Instance=USART1;					    //USART1
	usart1_handler.Init.BaudRate=115200;				    //波特率
	usart1_handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
	usart1_handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位
	usart1_handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位
	usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
	usart1_handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式
	HAL_UART_Init(&usart1_handler);					    //HAL_UART_Init()会使能UART1
}

 无需解释,只是 UART 的初始配置。

UART1 端口配置初始化

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10
		
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);	//设置中断优先级
		HAL_NVIC_EnableIRQ(USART1_IRQn);		//使能中断
	}
}

 上一段代码最后一行 HAL_UART_Init() 会自动调用这个端口初始化函数。因为 UART1 依赖于PA9 和 PA10 所以需要初始化这两个 GPIO 的配置,在最后两行中,为UART1 设置了中断优先级并使能。

中断响应函数

void  USART1_IRQHandler (void) 函数是串口1的中断响应函数,当串口1 发生了相应的中断后,就会跳到该函数执行。

void USART1_IRQHandler(void){
	HAL_UART_IRQHandler(&usart1_handler);
	HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
}

值得注意的是,每次相应中断后,就会关闭之后的相应。

需要调用 HAL_UART_Receive_IT() 从新注册这个相应中断。

中断相应回调函数

当 huart->RxXferCount 等于0时,HAL 就会帮我们调用 HAL_UART_RxCpltCallback 此函数才是真正的实现逻辑的地方。在下列函数中,会在读缓存区中取一个字符,并且通过串口回传给电脑。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	u8 rec;
	if(huart->Instance == USART1){
		rec = *((huart->pRxBuffPtr)-1);
		HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
	}
}

代码与执行结果

#include "sys.h"
#include "delay.h"

//初始化IO 串口1 
//bound:波特率
UART_HandleTypeDef usart1_handler;
u8 rdata[1];

void uart_init()
{
	//UART 初始化设置
	usart1_handler.Instance=USART1;					    //USART1
	usart1_handler.Init.BaudRate=115200;				    //波特率
	usart1_handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
	usart1_handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位
	usart1_handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位
	usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
	usart1_handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式
	HAL_UART_Init(&usart1_handler);					    //HAL_UART_Init()会使能UART1
}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10
		
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);	//设置中断优先级
		HAL_NVIC_EnableIRQ(USART1_IRQn);		//使能中断
	}
}

void USART1_IRQHandler(void){
	HAL_UART_IRQHandler(&usart1_handler);
	HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ //huart->RxXferCount 等于0 也就是读满rdata就执行这个回调函数
	u8 rec;
	if(huart->Instance == USART1){
		rec = *((huart->pRxBuffPtr)-1);
		HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
	}
}


int main(void)
{
    HAL_Init();                     //初始化HAL库    
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
	delay_init(180);
	
	uart_init();
	
	
	HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
	
	while(1){ //必须卡在死循环中,程序执行完毕就不能相应中断了
		delay_ms(3000);
	}
}

hal_uart_rxcpltcallback,# stm32,硬件,stm32,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-615239.html

到了这里,关于stm32 笔记 UART读取及HAL库应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 HAL库 STM32CubeMx -- 串口的使用(USART/UART)

    在上一篇博客里面写了串口通信的理论知识,在这一篇中将讲述串口通信在STM32CubeMx里面的配置,以及在函数里面怎么使用。 对于串口发送信息,分为三种方法: 串口阻塞方式收发 、 串口中断方式收发 、 串口DMA方式收发 。(DMA方式在之后的DMA章节讲解) 关于STM32CubeMx的基

    2024年02月06日
    浏览(74)
  • STM32 HAL库函数——HAL_UART_Transmit_IT()详解

    HAL_UART_Transmit_IT 函数的用法如下: 输入参数: huart :指向UART句柄结构体的指针,用于指定要使用的UART外设。 pData :指向要发送数据缓冲区的指针,可以是 uint8_t 类型或 uint16_t 类型的数据。 Size :要发送的数据大小,以数据元素( uint8_t 或 uint16_t )的数量表示。 返回值:

    2024年02月08日
    浏览(38)
  • STM32 HAL库函数——HAL_UART_Receive_IT()详解

    huart :UART句柄,指向要使用的UART外设。 pData :指向数据缓冲区的指针,用于存储接收到的数据。 Size :要接收的数据元素(u8或u16)的数量。 返回值类型为 HAL_StatusTypeDef ,表示函数执行的状态。可能的返回值有: HAL_OK :函数执行成功。 HAL_ERROR :函数执行过程中发生错误

    2024年02月08日
    浏览(43)
  • STM32-UART-DMA HAL库缓冲收发

    1.1、注意事项: HAL库的DMA底层基本都会默认开启中断使能,如果在STM32CubeMx禁用了中断相关的功能,程序可能会进入空中断回调出不来。 切记使用STM32-HAL库的DMA发送时需要开启USART中断和DMA中断。 在一般时间要求不是很高很高的场合,使用HAL库自带的函数就可以,并不会很频

    2024年01月18日
    浏览(46)
  • STM32 HAL库的HAL_UART_Transmit_IT使用方法

    是STM32 HAL库中非阻塞的串口发送函数。 用法:1. 调用HAL_UART_Transmit_IT()发送数据            2. 在HAL_UART_TxCpltCallback()里写上发送完成后的处理 注意: HAL_UART_Transmit_IT()要等待上次发送完成后再发送,否则返回HAL_BUSY。用huart-gState == HAL_UART_STATE_READY判断上次是否发送完成。 官方

    2024年02月16日
    浏览(39)
  • STM32 HAL 库 串口 函数HAL_UART_Transmit的BUG问题 及解决方法

    近期在开发图传项目的时候,由于需要发送的数据量及其庞大,因此在处理的时候, 发现STM32HAL库的串口函数,在处理海量数据的时候, 存在bug, 导致不能将指定数量的数据全部发送出去。  例如, 我以200个字节为一个数据包, 使用HAL_UART_Transmit函数,通过串口发送。 那么

    2024年02月13日
    浏览(37)
  • 关于STM32使用HAL_UART_Receive()无法接收数据的问题

    一、问题发现         在项目中我想通过阻塞的方式接收一段来自串口的数据,于是使用了HAL_UART_Receive函数,但跑起来发现一直超时接收不到。网上使劲搜但没搜到啥有用的结果,那只能自己捣鼓了。一开始怀疑是硬件的问题,于是用示波器直接连到对应的rx脚上,发现数据

    2024年02月11日
    浏览(50)
  • STM32基于CubeIDE和HAL库 基础入门学习笔记:功能驱动与应用

    文章目录: 一:LED与按键驱动程序 main.c 1.闪灯  led.h led.c  2.按键控制LED亮灭  key.h  key.c 二:蜂鸣器与继电器驱动程序 main.c 1.蜂鸣器 buzzer.h buzzer.c delay.h delay.c 2.继电器 relay.h relay.c 三:USART串口收发测试程序(超级终端) main.c retarget.h retarget.c usart.h usart.c 四:ADC与DMA驱动程序

    2024年02月13日
    浏览(36)
  • (stm32之HAL库)UART工作在DMA模式要打开串口中断吗?

    最近学习了stm32(F4xx)的串口在DMA模式下的使用,期间以ST官方提供的例程进行参考学习,发现其初始化过程中是打开了UART的中断的,而且HAL库中stm32f4xx_hal_uart.c文件中的DMA模式使用说明里也有这么一句话: 即在非循环模式下(也就是发完一次数据就停止的常用模式)需要配置

    2024年02月12日
    浏览(39)
  • stm32 hal库uart使用 DMA中断只能发送一次的问题

    1.stm32 uart使用DMA,无论发送还是接收都各自有一个数据流中断。这个数据流中断是框架代码不必过多关心。 2.使用了DMA后,uart的global中断是否要使用?标准做法是在cubemx上要勾选的,不然,就会产生只能发送一次的问题。 问题的原因? 我相信这是hal库的问题,理论上讲有一

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包