串口接收中断配置过程---STM32F4--HAL

串口接收中断程序配置过程(HAL)
  1. 初始化相关参数,使能串口:
HAL_UART_Init();

该函数的参数是串口的基址,在stm32f429xx.h文件中,定义了8个UART_HandleTypeDef的值,分别是USART1、USART2、USART3、UART4、UART5、USART6、UART7、UART8,可以用HAL_UART_Init对这8个串口进行初始化,我们要用USART1,就填USART1

  1. 串口相关IO口配置,复用配置。在HAL_UART_MspInit中调用HAL_GPIO_Init函数

  2. 串口接收中断优先级配置和使能

HAL_NVIC_EnableIRQ();
HAL_NVIC_SetPriority();
  1. 使能串口接收中断
    所有的串口都使用HAL_UART_Receive_IT使能接收中断
HAL_UART_Receive_IT();
  1. 编写中断服务函数:USARTx_IRQHandler
    这个函数在startup_stm32f429xx.s中可以找到。
    不同的串口有不同的中断服务函数
void USARTx_IRQHandler(void) ;//(x=1~3,6)
void USARTx_IRQHandler(void) ;//(x=4,5,7,8)
具体配置过程

我们通过电脑把数据发送给STM32,STM32收到数据之后再把数据发送给电脑

  1. 初始化相关参数,使能串口
UART_HandleTypeDef usart_handler;	//定义为全局变量
void usart1_init(void)
{
	
	
	usart_handler.Instance = USART1;						//指定用哪个串口
	usart_handler.Init.BaudRate = 115200;					//波特率设置
	usart_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;		//硬件流控制
	usart_handler.Init.Mode = UART_MODE_TX_RX;				//接收or发送or接收发送
	//usart_handler.Init.OverSampling = 
	usart_handler.Init.Parity = UART_PARITY_NONE;			//奇偶校验
	usart_handler.Init.StopBits = UART_STOPBITS_1;			//停止位
	usart_handler.Init.WordLength = UART_WORDLENGTH_8B;		//字长
	HAL_UART_Init(&usart_handler);
	
}
  1. 串口相关IO口配置,复用配置。在HAL_UART_MspInit中调用HAL_GPIO_Init函数
//HAL_UART_Init会自动调用HAL_UART_MspInit

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)
	{
		GPIO_InitTypeDef GPIO_Initure;
		__HAL_RCC_GPIOA_CLK_ENABLE();
		__HAL_RCC_USART1_CLK_ENABLE();
		//GPIO口初始化就配置好了复用功能
		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_EnableIRQ(USART1_IRQn);
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);
	}
}

HAL_UART_Init初始化串口后,会自动调用HAL_UART_MspInit,我们在HAL_UART_MspInit里面初始化相关GPIO、设置中断优先级以及使能中断。

  1. 串口接收中断优先级配置和使能,在步骤2实现了

  2. 使能接收中断,我们在main函数里面加入一行代码来使能接收中断,该中断对所有的UART中断都产生影响。

HAL_UART_Receive_IT(&usart_handler,rdata,sizeof(rdata));

第一个参数usart_handler是UART_HandleTypeDef类型的句柄,第二个参数是接收数据存放的位置,第三个是位置大小。经过这四个步骤,我们就配置好了接收中断。

  1. 编写中断服务函数:USARTx_IRQHandler
void USART1_IRQHandler(void)	
{
	HAL_UART_IRQHandler(&usart_handler);
	HAL_UART_Receive_IT(&usart_handler,rdata,sizeof(rdata));
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)
	{
		HAL_UART_Transmit(huart,rdata,sizeof(rdata),1000);
		
	}
	
}

HAL提供了中断处理函数HAL_UART_IRQHandler,具体流程如下:
在这里插入图片描述

前面四个步骤是配置接收中断的,那么什么时候产生中断呢?
我们使能接收中断函数是:

HAL_UART_Receive_IT(&usart_handler,rdata,sizeof(rdata));

当接收的数据为sizeof(rdate)字节时,就会产生中断,进入USART1_IRQHandler函数,USART1_IRQHandler调用HAL库提供的中断处理函数HAL_UART_IRQHandler来判断中断类型,进而调用不同的处理函数。我们这里是接收中断,所以会进入UART_Receive_IT函数,把数据放到rdata,处理完毕后,UART_Receive_IT会自动调用HAL_UART_RxCpltCallback回调函数,这个函数我们是可以重写的,我们可以写出我们想要的逻辑处理功能函数,在这里调用HAL_UART_Transmit发送数据。

当接收完数据之后,系统会关闭中断,所以我们还需要打开中断,接收下一位数据,USART1_IRQHandler中调用HAL_UART_Receive_IT开启中断

具体main函数代码:

int main(void)
{
	//u8 buff[] = "send to rec";
	
	HAL_Init();
	Stm32_Clock_Init(360,25,2,8);
	delay_init(180);
	usart1_init();
	HAL_UART_Receive_IT(&usart_handler,rdata,sizeof(rdata));
	while(1)
	{
		
	}
	
}
结果

在这里插入图片描述

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是ESP8266-01S与STM32通信的HAL库示例代码: ```c #include "stm32f4xx_hal.h" #include <string.h> UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); char buffer[100]; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); while (1) { // 发送 AT 指令 strcpy(buffer, "AT\r\n"); HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); // 等待回复 HAL_Delay(1000); memset(buffer, 0, strlen(buffer)); HAL_UART_Receive(&huart2, (uint8_t *)buffer, 100, 1000); // 打印回复 printf("%s", buffer); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 上面的代码使用了STM32的USART2串口与ESP8266-01S通信,发送AT指令获取回复并打印。其中使用的函数有: - `HAL_UART_Transmit()`:用于发送数据到ESP8266-01S; - `HAL_UART_Receive()`:用于从ESP8266-01S接收数据; - `memset()`:用于清空缓冲区; - `printf()`:用于打印回复。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值