HAL库-STM32F4 UART-IT


注:参考ST公司HAL库附带UART-IT例程。 参考资料:ST-《STM32F4xx中文参考手册》、野火-《零死角玩转STM-F429》

主要数据类型:

UART_HandleTypeDef UartHandle;
主要HAL函数:
初始化函数:
HAL_StatusTypeDef HAL_UART_Init ( UART_HandleTypeDef * huart );
void HAL_UART_MspInit ( UART_HandleTypeDef *huart ) ;
回调函数:
void HAL_UART_TxCpltCallback( UART_HandleTypeDef * UartHandle );

void HAL_UART_RxCpltCallback( UART_HandleTypeDef * UartHandle );

void HAL_UART_ErrorCallback( UART_HandleTypeDef *UartHandle )

操作函数:
HAL_StatusTypeDef HAL_UART_Transmit_IT( UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size );
HAL_StatusTypeDef HAL_UART_Receive_IT(
UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size );
中断响应函数:
void USARTx_IRQHandler();



步骤:


1.进行UART外设配置:

<span style="white-space:pre">	</span>UART_HandleTypeDef UartHandle;			//全局或在主函数中定义
	
  	UartHandle.Instance          = USARTx;		//选择所需端口,例程中将USART1作为UART使用
  
 	//以下为示例
	UartHandle.Init.BaudRate     = 9600;				//波特率设置
	UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;		//数据长度设置
  	UartHandle.Init.StopBits     = UART_STOPBITS_1;			//停止位设置
  	UartHandle.Init.Parity       = UART_PARITY_NONE;		//奇偶校验设置
  	UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;		//流控制设置 (RTS以及CTS)
 	UartHandle.Init.Mode         = UART_MODE_TX_RX;			//模式设置	例程中同时用到收发功能
  	UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;		


  	//使用初始化函数进行配置
  	HAL_UART_Init(&UartHandle);	//若配置成功,该函数返回值 HAL_OK

       UART_HandleTypeDef 结构体内的成员有许多,但是使用HAL库进行配置则只需要用户设置其中的 Init 成员,其余的由初始化库函数以及操作库函数自行配置完成。
注意,在 HAL_UART_Init 函数结束时则使能了对应UART外设(相应时钟还未使能)



2.进行GPIO、NVIC、相应时钟配置
    在HAL_UART_Init函数中,有语句

if(huart->State == HAL_UART_STATE_RESET)
{  
     	/* Allocate lock resource and initialize it */
     	huart->Lock = HAL_UNLOCKED;
     	/* Init the low level hardware */
     	HAL_UART_MspInit(huart);
}

    即若传入的 UART_HandleTypeDef 类型结构体的 State 成员为 HAL_UART_STATE_RESET 状态,则对其解锁限制,然后调用一个WEAK定义的HAL函数
void HAL_UART_MspInit ( UART_HandleTypeDef * huart );
    一般用户可以在外部自行重新定义该函数,用来初始化板载上GPIO的UART复用,以及相应时钟配置、NVIC配置。在例程中便是如此


/**
  * @brief UART MSP Initialization 
  *        This function configures the hardware resources used in this example: 
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration  
  *           - NVIC configuration for UART interrupt request enable
  * @param huart: UART handle pointer
  * @retval None
  */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{  
  	GPIO_InitTypeDef  GPIO_InitStruct;
  
  	/*##-1- Enable peripherals and GPIO Clocks #################################*/
  	/* Enable GPIO TX/RX clock */
  	USARTx_TX_GPIO_CLK_ENABLE();				//使能相应使用的Tx引脚GPIO口时钟
  	USARTx_RX_GPIO_CLK_ENABLE();				//使能相应使用的Rx引脚GPIO口时钟
  	/* Enable USART1 clock */
  	USARTx_CLK_ENABLE(); 					//使能相应UART\USART时钟
  
  	/*##-2- Configure peripheral GPIO ##########################################*/  
  	/* UART TX GPIO pin configuration  */
  	GPIO_InitStruct.Pin       = USARTx_TX_PIN;		//可使用的引脚需要参考手册
  	GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  	GPIO_InitStruct.Pull      = GPIO_NOPULL;
  	GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
  	GPIO_InitStruct.Alternate = USARTx_TX_AF;
  
  	HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
    
  	/* UART RX GPIO pin configuration  */


  	GPIO_InitStruct.Pin = USARTx_RX_PIN;			//可使用的引脚需要参考手册
  	GPIO_InitStruct.Alternate = USARTx_RX_AF;
    
  	HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
    
  	/*##-3- Configure the NVIC for UART ########################################*/
  	/* NVIC for USART1 */
 	HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);		//配置NVIC优先级
  	HAL_NVIC_EnableIRQ(USARTx_IRQn);			//使能使用的UART\USART中断
}

注意:
1.每个 USART\UART 可使用来作为Tx、Rx的引脚是各不相同的,这点需要具体参考手册进行配置
  2.所使用的 USART\UART 时钟以及对应中断需要使能
  3.若程序中使用到了 SysTick,建议将 SysTick 的中断优先级提在USART\UART之前
" The the SysTick interrupt must have higher priority (numerically lower) than the peripheral interrupt. Otherwise the caller ISR process will be blocked. "
  4.如果想要使用 HAL_UART_MspInit 函数来调用板载外设初始化语句,那么应当确保参数的 Status



