STM32F746 利用HAL库编写串口驱动程序

之前用hal库的时候都是用一些简单的,例如初始化一个IO用作LED指示,今天写的代码需要串口的例子,说真的看了官方的demo也没看出啥名堂,反而觉得用hal写串口驱动太麻烦了.

回顾下之前常见的串口写法,发送用的是阻塞式发送,一般都是发送一些调试信息,接收肯定用的是中断;

为了编程的方便,发送一般是跟printf绑定的,但是对于hal库这些我们又怎么来编写呢?

接下来我把我刚刚学习到的东西分享下,如果有错误请指教。

我的开发板是STM32F746G-DISCO,参考的是UART_TwoBoards_ComIT例子。

首先我们看看中断发送的例子:

/* Buffer used for transmission */
uint8_t aTxBuffer[] = "****UART_TwoBoards_ComIT****\r\n";

/* Buffer used for reception */
uint8_t aRxBuffer[RXBUFFERSIZE];
if(HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
{
    Error_Handler();
}


发送就是aTxBuffer里的数据通过中断方式发送出去,因此这条语句是非阻塞式的,当发送完成后会回调

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle);


接下来我们把改成使用printf的来发送;

① 在main.c里添加

#include <stdio.h>	
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) //MDK
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
   /* Loop until the end of transmission */
    while(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) == RESET);
	
	/* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
    UartHandle.Instance->TDR = (uint8_t) ch;
  
  return ch;
}


然后在串口初始化完毕后就可以调用printf语句试试了

printf("my printf test,compile time:%s %s\r\n",__DATE__,__TIME__);


本人特别喜欢用printf来调试,推荐使用115200波特率;


再说说接中断框架,先看源码:

int main()
{

	//串口初始化
	
	if(HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
	{
		Error_Handler();
	}

	while(1) //单片机的大循环
	{
	  if(UartReady == SET)
		{		
			UartReady =RESET;
			//添加你的处理代码...
		HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE);//再次打开中断接收代码
		}
		//其他代码...
	}

}

/**
	  * @brief  Rx Transfer completed callback
	  * @param  UartHandle: UART handle
	  * @note   This example shows a simple way to report end of DMA Rx transfer, and 
	  *         you can add your own implementation.
	  * @retval None
	  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
	/* Set transmission flag: transfer complete */
	UartReady = SET;

	printf("HAL_UART_RxCpltCallback\r\n");
}


HAL库的中断接收效率很低,而且还很死板,必须接收指定字节才能回调接收完成函数,那能不能改成超时后再回调接收完成函数呢?当然是可以的,并且我已经改出来了,思路简单提下,在钩子函数里加个软件定时器,从接收到第一个字符开始倒计时,超过一定时间就调用接收回调函数,这里有个注意地方就是接收的时候接收指针千万不要溢出了!!!

对于我提出的方法比较感兴趣的可以给我留言,期待着跟大家一起探讨~


猜你喜欢

转载自blog.csdn.net/yunjie167/article/details/60358716
今日推荐