标签:初始 mod 注意 ret 遇到 取消 prevent data complete
1 void USART1_IRQHandler(void) 2 { 3 HAL_UART_IRQHandler(&UartHandle); //该函数会清空中断标志,取消中断使能,并间接调用回调函数 4 }
③在文件“stm32l4xx_hal_uart.h”中,我们可以看到串口接收回调函数的定义。使用“_weak”关键字定义的函数,其具有如下特性: 一般情况下和一般函数相同。但是当有一个同名函数但是不带__weak被定义时,所有对这个函数的调用都是指向后者(不带__weak那个)。也就是说,ST官方提供的这个回调函数需要我们自己进行改写。
1 /** 2 * @brief Rx Transfer completed callback. 3 * @param huart UART handle. 4 * @retval None 5 */ 6 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 7 { 8 /* Prevent unused argument(s) compilation warning */ 9 UNUSED(huart); 10 11 /* NOTE : This function should not be modified, when the callback is needed, 12 the HAL_UART_RxCpltCallback can be implemented in the user file. 13 */ 14 }
我们在主函数所在的文件中对回调函数进行改写:
1 uint8_t myBuffer[] = "I have gotten your message: "; //用户提示信息 2 uint8_t Enter[] = "\r\n"; //回车换行 3 uint8_t getBuffer[100]; //用户自定义的缓冲区 4 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) 5 { 6 while(HAL_UART_Transmit(UartHandle, (uint8_t*)myBuffer, COUNTOF(myBuffer), 5000)!= HAL_OK); //发送字符串,用户提示信息 7 while(HAL_UART_Transmit(UartHandle, (uint8_t*)getBuffer, 10, 5000)!= HAL_OK); //发送用户自定义缓冲区中的数据 8 while(HAL_UART_Transmit(UartHandle, (uint8_t*)Enter, COUNTOF(Enter), 5000)!= HAL_OK); //发送回车换行 9 }
以上代码的作用是把用户发送给单片机数据再返回给用户。运行效果如下图:
1 void USART1_IRQHandler(void) 2 { 3 HAL_UART_IRQHandler(&UartHandle); //该函数会清空中断标志,取消中断使能,并间接调用回调函数 4 HAL_UART_Receive_IT(&UartHandle, (uint8_t *)&value,1); //添加的一行代码 5 }
这样就可以实现多次数据返回了,新的执行结果如下图:
可见,函数HAL_UART_Receive_IT还有中断使能的作用。这一功能的实现我们可以在HAL_UART_Receive_IT函数中找到。
②注册中断函数
1 uint8_t myBuffer[] = "I have gotten your message: "; 2 uint8_t getBuffer[10]; 3 uint8_t Enter[] = "\r\n"; 4 void USARTx_IRQHandler(void) 5 { 6 HAL_UART_IRQHandler(&UartHandle); //该函数会清空中断标志,取消中断使能,并间接调用回调函数 7 8 getBuffer[countOfGetBuffer++] = value; 9 if(countOfGetBuffer == 10) 10 { 11 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)myBuffer, COUNTOF(myBuffer), 5000)!= HAL_OK); 12 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)getBuffer, countOfGetBuffer, 5000)!= HAL_OK); 13 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)Enter, COUNTOF(Enter), 5000)!= HAL_OK); 14 countOfGetBuffer = 0; 15 } 16 HAL_UART_Receive_IT(&UartHandle, (uint8_t *)&value,1); //由于接收中断是每接收一个字符便进入一次,所以这一行代码必须添加,否则只能接收一个字符,而无法接收整个字符串 17 }
以上代码的作用是接收每个来自用户的字符,并依次存入用户自定义的缓冲区中,数量达到10个后,将缓冲区中的所有数据返回给用户,同时清空计数,准备接下来10个字符的接收。运行效果如下图:
看完本文,大家可能对回调函数和中断处理函数的关系产生了疑问。其实是这样的,单片机每完成接收一个字符,就会进入一次中断处理函数,而在中断处理函数中,我们又调用了函数“void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)”,该函数会间接调用回调函数,也就是说回调函数是由中断处理函数间接调用的。而函数“HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)”决定了中断处理函数调用回调函数的频率,若Size为1,则每进入一次中断处理函数都会调用一次回调函数;若Size为10,则每第十次进入中断处理函数时,才会调用回调函数。
标签:初始 mod 注意 ret 遇到 取消 prevent data complete
原文地址:https://www.cnblogs.com/UnfriendlyARM/p/10321838.html