最近有較多關(guān)于STM32Cube HAL的問題,側(cè)面反應(yīng)了使用STM32CubeMX的人不少。所以,最近可能會(huì)重點(diǎn)寫這方面內(nèi)容。
1寫在前面
很多人都知道STM32CubeMX這套工具的一個(gè)目的:減少開發(fā)者對(duì)STM32底層驅(qū)動(dòng)的開發(fā)時(shí)間,把重心放在應(yīng)用代碼上。
但是,STM32CubeMX只是生成了底層驅(qū)動(dòng)的初始化代碼。所以,我們還需要掌握:應(yīng)用層代碼如何調(diào)用HAL庫(kù)函數(shù)接口,以及HAL庫(kù)中斷處理機(jī)制等相關(guān)知識(shí)。
HAL庫(kù)牽涉的內(nèi)容較多,本文拿HAL庫(kù)中斷處理來講解,以及相關(guān)的回調(diào)函數(shù)。
2
HAL庫(kù)中斷處理機(jī)制
之前使用標(biāo)準(zhǔn)外設(shè)庫(kù)開發(fā)時(shí),中斷程序(函數(shù))由我們自己實(shí)現(xiàn)。
而HAL庫(kù)的中斷處理函數(shù)是按照HAL處理機(jī)制來實(shí)現(xiàn),如USART1,統(tǒng)一由HAL_UART_IRQHandler來進(jìn)行處理,如下圖:
其它大部分外設(shè)(TIM、SPI、CAN...)中斷都類似,HAL進(jìn)行統(tǒng)一處理。
也就是說,HAL已經(jīng)幫我們把中斷處理函數(shù)寫好了,我們只需要調(diào)用相應(yīng)函數(shù)來編寫應(yīng)用程序就行了。
HAL_xxx_IRQHandler里面做了哪些處理?我們以STM32F1的HAL_UART_IRQHandler為例:
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart){ uint32_t isrflags = READ_REG(huart->Instance->SR); uint32_t cr1its = READ_REG(huart->Instance->CR1); uint32_t cr3its = READ_REG(huart->Instance->CR3); uint32_t errorflags = 0x00U; uint32_t dmarequest = 0x00U; /* If no error occurs */ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); if(errorflags == RESET) { /* UART in mode Receiver -------------------------------------------------*/ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { UART_Receive_IT(huart); return; } } /* If some errors occur */ if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) {/*··刪減了部分代碼·*/ } /* End if some error occurs */ /* UART in mode Transmitter ------------------------------------------------*/ if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { UART_Transmit_IT(huart); return;} /* UART in mode Transmitter end --------------------------------------------*/ if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { UART_EndTransmit_IT(huart); return; }}
其實(shí),大家認(rèn)真看一下代碼應(yīng)該能明白,這些和我們編寫的中斷處理函數(shù)是不是有類似之處?
這是無非就是接收中斷、發(fā)送中斷、錯(cuò)誤中斷等一系列處理。只是這里又進(jìn)行了再次封裝,比如接收中斷UART_Receive_IT。
當(dāng)然,這個(gè)UART_Receive_IT接收中斷實(shí)現(xiàn)方式又可能存在不同。像F0、F1...就是直接調(diào)用這個(gè)接收中斷函數(shù)來進(jìn)一步處理。
像L0、G0...是通過執(zhí)行指針函數(shù)RxISR來進(jìn)一步處理。G0的接收中斷處理為:huart->RxISR(huart);
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart){//刪除了前面代碼 /* If no error occurs */ errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); if (errorflags == 0U) { /* UART in mode Receiver ---------------------------------------------------*/ if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || ((cr3its & USART_CR3_RXFTIE) != 0U))) { if (huart->RxISR != NULL) { huart->RxISR(huart); } return; } }//刪除了后面代碼}
看了上面USART中斷處理的函數(shù),大家有沒有得到什么啟發(fā)?
其實(shí),HAL庫(kù)里面處理機(jī)制基本一致,只是實(shí)現(xiàn)方式上有所不同。
如果你摸清楚了HAL庫(kù)基本原理,相信閱讀HAL庫(kù),或者使用HAL庫(kù)編寫應(yīng)用代碼不是問題。
3
回調(diào)函數(shù)實(shí)現(xiàn)原理
在HAL庫(kù)中存在大量類似HAL_XXX_XXXCallback這樣的函數(shù),這些都是回調(diào)函數(shù)。
回調(diào)函數(shù)就是一個(gè)通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來調(diào)用其所指向的函數(shù)時(shí),我們就說這是回調(diào)函數(shù)。
回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。
---來自百度百科
HAL庫(kù)中斷處理使用了較多的回調(diào)函數(shù),還是拿UART接收中斷來舉例說明。
初始化配置好UART中斷接收,如果有中斷請(qǐng)求,就會(huì)執(zhí)行回調(diào)函數(shù)HAL_UART_RxCpltCallback。
看上面回調(diào)函數(shù)的定義,通過特定條件調(diào)用『回調(diào)函數(shù)』,這里觸發(fā)的條件就是中斷。
4
擴(kuò)展說明
這里也簡(jiǎn)單說幾點(diǎn):
1.初學(xué)者想直接使用HAL不是不行,需要有一定C語(yǔ)言功底
針對(duì)大部分初學(xué)者來說,是不建議直接上手HAL。但是,有部分C功底較好的,還是建議直接上手。
2.學(xué)HAL,建議參看官網(wǎng)例程
很多人不知道如何找資源,我不止一次強(qiáng)調(diào),官方的才是最好。在HAL庫(kù)中Projects目錄下就有很多例程Examples。
3.我們追求效率,可以HAL庫(kù)源碼
如果你想修改HAL庫(kù)源碼,允許修改少部分。如果要大量修改,還是別折騰了。
4.實(shí)際項(xiàng)目需做一定修改
STM32CubeMX僅僅是生成初始化代碼和工程,你實(shí)際項(xiàng)目中一般都有自己的軟件架構(gòu)。
特別是項(xiàng)目越大,軟件架構(gòu)就需要更加規(guī)范。
比如:生成的gpio.c文件名,你需要修改成bsp_gpio.c.
再比如:函數(shù)MX_USART2_UART_Init改成MX_DEBUG_UART_Init.
-
底層驅(qū)動(dòng)
+關(guān)注
關(guān)注
0文章
4瀏覽量
8440 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14809 -
HAL庫(kù)
+關(guān)注
關(guān)注
1文章
121瀏覽量
6241
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論