串口接收中斷程序配置過程(HAL)
- 初始化相關參數,使能串口:
HAL_UART_Init();
該函數的參數是串口的基址,在stm32f429xx.h文件中,定義了8個UART_HandleTypeDef的值,分別是USART1、USART2、USART3、UART4、UART5、USART6、UART7、UART8,可以用HAL_UART_Init對這8個串口進行初始化,我們要用USART1,就填USART1
-
串口相關IO口配置,復用配置。在HAL_UART_MspInit中調用HAL_GPIO_Init函數
-
串口接收中斷優先級配置和使能
HAL_NVIC_EnableIRQ();
HAL_NVIC_SetPriority();
- 使能串口接收中斷
所有的串口都使用HAL_UART_Receive_IT使能接收中斷
HAL_UART_Receive_IT();
- 編寫中斷服務函數:USARTx_IRQHandler
這個函數在startup_stm32f429xx.s中可以找到。
不同的串口有不同的中斷服務函數
void USARTx_IRQHandler(void) ;//(x=1~3,6)
void USARTx_IRQHandler(void) ;//(x=4,5,7,8)
具體配置過程
我們通過電腦把數據發送給STM32,STM32收到數據之后再把數據發送給電腦
- 初始化相關參數,使能串口
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);}
- 串口相關IO口配置,復用配置。在HAL_UART_MspInit中調用HAL_GPIO_Init函數
//HAL_UART_Init會自動調用HAL_UART_MspInitvoid 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; //PA9GPIO_Initure.Mode=GPIO_MODE_AF_PP; //復用推挽輸出GPIO_Initure.Pull=GPIO_PULLUP; //上拉GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速GPIO_Initure.Alternate=GPIO_AF7_USART1; //復用為USART1HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9GPIO_Initure.Pin=GPIO_PIN_10; //PA10HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10HAL_NVIC_EnableIRQ(USART1_IRQn);HAL_NVIC_SetPriority(USART1_IRQn,3,3);}
}
HAL_UART_Init初始化串口后,會自動調用HAL_UART_MspInit,我們在HAL_UART_MspInit里面初始化相關GPIO、設置中斷優先級以及使能中斷。
-
串口接收中斷優先級配置和使能,在步驟2實現了
-
使能接收中斷,我們在main函數里面加入一行代碼來使能接收中斷,該中斷對所有的UART中斷都產生影響。
HAL_UART_Receive_IT(&usart_handler,rdata,sizeof(rdata));
第一個參數usart_handler是UART_HandleTypeDef類型的句柄,第二個參數是接收數據存放的位置,第三個是位置大小。經過這四個步驟,我們就配置好了接收中斷。
- 編寫中斷服務函數: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){}}