3.收发函数

    这里是用到的IT方式,故只举例IT方式的库函数。
    HAL_StatusTypeDef HAL_UART_Transmit_IT  ( UART_HandleTypeDef *  huart,uint8_t *  pData,uint16_t  Size
   
HAL_StatusTypeDef HAL_UART_Receive_IT   ( UART_HandleTypeDef *  huart,uint8_t *  pData,uint16_t  Size )


    HAL_UART_Transmit_IT
函数为发送函数。在其中自动将奇偶校验错误、帧错误、噪音错误、上溢错误以及数据寄存器( DR )为空 中断使能。
    调用该函数后则将把 pData 所指向的数组中的 Size 个数据发送出去。应当在调用该函数后利用一个循环等待发送完成。可通过判断作为参数传入该函数的 UART_HandleTypeDef 类型结构体的 Status 成员是否为 HAL_UART_STATE_READY 来判断是否发送完成(该成员在刚被该函数调用时被设置为 HAL_UART_STATE_BUSY_TX_RX HAL_UART_STATE_BUSY_TX,在程序运行至 UART_EndTransmit_IT 并发送成功后被设置为 HAL_UART_STATE_READY
    HAL_UART_Receive_IT  函数为接收函数。在其中自动将奇偶校验错误、帧错误、噪音错误、上溢错误以及数据寄存器( DR )为空 中断使能。
    调用该函数后则将把从端口中接收的 Size 个数据存放到 pData 所指向的数组去。应当在调用该函数后利用一个循环等待接收完成。可通过判断作为参数传入该函数的 UART_HandleTypeDef 类型结构体的 Status 成员是否为 HAL_UART_STATE_READY 来判断是否接收完成(该成员在刚被该函数调用时被设置为 HAL_UART_STATE_BUSY_TX_RX HAL_UART_STATE_BUSY_TX,在程序运行至 UART_Receive_IT 并接收成功后被设置为 HAL_UART_STATE_READY
PS:DMA方式中相应函数用到了函数指针知识。

    
4.对应中断响应函数以及回调函数
    在这里,主要用到的中断响应函数有 
SysTick_Handler() //Systick计时到点中断
USARTx_IRQHandler() //USART中断 因为我们使用的是USART1,所以是USART中断
    回调函数有
HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) //发送完成回调函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) //接收完成回调函数
HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle) //错误回调函数


    其中,USARTx_IRQHandler 中断响应函数在 USART 发送、接收、以及错误等时候会响应。使用HAL库,我们可以这样编写该中断响应函数

/* UART handler declared in other file */
extern UART_HandleTypeDef UartHandle;
.
.
.
void USARTx_IRQHandler(void)
{
  HAL_UART_IRQHandler(& UartHandle);
}

    这里,该中断响应函数里面调用了库函数 HAL_UART_IRQHandler 函数,并将我们之前定义的 UART_HandleTypeDef 类型的结构体 UartHandle 的地址作为参数传入。
    在 HAL_UART_IRQHandler 函数里,主要进行了清除错误标志位、记录错误码 (HAL库中定义的 UART Error Code)以及判断是否进入接收( UART_Receive_IT(& UartHandle) )、发送( UART_Transmit_IT(& UartHandle) )、发送结束( UART_EndTransmit_IT(& UartHandle) )以及错误回调函数 (HAL_UART_ErrorCallback(& UartHandle) 函数默认为空,WEAK定义。)。


--------------------------------------------------------------------------------------
    UART Error Code为一系列宏定义

<span style="white-space:pre">	</span>#define  HAL_UART_ERROR_NONE   	((uint32_t)0x00000000) //无
	#define  HAL_UART_ERROR_PE   	((uint32_t)0x00000001) //奇偶校验错误
	#define  HAL_UART_ERROR_NE   	((uint32_t)0x00000002) //噪声错误
	#define  HAL_UART_ERROR_FE   	((uint32_t)0x00000004) //帧错误
	#define  HAL_UART_ERROR_ORE   	((uint32_t)0x00000008) //上溢错误
	#define  HAL_UART_ERROR_DMA   	((uint32_t)0x00000010) //DMA传输错误

    static HAL_StatusTypeDef UART_Receive_IT  ( UART_HandleTypeDef *  huart ) //接收数据,如果当前端口不忙,接收成功返回 HAL_OK ,否则返回 HAL_BUSY。并且在接受完成后关闭由 HAL_UART_Receive_IT 开启的一系列中断,调用 HAL_UART_RxCpltCallback 函数。默认为空,WEAK定义。

    static HAL_StatusTypeDef UART_Transmit_IT  ( UART_HandleTypeDef *  huart ) //发送数据,如果当前端口不忙,发送成功返回 HAL_OK ,否则返回 HAL_BUSY

    static HAL_StatusTypeDef UART_EndTransmit_IT  ( UART_HandleTypeDef *  huart ) //结束传输置传入结构体 State 成员为非阻塞状态。并且在完成后关闭由 HAL_UART_Transmit_IT 开启的一系列中断。调用 HAL_UART_TxCpltCallback 函数。默认为空,WEAK定义。



--------------------------------------------------------------------------------------

    以上的都是由 HAL_UART_IRQHandler 函数自动调用配置。

猜你喜欢

转载自blog.csdn.net/u013662665/article/details/51346390