完整教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
第63章 STM32H7的高分辨率定時器HRTIM基礎知識和HAL庫API
本章節為大家講解高分辨率定時器(High-Resolution Timer)的基礎知識和對應的HAL庫API。
63.1 初學者重要提示
63.2 HRTIM基礎知識
63.3 HRTIM定時器的HAL庫用法
63.4 源文件stm32h7xx_hal_hrtim.c
63.5 總結
63.1 初學者重要提示
- 高分辨率定時器可以產生多達10路高分辨率信號。它主要用數字電源、照明,電源耗材,太陽能逆變器和無線充電等應用場合,當然,也可以作為通用目的。
- HRTIM模塊化的架構允許產生獨立或者疊加波形。通過帶的時序控制單元和各種外部事件的配合,可以產生各種信號PWM,相移等。
- HRTIM定時器還具有定時測量功能和鏈接到內置ADC和DAC轉換器。 並且它還具有輕載管理模式和能夠處理各種故障的方案以實現安全關閉。
- HRTIM有多個中斷入口函數,使用的時候別搞錯了:
HRTIM1_Master_IRQHandler
HRTIM1_TIMA_IRQHandler
HRTIM1_TIMB_IRQHandler
HRTIM1_TIMC_IRQHandler
HRTIM1_TIMD_IRQHandler
HRTIM1_TIME_IRQHandler
HRTIM1_FLT_IRQHandler
63.2 HRTIM基礎知識
- HRTIM由6個定時器組成,分別是1個主定時器(Master Timer)和5個獨立的定時器單元,從Timer A到Timer E。
- 這6個都是16bit定時器,每個定時器都包含 1 個獨立計數器和 4 個比較單元。
- 主定時器(Master Timer):
基於 16 位遞增計數器。它可通過 4 個比較單元置位/ 復位 10 路輸出中的任何一路,並向 5 個定時器單元提供同步信號。其主要用途是使定時器單元受唯一的時鍾源控制。交錯降壓轉換器是一個典型的應用示例,主定時器在其中管理多個單元之間的相移。
-
- 5個定時器Timer A到Timer E:
既可以獨立工作,也可以與其它定時器(包括主定時器)配合工作。每個定時器都可控制兩路輸出。輸出置位/復位事件可以由定時單元比較寄存器觸發,或者由主定時器事件、其他定時器的事件或外部事件觸發。
-
- 每個定時器的兩路輸出:
- 支持PWM互補輸出,支持添加死區時間。
- 將載波頻率添加到調制信號上。
- 通過將異步輸出置為預定義的安全電平來管理故障事件。
- 每個定時器的兩路輸出:
- 10個外部事件,可用於任何定時器單元。
- 可編程極性和邊沿有效性。
- 5個事件用於快速異步模式。
- 5個事件用於可編程數字濾波器。
- 利用消隱和窗口模式實現偽事件過濾。
- 多條通道可連接到內置模擬外設。
- 4個用於 ADC 轉換器的觸發信號。
- 3個用於 DAC 轉換器的觸發信號。
- 3個用於比較器。
- 豐富的保護機制。
- 5 路故障輸入可組合使用,而且可以關聯到任何定時單元。
- 可編程極性和邊沿有效性。
- 對諧振變換器配有專門的延時保護。
- 不同HRTIM之間可以做同步輸入/輸出。
63.2.1 定時器的硬件框圖
認識一個外設,最好的方式就是看他的框圖,方便我們快速的了解HRTIM的基本功能,然后再看手冊了解細節。
下面我們直接看HRTIM的框圖:
通過這個框圖,我們可以得到如下信息:
- hrtim_in_sync[3:1]
同步輸入端,將HRTIM與其他內部或外部定時器資源進行同步輸入:
hrtim_in_sync[1]:保留。
hrtim_in_sync[2]:時鍾源為通用TIMx定時器(通過片上互連)。
hrtim_in_sync[3]:時鍾源為外部HRTIM(通過HRTIM_SCIN輸入引腳)。
- hrtim_out_sync[2:1]
同步輸出端,用於級聯或同步多個片上或片外HRTIM,由於H7只有一個HRTIM,所以只能同步其它器件上帶的HRTIM。
hrtim_out_sync[1]:保留。
hrtim_out_sync[2]:目標為片外 HRTIM 或外設(通過HRTIM_SCOUT輸出引腳)。
- hrtim_adc_trg[4:1]
輸出端,用於觸發ADC轉換。
- hrtim_dac_trg[3:1]
輸出端,用於觸發DAC轉換。
- hrtim_mst_it[7:1]
輸出端,用於發出中斷請求。
- hrtim_dma[6:1]
輸出端,用於發出DMA請求。
- hrtim_pclk
輸入端,APB時鍾。
- hrtim_ker_ck
輸出端, HRTIM內核時鍾。
- hrtim_evtX[4:1] 大寫字母X的范圍是1到10。
輸入端,用於接收外部事件,支持接收10個事件,每個事件有4種輸入源可以選擇,可選擇片上(來自其他內置外設:比較器、ADC模擬看門狗、TIMx定時器、觸發輸出等)或片外(HRTIM_EEVx輸入引腳)。
- HRTIM_FLT[5:1]
hrtim_in_flt[5:1]
故障輸入端,5 路片上輸入和 5 路片外HRTIM_FLTx 輸入。
當輸入信號有效時立即禁止HRTIM 輸出。
- hrtim_sys_flt
系統故障輸入,比如時鍾安全系統、 SRAM奇偶校驗錯誤、 Cortex®-M7 LOCKUP (HardFault)、 PVD輸出等。
- hrtim_upd_en[3:1]
輸入端,HRTIM寄存器更新使能(片上互連)會觸發從影子寄存器到活動寄存器的傳輸。
- hrtim_bm_trg
輸入端,突發模式觸發事件。
- hrtim_bm_ck
輸入端,突發模式時鍾。
- HRTIM_CHA1
- HRTIM_CHA2
- HRTIM_CHB1
- HRTIM_CHB2
- HRTIM_CHC1
- HRTIM_CHC2
- HRTIM_CHD1
- HRTIM_CHD2
- HRTIM_CHE1
- HRTIM_CHE2
對應定時器單元Timer A,B,C,D,E的輸出,每個定時器有兩路。
63.2.2 HRTIM時鍾選擇
HRTIM支持兩種時鍾輸入,一個是通用定時器時鍾輸入,另一個是CPU主頻時鍾輸入:
反映到程序代碼上,通過下兩個宏定義參數區分:
#define RCC_HRTIM1CLK_TIMCLK ((uint32_t)0x00000000) #define RCC_HRTIM1CLK_CPUCLK RCC_CFGR_HRTIMSEL
- 使用CPU主頻時鍾,對應參數RCC_HRTIM1CLK_CPUCLK
- 使用通用定時器時鍾,對應參數RCC_HRTIM1CLK_TIMCLK。如果CPU主頻時鍾是400MHz的話,通用定時器時鍾就是200MHz。
- 具體實現,通過函數HAL_RCCEx_PeriphCLKConfig來配置:
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_HRTIM1; PeriphClkInitStruct.Hrtim1ClockSelection = RCC_HRTIM1CLK_TIMCLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }
63.2.3 HRTIM主定時器
HRTIM的主定時器框圖:
對於這個框圖,了解到以下幾點即可:
- 主定時器有1個計數器,4個比較單元,但沒有捕獲單元和輸出。
- 主定時器的控制寄存器包含主定時器Master Timer和定時單元Timer A到E的所有定時器使能位。
63.2.4 HRTIM定時器單元(Timer A到E)
5個定時器單元的Timer A到E都是一樣的,框圖如下:
對於這個框圖,了解到以下幾點即可:
- 有1個計數器,4個比較單元,2個捕獲單元,帶兩個輸出。
- 比較單元2和比較單元4支持自帶延遲。
- 事件消隱和窗口模式可以實現偽事件過濾。
- REP,CMP1,CMP2,CMP3,CMP和定時器更新這幾個信號可以設置輸出端的置位/復位。
63.2.5 HRTIM的分辨率
STM32H7的主頻配置為400MHz時,那么HRTIM的時鍾最高就是400MHz。對於H7系列,HRTIM不支持倍頻設置,僅支持1分頻,2分頻和4分頻:
H7系列與F3以及G4的對比:
分辨率最高是G4系列,可以做到184ps。
63.2.6 HRTIM的PWM多路輸出實現
這里我們先來看下單路PWM輸出:
寄存器HRTIM_PERxR存儲定時器的周期,寄存器HRTIM_CMP1xR存儲比較值。執行過程如下:
- 計數器Counter計數到HRTIM_CMP1xR存儲的比較值時,HRTIM_CHD1輸出端復位。
- 計數到HRTIM_PERxR時,HRTIM_CHD1輸出端置位,並且Counter重新從頭開始計數。
理解了單路PWM輸出后,再看實現這個功能對應的框圖就很好理解了:
接下來再來看多路PWM輸出:
截圖上半部分波形是Timer D輸出兩路:
- HRTIM_CHD1輸出是通過CMP1以及計數更新實現輸出的置位/復位。
- HRTIM_CHD2輸出是通過CMP2以及計數更新實現輸出的置位/復位。
截圖下半部分波形是Timer A輸出兩路:
- HRTIM_CHA1輸出是通過CMP1以及計數更新實現輸出的置位/復位。
- HRTIM_CHA2輸出是通過CMP2,CMP3以及計數更新實現輸出的置位/復位。
63.3 HRTIM定時器的HAL庫用法
HRTIM的HAL庫用法其實就是幾個結構體變量成員的配置和使用,然后配置GPIO、時鍾,並根據需要配置NVIC、中斷和DMA。下面我們逐一展開為大家做個說明。
63.3.1 定時器寄存器結構體HRTIM_TypeDef
定時器相關的寄存器是通過HAL庫中的結構體HRTIM_TypeDef定義的,在stm32h743xx.h中可以找到這個定義類型:
typedef struct { HRTIM_Master_TypeDef sMasterRegs; HRTIM_Timerx_TypeDef sTimerxRegs[5]; uint32_t RESERVED0[32]; HRTIM_Common_TypeDef sCommonRegs; }HRTIM_TypeDef; typedef struct { __IO uint32_t MCR; __IO uint32_t MISR; __IO uint32_t MICR; __IO uint32_t MDIER; __IO uint32_t MCNTR; __IO uint32_t MPER; __IO uint32_t MREP; __IO uint32_t MCMP1R; uint32_t RESERVED0; __IO uint32_t MCMP2R; __IO uint32_t MCMP3R; __IO uint32_t MCMP4R; uint32_t RESERVED1[20]; }HRTIM_Master_TypeDef; typedef struct { __IO uint32_t TIMxCR; __IO uint32_t TIMxISR; __IO uint32_t TIMxICR; __IO uint32_t TIMxDIER; __IO uint32_t CNTxR; __IO uint32_t PERxR; __IO uint32_t REPxR; __IO uint32_t CMP1xR; __IO uint32_t CMP1CxR; __IO uint32_t CMP2xR; __IO uint32_t CMP3xR; __IO uint32_t CMP4xR; __IO uint32_t CPT1xR; __IO uint32_t CPT2xR; __IO uint32_t DTxR; __IO uint32_t SETx1R; __IO uint32_t RSTx1R; __IO uint32_t SETx2R; __IO uint32_t RSTx2R; __IO uint32_t EEFxR1; __IO uint32_t EEFxR2; __IO uint32_t RSTxR; __IO uint32_t CHPxR; __IO uint32_t CPT1xCR; __IO uint32_t CPT2xCR; __IO uint32_t OUTxR; __IO uint32_t FLTxR; uint32_t RESERVED0[5]; }HRTIM_Timerx_TypeDef; typedef struct { __IO uint32_t CR1; __IO uint32_t CR2; __IO uint32_t ISR; __IO uint32_t ICR; __IO uint32_t IER; __IO uint32_t OENR; __IO uint32_t ODISR; __IO uint32_t ODSR; __IO uint32_t BMCR; __IO uint32_t BMTRGR; __IO uint32_t BMCMPR; __IO uint32_t BMPER; __IO uint32_t EECR1; __IO uint32_t EECR2; __IO uint32_t EECR3; __IO uint32_t ADC1R; __IO uint32_t ADC2R; __IO uint32_t ADC3R; __IO uint32_t ADC4R; __IO uint32_t RESERVED0; __IO uint32_t FLTINR1; __IO uint32_t FLTINR2; __IO uint32_t BDMUPR; __IO uint32_t BDTAUPR; __IO uint32_t BDTBUPR; __IO uint32_t BDTCUPR; __IO uint32_t BDTDUPR; __IO uint32_t BDTEUPR; __IO uint32_t BDMADR; }HRTIM_Common_TypeDef;
這個結構體的成員名稱和排列次序和CPU的定時器寄存器是一 一對應的。
__IO表示volatile, 這是標准C語言中的一個修飾字,表示這個變量是非易失性的,編譯器不要將其優化掉。core_m7.h 文件定義了這個宏:
#define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */
下面我們看下定時器的定義,在stm32h743xx.h文件。
#define PERIPH_BASE (0x40000000UL) #define D2_APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL) #define HRTIM1_BASE (D2_APB2PERIPH_BASE + 0x7400UL) #define HRTIM1_TIMA_BASE (HRTIM1_BASE + 0x00000080UL) #define HRTIM1_TIMB_BASE (HRTIM1_BASE + 0x00000100UL) #define HRTIM1_TIMC_BASE (HRTIM1_BASE + 0x00000180UL) #define HRTIM1_TIMD_BASE (HRTIM1_BASE + 0x00000200UL) #define HRTIM1_TIME_BASE (HRTIM1_BASE + 0x00000280UL) #define HRTIM1_COMMON_BASE (HRTIM1_BASE + 0x00000380UL) #define HRTIM1 ((HRTIM_TypeDef *) HRTIM1_BASE)<----- 展開這個宏,(HRTIM_TypeDef *)0x40017400 #define HRTIM1_TIMA ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMA_BASE) #define HRTIM1_TIMB ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMB_BASE) #define HRTIM1_TIMC ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMC_BASE) #define HRTIM1_TIMD ((HRTIM_Timerx_TypeDef *) HRTIM1_TIMD_BASE) #define HRTIM1_TIME ((HRTIM_Timerx_TypeDef *) HRTIM1_TIME_BASE) #define HRTIM1_COMMON ((HRTIM_Common_TypeDef *) HRTIM1_COMMON_BASE)
我們訪問HRTIM的MCR寄存器可以采用這種形式:HRTIM1->sMasterRegs.MCR = 0;
63.3.2 定時器初始化結構體HRTIM_InitTypeDef
此結構體主要用於HRTIM初始化,定義如下:
typedef struct { uint32_t HRTIMInterruptResquests; uint32_t SyncOptions; uint32_t SyncInputSource; uint32_t SyncOutputSource; uint32_t SyncOutputPolarity; } HRTIM_InitTypeDef;
下面將這幾個參數一 一做個說明。
- HRTIMInterruptResquests
用於配置支持的中斷請求,支持的模式較多:
#define HRTIM_IT_NONE 0x00000000U /*!< No interrupt enabled */ #define HRTIM_IT_FLT1 HRTIM_IER_FLT1 /*!< Fault 1 interrupt enable */ #define HRTIM_IT_FLT2 HRTIM_IER_FLT2 /*!< Fault 2 interrupt enable */ #define HRTIM_IT_FLT3 HRTIM_IER_FLT3 /*!< Fault 3 interrupt enable */ #define HRTIM_IT_FLT4 HRTIM_IER_FLT4 /*!< Fault 4 interrupt enable */ #define HRTIM_IT_FLT5 HRTIM_IER_FLT5 /*!< Fault 5 interrupt enable */ #define HRTIM_IT_SYSFLT HRTIM_IER_SYSFLT /*!< System Fault interrupt enable */ #define HRTIM_IT_BMPER HRTIM_IER_BMPER /*!< Burst mode period interrupt enable */
- SyncOptions
配置HRTIM作為Master,發送同步信號,或者作為Slave,接收同步信號。
#define HRTIM_SYNCOPTION_NONE 0x00000000U #define HRTIM_SYNCOPTION_MASTER 0x00000001U /* 作為MASTER, 同步輸出SYNCOUT */ #define HRTIM_SYNCOPTION_SLAVE 0x00000002U /* 作為SLAVE, 同步輸入SYNCIN */
- SyncInputSource
設置外部同步輸入源,只有當HRTIM配置為Slave時才可以使用。
#define HRTIM_SYNCINPUTSOURCE_NONE 0x00000000U /* 片上定時器做同步輸入源 */ #define HRTIM_SYNCINPUTSOURCE_INTERNALEVENT HRTIM_MCR_SYNC_IN_1 /* 外部輸入引腳SYNCIN做同步輸入源 */ #define HRTIM_SYNCINPUTSOURCE_EXTERNALEVENT (HRTIM_MCR_SYNC_IN_1 | HRTIM_MCR_SYNC_IN_0)
- SyncOutputSource
設置同步脈沖輸出源,只有當HRTIM配置為Master時才可以使用。
/* 主定時器啟動事件觸發SYNCOUT引腳發送脈沖 */ #define HRTIM_SYNCOUTPUTSOURCE_MASTER_START 0x00000000U /* 主定時器比較1事件觸發SYNCOUT引腳發送脈沖 */ #define HRTIM_SYNCOUTPUTSOURCE_MASTER_CMP1 (HRTIM_MCR_SYNC_SRC_0) /* Timer A啟動或者復位事件觸發SYNCOUT引腳發送脈沖 */ #define HRTIM_SYNCOUTPUTSOURCE_TIMA_START (HRTIM_MCR_SYNC_SRC_1) /* Timer A比較1事件觸發SYNCOUT引腳發送脈沖 */ #define HRTIM_SYNCOUTPUTSOURCE_TIMA_CMP1 (HRTIM_MCR_SYNC_SRC_1 | HRTIM_MCR_SYNC_SRC_0)
- SyncOutputPolarity
同步輸出極性。
/* 同步輸出關閉 */ #define HRTIM_SYNCOUTPUTPOLARITY_NONE 0x00000000U /* SCOUT引腳空閑狀態是低電平,發送一個長度為16個HRTIM時鍾周期的正脈沖 */ #define HRTIM_SYNCOUTPUTPOLARITY_POSITIVE (HRTIM_MCR_SYNC_OUT_1) /* SCOUT引腳空閑狀態是高電平,發送一個長度為16個HRTIM時鍾周期的負脈沖 */ #define HRTIM_SYNCOUTPUTPOLARITY_NEGATIVE (HRTIM_MCR_SYNC_OUT_1 | HRTIM_MCR_SYNC_OUT_0)
63.3.3 定時器參數結構體HRTIM_TimerParamTypeDef
此結構體主要用於參數定義:
typedef struct { uint32_t CaptureTrigger1; uint32_t CaptureTrigger2; uint32_t InterruptRequests; uint32_t DMARequests; uint32_t DMASrcAddress; uint32_t DMADstAddress; uint32_t DMASize; } HRTIM_TimerParamTypeDef;
下面將這幾個參數一 一做個說明。
- CaptureTrigger1
觸發捕獲單元1。
當HRTIM工作在Simple Mode,支持的參數如下:
#define HRTIM_EVENT_NONE (0x00000000U) /*!< Undefined event channel */ #define HRTIM_EVENT_1 (0x00000001U) /*!< External event channel 1 identifier */ #define HRTIM_EVENT_2 (0x00000002U) /*!< External event channel 2 identifier */ #define HRTIM_EVENT_3 (0x00000003U) /*!< External event channel 3 identifier */ #define HRTIM_EVENT_4 (0x00000004U) /*!< External event channel 4 identifier */ #define HRTIM_EVENT_5 (0x00000005U) /*!< External event channel 5 identifier */ #define HRTIM_EVENT_6 (0x00000006U) /*!< External event channel 6 identifier */ #define HRTIM_EVENT_7 (0x00000007U) /*!< External event channel 7 identifier */ #define HRTIM_EVENT_8 (0x00000008U) /*!< External event channel 8 identifier */ #define HRTIM_EVENT_9 (0x00000009U) /*!< External event channel 9 identifier */ #define HRTIM_EVENT_10 (0x0000000AU) /*!< External event channel 10 identifier */
當HRTIM工作在Waveform Mode,支持的參數如下:
#define HRTIM_CAPTURETRIGGER_NONE 0x00000000U #define HRTIM_CAPTURETRIGGER_UPDATE (HRTIM_CPT1CR_UPDCPT) #define HRTIM_CAPTURETRIGGER_EEV_1 (HRTIM_CPT1CR_EXEV1CPT) #define HRTIM_CAPTURETRIGGER_EEV_2 (HRTIM_CPT1CR_EXEV2CPT) #define HRTIM_CAPTURETRIGGER_EEV_3 (HRTIM_CPT1CR_EXEV3CPT) #define HRTIM_CAPTURETRIGGER_EEV_4 (HRTIM_CPT1CR_EXEV4CPT) #define HRTIM_CAPTURETRIGGER_EEV_5 (HRTIM_CPT1CR_EXEV5CPT) #define HRTIM_CAPTURETRIGGER_EEV_6 (HRTIM_CPT1CR_EXEV6CPT) #define HRTIM_CAPTURETRIGGER_EEV_7 (HRTIM_CPT1CR_EXEV7CPT) #define HRTIM_CAPTURETRIGGER_EEV_8 (HRTIM_CPT1CR_EXEV8CPT) #define HRTIM_CAPTURETRIGGER_EEV_9 (HRTIM_CPT1CR_EXEV9CPT) #define HRTIM_CAPTURETRIGGER_EEV_10 (HRTIM_CPT1CR_EXEV10CPT) #define HRTIM_CAPTURETRIGGER_TA1_SET (HRTIM_CPT1CR_TA1SET) #define HRTIM_CAPTURETRIGGER_TA1_RESET (HRTIM_CPT1CR_TA1RST) #define HRTIM_CAPTURETRIGGER_TIMERA_CMP1 (HRTIM_CPT1CR_TIMACMP1) #define HRTIM_CAPTURETRIGGER_TIMERA_CMP2 (HRTIM_CPT1CR_TIMACMP2) #define HRTIM_CAPTURETRIGGER_TB1_SET (HRTIM_CPT1CR_TB1SET) #define HRTIM_CAPTURETRIGGER_TB1_RESET (HRTIM_CPT1CR_TB1RST) #define HRTIM_CAPTURETRIGGER_TIMERB_CMP1 (HRTIM_CPT1CR_TIMBCMP1) #define HRTIM_CAPTURETRIGGER_TIMERB_CMP2 (HRTIM_CPT1CR_TIMBCMP2) #define HRTIM_CAPTURETRIGGER_TC1_SET (HRTIM_CPT1CR_TC1SET) #define HRTIM_CAPTURETRIGGER_TC1_RESET (HRTIM_CPT1CR_TC1RST) #define HRTIM_CAPTURETRIGGER_TIMERC_CMP1 (HRTIM_CPT1CR_TIMCCMP1) #define HRTIM_CAPTURETRIGGER_TIMERC_CMP2 (HRTIM_CPT1CR_TIMCCMP2) #define HRTIM_CAPTURETRIGGER_TD1_SET (HRTIM_CPT1CR_TD1SET) #define HRTIM_CAPTURETRIGGER_TD1_RESET (HRTIM_CPT1CR_TD1RST) #define HRTIM_CAPTURETRIGGER_TIMERD_CMP1 (HRTIM_CPT1CR_TIMDCMP1) #define HRTIM_CAPTURETRIGGER_TIMERD_CMP2 (HRTIM_CPT1CR_TIMDCMP2) #define HRTIM_CAPTURETRIGGER_TE1_SET (HRTIM_CPT1CR_TE1SET) #define HRTIM_CAPTURETRIGGER_TE1_RESET (HRTIM_CPT1CR_TE1RST) #define HRTIM_CAPTURETRIGGER_TIMERE_CMP1 (HRTIM_CPT1CR_TIMECMP1) #define HRTIM_CAPTURETRIGGER_TIMERE_CMP2 (HRTIM_CPT1CR_TIMECMP2)
- CaptureTrigger2
觸發捕獲單元2,支持的參數與CaptureTrigger1一樣。
- InterruptRequests
定時器的中斷請求使能。
- DMASrcAddress
DMA源地址。
- DMADstAddress
DMA目的地址。
- DMASize
DMA傳輸大小。
63.3.4 定時器時基配置HRTIM_TimeBaseCfgTypeDef
此結構體主要用於定時器時間基准配置:
typedef struct { uint32_t Period; uint32_t RepetitionCounter; uint32_t PrescalerRatio; uint32_t Mode; } HRTIM_TimeBaseCfgTypeDef;
下面將這幾個參數一 一做個說:
- Period
定時器周期,至少3個HRTIM時鍾周期,最大值0xFFDF。
- RepetitionCounter
重復周期計數器,最小值0x00,最大值0xFF。
- PrescalerRatio
用於設置定時器分頻,對於H7系列,此參數僅支持分頻,也就是下面參數的后三個:
#define HRTIM_PRESCALERRATIO_MUL32 (0x00000000U) #define HRTIM_PRESCALERRATIO_MUL16 (0x00000001U) #define HRTIM_PRESCALERRATIO_MUL8 (0x00000002U) #define HRTIM_PRESCALERRATIO_MUL4 (0x00000003U) #define HRTIM_PRESCALERRATIO_MUL2 (0x00000004U) /* STM32H7僅支持下面這三種 */ #define HRTIM_PRESCALERRATIO_DIV1 (0x00000005U) #define HRTIM_PRESCALERRATIO_DIV2 (0x00000006U) #define HRTIM_PRESCALERRATIO_DIV4 (0x00000007U)
- Mode
設置工作模式,支持的參數如下:
#define HRTIM_MODE_CONTINUOUS (0x00000008U) #define HRTIM_MODE_SINGLESHOT (0x00000000U) #define HRTIM_MODE_SINGLESHOT_RETRIGGERABLE (0x00000010U)
63.3.5 定時器配置HRTIM_TimerCfgTypeDef
此結構體主要用於定時器配置:
typedef struct { /* 下面這些參數支持所有定時器,含主定時器和Timer A到Timer E*/ uint32_t InterruptRequests; uint32_t DMARequests; uint32_t DMASrcAddress; uint32_t DMADstAddress; uint32_t DMASize; uint32_t HalfModeEnable; uint32_t StartOnSync; uint32_t ResetOnSync; uint32_t DACSynchro; uint32_t PreloadEnable; uint32_t UpdateGating; uint32_t BurstMode; uint32_t RepetitionUpdate; /* 下面這些參數僅支持Timer A到Timer E */ uint32_t PushPull; uint32_t FaultEnable; uint32_t FaultLock; uint32_t DeadTimeInsertion; uint32_t DelayedProtectionMode; uint32_t UpdateTrigger; uint32_t ResetTrigger; uint32_t ResetUpdate; } HRTIM_TimerCfgTypeDef;
下面將這幾個參數一 一做個說:
- InterruptRequests
用於使能HRTIM的中斷,支持的中斷如下:
#define HRTIM_MASTER_IT_NONE 0x00000000U /*!< No interrupt enabled */ #define HRTIM_MASTER_IT_MCMP1 HRTIM_MDIER_MCMP1IE /*!< Master compare 1 interrupt enable */ #define HRTIM_MASTER_IT_MCMP2 HRTIM_MDIER_MCMP2IE /*!< Master compare 2 interrupt enable */ #define HRTIM_MASTER_IT_MCMP3 HRTIM_MDIER_MCMP3IE /*!< Master compare 3 interrupt enable */ #define HRTIM_MASTER_IT_MCMP4 HRTIM_MDIER_MCMP4IE /*!< Master compare 4 interrupt enable */ #define HRTIM_MASTER_IT_MREP HRTIM_MDIER_MREPIE /*!< Master Repetition interrupt enable */ #define HRTIM_MASTER_IT_SYNC HRTIM_MDIER_SYNCIE /*!< Synchronization input interrupt enable */ #define HRTIM_MASTER_IT_MUPD HRTIM_MDIER_MUPDIE /*!< Master update interrupt enable */
- DMARequests
用於設置支持的DMA請求,此參數支持兩種類型的參數,下面是HRTIM Master支持的請求
#define HRTIM_MASTER_DMA_NONE 0x00000000U /*!< No DMA request enable */ #define HRTIM_MASTER_DMA_MCMP1 HRTIM_MDIER_MCMP1DE /*!< Master compare 1 DMA request enable */ #define HRTIM_MASTER_DMA_MCMP2 HRTIM_MDIER_MCMP2DE /*!< Master compare 2 DMA request enable */ #define HRTIM_MASTER_DMA_MCMP3 HRTIM_MDIER_MCMP3DE /*!< Master compare 3 DMA request enable */ #define HRTIM_MASTER_DMA_MCMP4 HRTIM_MDIER_MCMP4DE /*!< Master compare 4 DMA request enable */ #define HRTIM_MASTER_DMA_MREP HRTIM_MDIER_MREPDE /*!< Master Repetition DMA request enable */ #define HRTIM_MASTER_DMA_SYNC HRTIM_MDIER_SYNCDE /*!< Synchronization input DMA request enable */ #define HRTIM_MASTER_DMA_MUPD HRTIM_MDIER_MUPDDE /*!< Master update DMA request enable */
下面是HRTIM 的TIMER A到TIMER E支持的請求:
#define HRTIM_TIM_DMA_NONE 0x00000000U /*!< No DMA request enable */ #define HRTIM_TIM_DMA_CMP1 HRTIM_TIMDIER_CMP1DE /*!< Timer compare 1 DMA request enable */ #define HRTIM_TIM_DMA_CMP2 HRTIM_TIMDIER_CMP2DE /*!< Timer compare 2 DMA request enable */ #define HRTIM_TIM_DMA_CMP3 HRTIM_TIMDIER_CMP3DE /*!< Timer compare 3 DMA request enable */ #define HRTIM_TIM_DMA_CMP4 HRTIM_TIMDIER_CMP4DE /*!< Timer compare 4 DMA request enable */ #define HRTIM_TIM_DMA_REP HRTIM_TIMDIER_REPDE /*!< Timer repetition DMA request enable */ #define HRTIM_TIM_DMA_UPD HRTIM_TIMDIER_UPDDE /*!< Timer update DMA request enable */ #define HRTIM_TIM_DMA_CPT1 HRTIM_TIMDIER_CPT1DE /*!< Timer capture 1 DMA request enable */ #define HRTIM_TIM_DMA_CPT2 HRTIM_TIMDIER_CPT2DE /*!< Timer capture 2 DMA request enable */ #define HRTIM_TIM_DMA_SET1 HRTIM_TIMDIER_SET1DE /*!< Timer output 1 set DMA request enable */ #define HRTIM_TIM_DMA_RST1 HRTIM_TIMDIER_RST1DE /*!< Timer output 1 reset DMA request enable */ #define HRTIM_TIM_DMA_SET2 HRTIM_TIMDIER_SET2DE /*!< Timer output 2 set DMA request enable */ #define HRTIM_TIM_DMA_RST2 HRTIM_TIMDIER_RST2DE /*!< Timer output 2 reset DMA request enable */ #define HRTIM_TIM_DMA_RST HRTIM_TIMDIER_RSTDE /*!< Timer reset DMA request enable */ #define HRTIM_TIM_DMA_DLYPRT HRTIM_TIMDIER_DLYPRTDE /*!< Timer delay protection DMA request enable */
- DMASrcAddress
用於設置DMA源地址。
- DMADstAddress
用於設置DMA目的地址。
- DMASize
用於設置DMA大小。
- HalfModeEnable
用於使能Half Mode。
#define HRTIM_HALFMODE_DISABLED (0x00000000U) /* 禁止 */ #define HRTIM_HALFMODE_ENABLED (0x00000020U) /* 使能 */
- StartOnSync
設置同步輸入端接收到上升沿信號后,是否啟動定時器:
#define HRTIM_SYNCSTART_DISABLED (0x00000000U) /* 禁止 */ #define HRTIM_SYNCSTART_ENABLED (HRTIM_MCR_SYNCSTRTM) /* 使能 */
- ResetOnSync
設置同步輸入端接收到上升沿信號后,是否復位定時器。
#define HRTIM_SYNCRESET_DISABLED (0x00000000U) /* 禁止 */ #define HRTIM_SYNCRESET_ENABLED (HRTIM_MCR_SYNCRSTM) /* 使能 */
- DACSynchro
用於設置是否使能DAC同步事件。
/* 禁止DAC同步事件 */ #define HRTIM_DACSYNC_NONE 0x00000000U /* 定時器更新時,DACTrigOut1輸出同步事件 */ #define HRTIM_DACSYNC_DACTRIGOUT_1 (HRTIM_MCR_DACSYNC_0) /* 定時器更新時,DACTrigOut2輸出同步事件 */ #define HRTIM_DACSYNC_DACTRIGOUT_2 (HRTIM_MCR_DACSYNC_1) /* 定時器更新時,DACTrigOut3輸出同步事件 */ #define HRTIM_DACSYNC_DACTRIGOUT_3 (HRTIM_MCR_DACSYNC_1 | HRTIM_MCR_DACSYNC_0)
- PreloadEnable
用於設置是否使能寄存器預加載。
/* 禁止預加載,寫操作是直接寫入到寄存器里面 */ #define HRTIM_PRELOAD_DISABLED (0x00000000U) /* 使能預加載,寫操作是寫入到預加載寄存器里面 */ #define HRTIM_PRELOAD_ENABLED (HRTIM_MCR_PREEN)
- UpdateGating
用於設置HRTIM更新方式來源。
/* 獨立更新,不受DMA突發傳輸完成影響 */ #define HRTIM_UPDATEGATING_INDEPENDENT 0x00000000U /* 突發傳輸完成時,完成更新!< Update done when the DMA burst transfer is completed */ #define HRTIM_UPDATEGATING_DMABURST (HRTIM_TIMCR_UPDGAT_0) /* 代碼太長,其它定義省略未寫 */
- BurstMode
設置定時器在突發模式下表現。
/* 定時器計數器時鍾保持,定時器正常操作 */ #define HRTIM_TIMERBURSTMODE_MAINTAINCLOCK 0x00000000U /* 定時器計數時鍾停止,計數器復位 */ #define HRTIM_TIMERBURSTMODE_RESETCOUNTER (HRTIM_BMCR_MTBM)
- RepetitionUpdate
設置重復計數事件是否可以觸發寄存器更新。
#define HRTIM_UPDATEONREPETITION_DISABLED 0x00000000U /* 禁止 */ #define HRTIM_UPDATEONREPETITION_ENABLED (HRTIM_MCR_MREPU) /* 使能 */
- PushPull
設置是否使能HRTIM的TIMER(A到E)的推挽模式。
#define HRTIM_TIMPUSHPULLMODE_DISABLED 0x00000000U /* 禁止推挽輸出 */ #define HRTIM_TIMPUSHPULLMODE_ENABLED (HRTIM_TIMCR_PSHPLL) /* 使能推挽輸出 */
- FaultEnable
使能HRTIM TIMER的Fault通道。
#define HRTIM_TIMFAULTENABLE_NONE 0x00000000U #define HRTIM_TIMFAULTENABLE_FAULT1 (HRTIM_FLTR_FLT1EN) #define HRTIM_TIMFAULTENABLE_FAULT2 (HRTIM_FLTR_FLT2EN) #define HRTIM_TIMFAULTENABLE_FAULT3 (HRTIM_FLTR_FLT3EN) #define HRTIM_TIMFAULTENABLE_FAULT4 (HRTIM_FLTR_FLT4EN) #define HRTIM_TIMFAULTENABLE_FAULT5 (HRTIM_FLTR_FLT5EN)
- FaultLock
設置HRTIM TIMER的異常使能狀態是否寫保護。
#define HRTIM_TIMFAULTLOCK_READWRITE (0x00000000U) /* 可讀可寫 */ #define HRTIM_TIMFAULTLOCK_READONLY (HRTIM_FLTR_FLTLCK) /* 只讀 */
- DeadTimeInsertion
設置HRTIM TIMER的死區插入。
#define HRTIM_TIMDEADTIMEINSERTION_DISABLED (0x00000000U) /* 輸出1和輸出2信號是獨立的 */ #define HRTIM_TIMDEADTIMEINSERTION_ENABLED HRTIM_OUTR_DTEN /* 輸出1和輸出2之間插入死區時間 */
- DelayedProtectionMode
設置HRTIM TIMER的延遲保護模式。
#define HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED (0x00000000U) /* 代碼太長,其它定義省略未寫 */
- UpdateTrigger
設置Master或者TIMER(A到E)更新時,同步更新寄存器。
#define HRTIM_TIMUPDATETRIGGER_NONE 0x00000000U #define HRTIM_TIMUPDATETRIGGER_MASTER (HRTIM_TIMCR_MSTU) #define HRTIM_TIMUPDATETRIGGER_TIMER_A (HRTIM_TIMCR_TAU) #define HRTIM_TIMUPDATETRIGGER_TIMER_B (HRTIM_TIMCR_TBU) #define HRTIM_TIMUPDATETRIGGER_TIMER_C (HRTIM_TIMCR_TCU) #define HRTIM_TIMUPDATETRIGGER_TIMER_D (HRTIM_TIMCR_TDU) #define HRTIM_TIMUPDATETRIGGER_TIMER_E (HRTIM_TIMCR_TEU)
- ResetTrigger
設置那個事件可以觸發定時器計數復位。
#define HRTIM_TIMRESETTRIGGER_NONE 0x00000000U /* 無觸發 */ /* 代碼太長,其它定義省略未寫 */
- ResetUpdate
當HRTIM TIMER的計數器復位時或者計數回滾到0時,是否觸發寄存器更新。
#define HRTIM_TIMUPDATEONRESET_DISABLED 0x00000000U /* 禁止 */ #define HRTIM_TIMUPDATEONRESET_ENABLED (HRTIM_TIMCR_TRSTU) /* 使能 */
63.3.6 定時器輸出配置HRTIM_OutputCfgTypeDef
此結構體主要用於定時器輸出配置:
typedef struct { uint32_t Polarity; uint32_t SetSource; uint32_t ResetSource; uint32_t IdleMode; uint32_t IdleLevel; uint32_t FaultLevel; uint32_t ChopperModeEnable; uint32_t BurstModeEntryDelayed; } HRTIM_OutputCfgTypeDef;
下面將這幾個參數一 一做個說:
- Polarity
輸出極性是用來設置激活狀態Active對應的高電平還是低電平
#define HRTIM_OUTPUTPOLARITY_HIGH (0x00000000U) #define HRTIM_OUTPUTPOLARITY_LOW (HRTIM_OUTR_POL1)
- SetSource
可以將輸出由Inactive狀態轉為Active狀態的事件,即輸出置位。
#define HRTIM_OUTPUTSET_NONE 0x00000000U #define HRTIM_OUTPUTSET_RESYNC (HRTIM_SET1R_RESYNC) #define HRTIM_OUTPUTSET_TIMPER (HRTIM_SET1R_PER) #define HRTIM_OUTPUTSET_TIMCMP1 (HRTIM_SET1R_CMP1) #define HRTIM_OUTPUTSET_TIMCMP2 (HRTIM_SET1R_CMP2) #define HRTIM_OUTPUTSET_TIMCMP3 (HRTIM_SET1R_CMP3) #define HRTIM_OUTPUTSET_TIMCMP4 (HRTIM_SET1R_CMP4) /* 代碼太長,其它定義省略未寫 */
- ResetSource
可以將輸出由Active狀態轉為Inactive狀態的事件,即輸出復位。
#define HRTIM_OUTPUTRESET_NONE 0x00000000U #define HRTIM_OUTPUTRESET_RESYNC (HRTIM_RST1R_RESYNC) #define HRTIM_OUTPUTRESET_TIMPER (HRTIM_RST1R_PER) #define HRTIM_OUTPUTRESET_TIMCMP1 (HRTIM_RST1R_CMP1) #define HRTIM_OUTPUTRESET_TIMCMP2 (HRTIM_RST1R_CMP2) #define HRTIM_OUTPUTRESET_TIMCMP3 (HRTIM_RST1R_CMP3) #define HRTIM_OUTPUTRESET_TIMCMP4 (HRTIM_RST1R_CMP4) /* 代碼太長,其它定義省略未寫 */
- IdleMode
設置進入突發模式后,輸出空閑狀態。
#define HRTIM_OUTPUTIDLEMODE_NONE 0x00000000U /* 輸出不受突發模式影響 */ #define HRTIM_OUTPUTIDLEMODE_IDLE (HRTIM_OUTR_IDLM1) /* 進入突發模式后,輸出空閑狀態*/
- IdleLevel
設置輸出為空閑狀態時,輸出電平為Inactive或者Active。
#define HRTIM_OUTPUTIDLELEVEL_INACTIVE 0x00000000U #define HRTIM_OUTPUTIDLELEVEL_ACTIVE (HRTIM_OUTR_IDLES1)
- FaultLevel
設置輸出為Fault狀態時,輸出電平為Inactive,Active或者HIGHZ(高阻)。
#define HRTIM_OUTPUTFAULTLEVEL_NONE 0x00000000U #define HRTIM_OUTPUTFAULTLEVEL_ACTIVE (HRTIM_OUTR_FAULT1_0) #define HRTIM_OUTPUTFAULTLEVEL_INACTIVE (HRTIM_OUTR_FAULT1_1) #define HRTIM_OUTPUTFAULTLEVEL_HIGHZ (HRTIM_OUTR_FAULT1_1 | HRTIM_OUTR_FAULT1_0)
- ChopperModeEnable
設置是否使能chopper模式
#define HRTIM_OUTPUTCHOPPERMODE_DISABLED 0x00000000U /* 禁止 */ #define HRTIM_OUTPUTCHOPPERMODE_ENABLED (HRTIM_OUTR_CHP1) /* 使能 */
- BurstModeEntryDelayed
設置從突發模式切換到空閑模式前,是否插入一個死區時間。
#define HRTIM_OUTPUTBURSTMODEENTRY_REGULAR 0x00000000U /* 立即進入空閑狀態 */ #define HRTIM_OUTPUTBURSTMODEENTRY_DELAYED (HRTIM_OUTR_DIDL1) /* 進入空閑狀態前,插入死區時間 */
63.3.7 定時器比較配置HRTIM_CompareCfgTypeDef
此結構體主要用於定時器比較配置:
typedef struct { uint32_t CompareValue; uint32_t AutoDelayedMode; uint32_t AutoDelayedTimeout; } HRTIM_CompareCfgTypeDef;
下面將這幾個參數一 一做個說:
- CompareValue
設置定時器比較單元的比較值。
最小值要大於等於3個HRTIM時鍾周期。
最大值要小於等於0xFFFF – 1。
- AutoDelayedMode
設置比較單元2和4的自動延遲模式。
#define HRTIM_AUTODELAYEDMODE_REGULAR (0x00000000U) #define HRTIM_AUTODELAYEDMODE_AUTODELAYED_NOTIMEOUT (HRTIM_TIMCR_DELCMP2_0) #define HRTIM_AUTODELAYEDMODE_AUTODELAYED_TIMEOUTCMP1 (HRTIM_TIMCR_DELCMP2_1) #define HRTIM_AUTODELAYEDMODE_AUTODELAYED_TIMEOUTCMP3 (HRTIM_TIMCR_DELCMP2_1 | HRTIM_TIMCR_DELCMP2_0)
- AutoDelayedTimeout
當選擇了溢出時間的自動延遲模式時,指定計時單元1或3的比較值。
注意:CompareValue + AutoDelayedTimeout必須小於0xFFFFU
63.3.8 定時器句柄結構體HRTIM_HandleTypeDef
HAL庫在前面幾個結構體的基礎上封裝了一個結構體HRTIM_HandleTypeDef,定義如下:
#if (USE_HAL_HRTIM_REGISTER_CALLBACKS == 1) typedef struct __HRTIM_HandleTypeDef #else typedef struct #endif { HRTIM_TypeDef * Instance; /*!< Register base address */ HRTIM_InitTypeDef Init; /*!< HRTIM required parameters */ HRTIM_TimerParamTypeDef TimerParam[MAX_HRTIM_TIMER]; /*!< HRTIM timers */ HAL_LockTypeDef Lock; /*!< Locking object */ __IO HAL_HRTIM_StateTypeDef State; /*!< HRTIM communication state */ DMA_HandleTypeDef * hdmaMaster; /*!< Master timer DMA handle parameters */ DMA_HandleTypeDef * hdmaTimerA; /*!< Timer A DMA handle parameters */ DMA_HandleTypeDef * hdmaTimerB; /*!< Timer B DMA handle parameters */ DMA_HandleTypeDef * hdmaTimerC; /*!< Timer C DMA handle parameters */ DMA_HandleTypeDef * hdmaTimerD; /*!< Timer D DMA handle parameters */ DMA_HandleTypeDef * hdmaTimerE; /*!< Timer E DMA handle parameters */ #if (USE_HAL_HRTIM_REGISTER_CALLBACKS == 1) void (* Fault1Callback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* Fault2Callback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* Fault3Callback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* Fault4Callback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* Fault5Callback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* SystemFaultCallback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* BurstModePeriodCallback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* SynchronizationEventCallback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* ErrorCallback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* RegistersUpdateCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* RepetitionEventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Compare1EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Compare2EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Compare3EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Compare4EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Capture1EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Capture2EventCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* DelayedProtectionCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* CounterResetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Output1SetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Output1ResetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Output2SetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* Output2ResetCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* BurstDMATransferCallback)(struct __HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx); void (* MspInitCallback)(struct __HRTIM_HandleTypeDef *hhrtim); void (* MspDeInitCallback)(struct __HRTIM_HandleTypeDef *hhrtim); #endif } HRTIM_HandleTypeDef;
這里注意條件編譯USE_HAL_HRTIM_REGISTER_CALLBACKS,用來設置使用自定義回調還是使用默認回調,此定義一般放在stm32h7xx_hal_conf.h文件里面設置:
#define USE_HAL_HRTIM_REGISTER_CALLBACKS 1
下面將這幾個參數一 一做個說:
- HRTIM_TypeDef * Instance;
這個參數是寄存器的例化,方便操作寄存器,比如設置MCR寄存器。
SET_BIT(hrtim->sMasterRegs.MCR, 0)。
- HRTIM_InitTypeDef Init
HRTIM初始化配置,在本章的63.3.2小節進行了說明。
- HRTIM_TimerParamTypeDef TimerParam[MAX_HRTIM_TIMER]
HRTIM的主定時器和5個定時器單元Timer A到E的配置。在本章的63.3.3小節進行了說明。
- HAL_LockTypeDef Lock
- __IO HAL_HRTIM_StateTypeDef State
這兩個變量主要供函數內部使用。Lock用於設置鎖狀態,State用於設置HRTIM狀態。
- DMA_HandleTypeDef * hdmaMaster;
- DMA_HandleTypeDef * hdmaTimerA;
- DMA_HandleTypeDef * hdmaTimerB;
- DMA_HandleTypeDef * hdmaTimerC;
- DMA_HandleTypeDef * hdmaTimerD;
- DMA_HandleTypeDef * hdmaTimerE;
用於關聯DMA。
- 其它所有參數
用於自定義回調。
63.3.9 定時器的底層配置(GPIO,時鍾,中斷等)
HAL庫有自己的底層初始化回調函數,用於GPIO,時鍾,中斷等初始化,比如調用函數HAL_HRTIM_Init就會調用HAL_HRTIM_MspInit,此函數是弱定義的。
__weak void HAL_HRTIM_MspInit(HRTIM_HandleTypeDef * hhrtim) { /* Prevent unused argument(s) compilation warning */ UNUSED(hhrtim); /* NOTE: This function should not be modified, when the callback is needed, the HAL_HRTIM_MspInit could be implemented in the user file */ }
用戶可以在其它的C文件重定向,並將相對的底層初始化在里面實現。對應的底層復位初始化函數HAL_HRTIM_DeInit是在函數HAL_HRTIM_MspDeInit里面被調用的,也是弱定義的。
除了默認回調,用戶也可為HRTIM句柄成員MspInitCallback注冊一個回調函數,然后設置宏定義USE_HAL_HRTIM_REGISTER_CALLBACKS為1即可。這樣以來,用戶調用了HAL_HRTIM_Init后,此函數就會調用用戶注冊的回調函數。使用注冊回調好處是每個定時器可以有獨立的回調,無需多少個定時器共用
當然,用戶也可以自己初始化,不限制必須在兩個函數里面實現。
關於這個底層配置有以下幾點要着重說明下:
- 定時器所使用引腳的復用模式選擇已經被HAL庫定義好,放在了stm32h7xx_hal_gpio_ex.h文件里面。但是里面卻有三個復用:
#define GPIO_AF1_HRTIM1 ((uint8_t)0x01) #define GPIO_AF2_HRTIM1 ((uint8_t)0x02) #define GPIO_AF3_HRTIM1 ((uint8_t)0x03)
具體使用哪個,配置對應引腳的復用即可:
63.3.10 定時器初始化流程總結
使用方法由HAL庫提供:
HRTIM的API主要分為兩類,Simple mode和waveform mode
- Simple mode
與通用定時器的相同,只是分辨率更高,支持的模式如下:
a、輸出比較模式。
b、PWM輸出模式。
c、輸入捕獲模式。
d、單脈沖模式。
函數以HAL_HRTIM_Simple開頭。
- Waveform mode
這個模式下的API可以充分發揮HRTIM的所有特性。所有功能都可以使用,而且沒有任何限制。函數以HAL_HRTIM_Waveform開頭。
第1步:通過函數HAL_HRTIM_MspInit實現HRTIM的底層初始化是
- 函數__HRTIMx_CLK_ENABLE()使能時鍾。
- 初始化使用了的IO引腳,__HAL_RCC_GPIOx_CLK_ENABLE和HAL_GPIO_Init。
- 使用DMA方式控制數據傳輸,比如HAL_HRTIM_SimpleBaseStart_DMA。
a、使能DMA接口時鍾__DMAx_CLK_ENABLE。
b、初始化DMA句柄。
c、調用函數__HAL_LINKDMA關聯DMA和HRTIM句柄。
d、調用函數HAL_DMA_Init初始化DMA。
e、HAL_NVIC_SetPriority配置DMA優先級,HAL_NVIC_EnableIRQ使能DMA中斷。
- 使用中斷方式控制數據傳輸,比如HAL_HRTIM_SimpleBaseStart_IT,
HAL_NVIC_SetPriority配置DMA優先級,HAL_NVIC_EnableIRQ使能DMA中斷。
第2步:初始化HRTIM使用函數HAL_HRTIM_Init
此函數除了配置HRTIM句柄的結構體成員,還包括外部同步配置,HRTIM既可以作為master發出同步信號,也可以作為slave,等待接收同步信號。
第3步:配置HRTIM
- 突發模式控制器
HAL_HRTIM_BurstModeConfig突發模式配置
- 外部事件條件
HAL_HRTIM_EventConfig 配置外部事件條件
HAL_HRTIM_EventPrescalerConfig 配置外部事件采樣時鍾
- 異常條件
HAL_HRTIM_FaultConfig 配置異常通道
HAL_HRTIM_FaultPrescalerConfig 預分頻配置
HAL_HRTIM_FaultModeCtl 使能或者禁止輸入電路
- ADC觸發
HAL_HRTIM_ADCTriggerConfig 配置觸發ADC
第4步,配置HRTIM時基
使用函數HAL_HRTIM_TimeBaseConfig配置定時器時間基准,不管用於Simple Mode還是Waveform Mode,都必須調用這個函數進行配置。
- HRTIM定時器計數操作模式。
- HRTIM定時器時鍾分頻。
- HRTIM定時器周期。
- HRTIM重復計數器。
第5步,如果HRTIM工作在Simple Mode可以調用的API
- 時間基准模式:
HAL_HRTIM_SimpleBaseStart(),HAL_HRTIM_SimpleBaseStop(),
HAL_HRTIM_SimpleBaseStart_IT(),HAL_HRTIM_SimpleBaseStop_IT(),
HAL_HRTIM_SimpleBaseStart_DMA(),HAL_HRTIM_SimpleBaseStop_DMA()。
- 輸出比較:
HAL_HRTIM_SimpleOCChannelConfig(),
HAL_HRTIM_SimpleOCStart(),HAL_HRTIM_SimpleOCStop(),
HAL_HRTIM_SimpleOCStart_IT(),HAL_HRTIM_SimpleOCStop_IT(),
HAL_HRTIM_SimpleOCStart_DMA(),HAL_HRTIM_SimpleOCStop_DMA()。
- PWM輸出:
HAL_HRTIM_SimplePWMChannelConfig(),
HAL_HRTIM_SimplePWMStart(),HAL_HRTIM_SimplePWMStop(),
HAL_HRTIM_SimplePWMStart_IT(),HAL_HRTIM_SimplePWMStop_IT(),
HAL_HRTIM_SimplePWMStart_DMA(),HAL_HRTIM_SimplePWMStop_DMA()。
- 輸入捕獲:
HAL_HRTIM_SimpleCaptureChannelConfig(),
HAL_HRTIM_SimpleCaptureStart(),HAL_HRTIM_SimpleCaptureStop(),
HAL_HRTIM_SimpleCaptureStart_IT(),HAL_HRTIM_SimpleCaptureStop_IT()。
- 單脈沖模式:
HAL_HRTIM_SimpleOnePulseChannelConfig(),
HAL_HRTIM_SimpleOnePulseStart(),HAL_HRTIM_SimpleOnePulseStop(),
HAL_HRTIM_SimpleOnePulseStart_IT(),HAL_HRTIM_SimpleOnePulseStop_It()。
第6步,如果HRTIM工作在waveform模式可以調用的API
- HAL_HRTIM_WaveformTimerConfig
使能HRTIM中斷和DMA請求。
使能HRTIM的HALF Mode。
定義HRTIM如何響應外部同步輸入。
使能HRTIM的推挽模式。
使能HRTIM的異常通道。
使能dead-time插入。
設置HRTIM的延遲保護。
設置HRTIM的更新和復位觸發。
設置HRTIM寄存器的更新策略。
配置外部事件消隱和開窗電路。
Blanking:在規定的時間內屏蔽外部事件。
Windowing:只能在規定的時間內使能外部事件。
- HAL_HRTIM_DeadTimeConfig
配置HRTIM的死區插入,用於配置互補信號。
- HAL_HRTIM_ChopperModeConfig
用於配置在定時之上添加的高頻載波信號輸出,HRTIM的每個輸出都可以單獨使能或者禁止 Chopper。
- HAL_HRTIM_BurstDMAConfig
配置HRTIM的DMA突發模式。
- HAL_HRTIM_WaveformCompareConfig
配置HRTIM的比較單元。
- HAL_HRTIM_WaveformCaptureConfig
配置HRTIM的捕獲單元。
- HAL_HRTIM_WaveformOutputConfig
配置HRTIM輸出。
- HAL_HRTIM_WaveformSetOutputLevel
配置激活或者非激活態。
- 使能或者禁止waveform timer輸出
HAL_HRTIM_WaveformOutputStart(),HAL_HRTIM_WaveformOutputStop().。
- 啟動或者禁止HRTIM
HAL_HRTIM_WaveformCountStart(), HAL_HRTIM_WaveformCountStop(),
HAL_HRTIM_WaveformCountStart_IT(), HAL_HRTIM_WaveformCountStop_IT(),
HAL_HRTIM_WaveformCountStart_DMA(), HAL_HRTIM_WaveformCountStop_DMA()。
- 突發模式控制器使能:
HAL_HRTIM_BurstModeCtl()。
- 軟件觸發 :
HAL_HRTIM_BurstModeSoftwareTrigger()
HAL_HRTIM_SoftwareCapture()
HAL_HRTIM_SoftwareUpdate()
HAL_HRTIM_SoftwareReset()。
第7步,根據需要可以做動態注冊回調
首先使能宏定義USE_HAL_HRTIM_REGISTER_CALLBACKS。
然后調用函數HAL_HRTIM_RegisterCallback() 就可以注冊如下回調函數:
(+) Fault1Callback
(+) Fault2Callback
(+) Fault3Callback
(+) Fault4Callback
(+) Fault5Callback
(+) SystemFaultCallback
(+) BurstModePeriodCallback
(+) SynchronizationEventCallback
(+) ErrorCallback
(+) MspInitCallback
(+) MspDeInitCallback
函數HAL_HRTIM_TIMxRegisterCallback允許注冊的回調函數如下:
(+) RegistersUpdateCallback
(+) RepetitionEventCallback
(+) Compare1EventCallback
(+) Compare2EventCallback
(+) Compare3EventCallback
(+) Compare4EventCallback
(+) Capture1EventCallback
(+) Capture2EventCallback
(+) DelayedProtectionCallback
(+) CounterResetCallback
(+) Output1SetCallback
(+) Output1ResetCallback
(+) Output2SetCallback
(+) Output2ResetCallback
(+) BurstDMATransferCallback
關於動態注冊回調函數注意以下幾點:
- 卸載注冊使用HAL_HRTIM_UnRegisterCallback和HAL_HRTIM_TIMxUnRegisterCallback
- 默認情況下,HAL_HRTIM_Init調用后將使用默認的弱定義回調,如果用戶注冊了回調,將使用用戶設置的。
- 回調函數只能在HAL_HRTIM_STATE_READY狀態下才可以注冊/注銷。
-
- 回調函數MspInit和MspDeInit除外,這兩個函數可以在HAL_HRTIM_STATE_READY 或 HAL_HRTIM_STATE_RESET狀態下注冊,這樣的話,用戶調用函數HAL_HRTIM_DeInit()或者HAL_HRTIM_Init()時,就可以在其函數內運行MspInit/DeInit。
- 用戶可以在調用HAL_HRTIM_DeInit()或者HAL_HRTIM_Init()之前調用HAL_HRTIM_RegisterCallback()為MspInit/MspDeInit注冊回調。
HRTIM常用的功能,通過上面這幾步即可實現。
63.4 源文件stm32h7xx_hal_hrtim.c
此文件涉及到的函數非常多,這里把幾個常用的函數做個說明:
- HAL_HRTIM_Init
- HAL_HRTIM_TimeBaseConfig
- HAL_HRTIM_WaveformTimerConfig
- HAL_HRTIM_WaveformCompareConfig
- HAL_HRTIM_WaveformOutputConfig
- HAL_HRTIM_WaveformOutputStart
- HAL_HRTIM_WaveformCounterStart
63.4.1 函數HAL_HRTIM_Init
函數原型:
HAL_StatusTypeDef HAL_HRTIM_Init(HRTIM_HandleTypeDef * hhrtim) { uint8_t timer_idx; uint32_t hrtim_mcr; /* 檢查句柄是否有效 */ if(hhrtim == NULL) { return HAL_ERROR; } /* 檢測參數 */ assert_param(IS_HRTIM_ALL_INSTANCE(hhrtim->Instance)); assert_param(IS_HRTIM_IT(hhrtim->Init.HRTIMInterruptResquests)); /* 使用注冊回調,這樣每個定時器可以有獨立的回調,無需多個定時器共用 */ #if (USE_HAL_HRTIM_REGISTER_CALLBACKS == 1) if (hhrtim->State == HAL_HRTIM_STATE_RESET) { /* 初始化回調函數到默認值, 也就是說,如果用戶使能了回調函數的注冊功能,但是沒有指定具體回調,就是用默認的 */ hhrtim->Fault1Callback = HAL_HRTIM_Fault1Callback; hhrtim->Fault2Callback = HAL_HRTIM_Fault2Callback; hhrtim->Fault3Callback = HAL_HRTIM_Fault3Callback; hhrtim->Fault4Callback = HAL_HRTIM_Fault4Callback; hhrtim->Fault5Callback = HAL_HRTIM_Fault5Callback; hhrtim->SystemFaultCallback = HAL_HRTIM_SystemFaultCallback; hhrtim->BurstModePeriodCallback = HAL_HRTIM_BurstModePeriodCallback; hhrtim->SynchronizationEventCallback = HAL_HRTIM_SynchronizationEventCallback; hhrtim->ErrorCallback = HAL_HRTIM_ErrorCallback; hhrtim->RegistersUpdateCallback = HAL_HRTIM_RegistersUpdateCallback; hhrtim->RepetitionEventCallback = HAL_HRTIM_RepetitionEventCallback; hhrtim->Compare1EventCallback = HAL_HRTIM_Compare1EventCallback; hhrtim->Compare2EventCallback = HAL_HRTIM_Compare2EventCallback; hhrtim->Compare3EventCallback = HAL_HRTIM_Compare3EventCallback; hhrtim->Compare4EventCallback = HAL_HRTIM_Compare4EventCallback; hhrtim->Capture1EventCallback = HAL_HRTIM_Capture1EventCallback; hhrtim->Capture2EventCallback = HAL_HRTIM_Capture2EventCallback; hhrtim->DelayedProtectionCallback = HAL_HRTIM_DelayedProtectionCallback; hhrtim->CounterResetCallback = HAL_HRTIM_CounterResetCallback; hhrtim->Output1SetCallback = HAL_HRTIM_Output1SetCallback; hhrtim->Output1ResetCallback = HAL_HRTIM_Output1ResetCallback; hhrtim->Output2SetCallback = HAL_HRTIM_Output2SetCallback; hhrtim->Output2ResetCallback = HAL_HRTIM_Output2ResetCallback; hhrtim->BurstDMATransferCallback = HAL_HRTIM_BurstDMATransferCallback; if (hhrtim->MspInitCallback == NULL) { hhrtim->MspInitCallback = HAL_HRTIM_MspInit; } } #endif /* USE_HAL_HRTIM_REGISTER_CALLBACKS */ /* 設置HRTIM忙 */ hhrtim->State = HAL_HRTIM_STATE_BUSY; /* 初始化DMA句柄 */ hhrtim->hdmaMaster = (DMA_HandleTypeDef *)NULL; hhrtim->hdmaTimerA = (DMA_HandleTypeDef *)NULL; hhrtim->hdmaTimerB = (DMA_HandleTypeDef *)NULL; hhrtim->hdmaTimerC = (DMA_HandleTypeDef *)NULL; hhrtim->hdmaTimerD = (DMA_HandleTypeDef *)NULL; hhrtim->hdmaTimerE = (DMA_HandleTypeDef *)NULL; /* HRTIM輸出同步配置 */ if ((hhrtim->Init.SyncOptions & HRTIM_SYNCOPTION_MASTER) != (uint32_t)RESET) { /* 檢測參數 */ assert_param(IS_HRTIM_SYNCOUTPUTSOURCE(hhrtim->Init.SyncOutputSource)); assert_param(IS_HRTIM_SYNCOUTPUTPOLARITY(hhrtim->Init.SyncOutputPolarity)); /* 同步輸出初始化必須優先於MCU輸出配置(通過HAL_HRTIM_MspInit) */ if (hhrtim->Instance == HRTIM1) { /* 使能HRTIM外設時鍾 */ __HAL_RCC_HRTIM1_CLK_ENABLE(); } hrtim_mcr = hhrtim->Instance->sMasterRegs.MCR; /* 設置同步輸出事件 */ hrtim_mcr &= ~(HRTIM_MCR_SYNC_SRC); hrtim_mcr |= (hhrtim->Init.SyncOutputSource & HRTIM_MCR_SYNC_SRC); /* 設置同步輸出極性 */ hrtim_mcr &= ~(HRTIM_MCR_SYNC_OUT); hrtim_mcr |= (hhrtim->Init.SyncOutputPolarity & HRTIM_MCR_SYNC_OUT); /* 更新HRTIM寄存器 */ hhrtim->Instance->sMasterRegs.MCR = hrtim_mcr; } /* 初始化底層硬件: GPIO, CLOCK, NVIC 和 DMA */ #if (USE_HAL_HRTIM_REGISTER_CALLBACKS == 1) hhrtim->MspInitCallback(hhrtim); #else HAL_HRTIM_MspInit(hhrtim); #endif /* USE_HAL_HRTIM_REGISTER_CALLBACKS */ /* HRTIM同步輸入配置 HRTIM */ if ((hhrtim->Init.SyncOptions & HRTIM_SYNCOPTION_SLAVE) != (uint32_t)RESET) { /* 檢測參數 */ assert_param(IS_HRTIM_SYNCINPUTSOURCE(hhrtim->Init.SyncInputSource)); hrtim_mcr = hhrtim->Instance->sMasterRegs.MCR; /* 設置同步輸入源 */ hrtim_mcr &= ~(HRTIM_MCR_SYNC_IN); hrtim_mcr |= (hhrtim->Init.SyncInputSource & HRTIM_MCR_SYNC_IN); /* 更新HRTIM寄存器 */ hhrtim->Instance->sMasterRegs.MCR = hrtim_mcr; } /* 設置HRTIM寄存器就緒 */ hhrtim->State = HAL_HRTIM_STATE_READY; /* 初始化HRTIM HAL API的鎖狀態,即開鎖 */ __HAL_UNLOCK(hhrtim); /* 初始化HRTIM TIMER相關參數 */ for (timer_idx = HRTIM_TIMERINDEX_TIMER_A ; timer_idx <= HRTIM_TIMERINDEX_MASTER ; timer_idx++) { hhrtim->TimerParam[timer_idx].CaptureTrigger1 = HRTIM_CAPTURETRIGGER_NONE; hhrtim->TimerParam[timer_idx].CaptureTrigger2 = HRTIM_CAPTURETRIGGER_NONE; hhrtim->TimerParam[timer_idx].InterruptRequests = HRTIM_IT_NONE; hhrtim->TimerParam[timer_idx].DMARequests = HRTIM_IT_NONE; hhrtim->TimerParam[timer_idx].DMASrcAddress = 0U; hhrtim->TimerParam[timer_idx].DMASize = 0U; } return HAL_OK; }
函數描述:
此函數用於初始化HRTIM。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
1、宏定義USE_HAL_HRTIM_REGISTER_CALLBACKS可以放在stm32h7xx_hal_conf.h文件里面使能
#define USE_HAL_HRTIM_REGISTER_CALLBACKS 1
使用注冊回調好處是每個定時器可以有獨立的回調,無需多個定時器共用。
2、函數HAL_HRTIM_MspInit用於初始化定時器的底層時鍾、引腳等功能。需要用戶自己在此函數里面實現具體的功能,由於這個函數是弱定義的,允許用戶在工程其它源文件里面重新實現此函數。當然,不限制一定要在此函數里面實現,也可以像早期的標准庫那樣,用戶自己初始化即可,更靈活些。
3、如果形參htim的結構體成員State沒有做初始狀態,這個地方就是個坑。特別是用戶搞了一個局部變量HRTIM_HandleTypeDef HRTimHandle。
對於局部變量來說,這個參數就是一個隨機值,如果是全局變量還好,一般MDK和IAR都會將全部變量初始化為0,而恰好這個 HAL_HRTIM_STATE_RESET = 0x00U。
解決辦法有三:
方法1:用戶自己初始定時器和涉及到的GPIO等。
方法2:定義HRTIM_HandleTypeDef HRTimHandle為全局變量。
方法3:下面的方法
if(HAL_HRTIM_DeInit(&HRTimHandle) != HAL_OK) { Error_Handler(); } if(HAL_HRTIM_Init(&HRTimHandle) != HAL_OK) { Error_Handler(); }
使用舉例:
HRTIM_HandleTypeDef HrtimHandle = {0}; /* 例化,使用的HRTIM1 */ HrtimHandle.Instance = HRTIM1; /* 用於配置支持的中斷請求,當前配置無中斷 */ HrtimHandle.Init.HRTIMInterruptResquests = HRTIM_IT_NONE; /* 配置HRTIM作為Master,發送同步信號,或者作為Slave,接收同步信號,當前配置沒有做同步功能 */ HrtimHandle.Init.SyncOptions = HRTIM_SYNCOPTION_NONE; HAL_HRTIM_Init(&HrtimHandle);
63.4.2 函數HAL_HRTIM_TimeBaseConfig
函數原型:
HAL_StatusTypeDef HAL_HRTIM_TimeBaseConfig(HRTIM_HandleTypeDef *hhrtim, uint32_t TimerIdx, HRTIM_TimeBaseCfgTypeDef * pTimeBaseCfg) { /* 檢查參數 */ assert_param(IS_HRTIM_TIMERINDEX(TimerIdx)); assert_param(IS_HRTIM_PRESCALERRATIO(pTimeBaseCfg->PrescalerRatio)); assert_param(IS_HRTIM_MODE(pTimeBaseCfg->Mode)); if(hhrtim->State == HAL_HRTIM_STATE_BUSY) { return HAL_BUSY; } /* 設置HRTIM狀態忙 */ hhrtim->State = HAL_HRTIM_STATE_BUSY; if (TimerIdx == HRTIM_TIMERINDEX_MASTER) { /* 配置MASTER TIMER時基 */ HRTIM_MasterBase_Config(hhrtim, pTimeBaseCfg); } else { /* 配置Timing單元時基(Timer A到Timer E) */ HRTIM_TimingUnitBase_Config(hhrtim, TimerIdx, pTimeBaseCfg); } /* 設置HRTIM就緒 */ hhrtim->State = HAL_HRTIM_STATE_READY; return HAL_OK; }
函數描述:
配置定時器時基單元。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 第2個參數是使用的定時器索引,支持的參數如下:
- HRTIM_TIMERINDEX_MASTER。
- HRTIM_TIMERINDEX_TIMER_A。
- HRTIM_TIMERINDEX_TIMER_B。
- HRTIM_TIMERINDEX_TIMER_C。
- HRTIM_TIMERINDEX_TIMER_D。
- HRTIM_TIMERINDEX_TIMER_E。
- 第3個參數是HRTIM_TimeBaseCfgTypeDef類型結構指針變量。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
- 啟動定時器前,優先調用此函數。
- 配置定時器計數器工作在連續或者單次模式以及時鍾分頻,周期和重復計數器。
使用舉例:
HRTIM_TimeBaseCfgTypeDef sConfig_time_base = {0}; /* PWM的頻率 = 400MHz / HRTIM_TIMD_PERIOD = 400000000 / 4000 = 100KHz */ sConfig_time_base.Mode = HRTIM_MODE_CONTINUOUS; /* 連續工作模式 */ sConfig_time_base.Period = HRTIM_TIMD_PERIOD; /* 設置周期 */ /* 設置HRTIM分頻,當前設置的1分頻,也就是不分頻 */ sConfig_time_base.PrescalerRatio = HRTIM_PRESCALERRATIO_DIV1; sConfig_time_base.RepetitionCounter = 0; /* 設置重復計數器為0,即不做重復計數 */ HAL_HRTIM_TimeBaseConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, &sConfig_time_base);
63.4.3 函數HAL_HRTIM_WaveformTimerConfig
函數原型:
HAL_StatusTypeDef HAL_HRTIM_WaveformTimerConfig(HRTIM_HandleTypeDef * hhrtim, uint32_t TimerIdx, HRTIM_TimerCfgTypeDef * pTimerCfg) { /* 檢查參數是否有效 */ assert_param(IS_HRTIM_TIMERINDEX(TimerIdx)); assert_param(IS_HRTIM_HALFMODE(pTimerCfg->HalfModeEnable)); assert_param(IS_HRTIM_SYNCSTART(pTimerCfg->StartOnSync)); assert_param(IS_HRTIM_SYNCRESET(pTimerCfg->ResetOnSync)); assert_param(IS_HRTIM_DACSYNC(pTimerCfg->DACSynchro)); assert_param(IS_HRTIM_PRELOAD(pTimerCfg->PreloadEnable)); assert_param(IS_HRTIM_TIMERBURSTMODE(pTimerCfg->BurstMode)); assert_param(IS_HRTIM_UPDATEONREPETITION(pTimerCfg->RepetitionUpdate)); /* 檢測HRTIM是否處於忙狀態 */ if(hhrtim->State == HAL_HRTIM_STATE_BUSY) { return HAL_BUSY; } /* 操作期間,上鎖 */ __HAL_LOCK(hhrtim); hhrtim->State = HAL_HRTIM_STATE_BUSY; if (TimerIdx == HRTIM_TIMERINDEX_MASTER) { /* 檢查參數 */ assert_param(IS_HRTIM_UPDATEGATING_MASTER(pTimerCfg->UpdateGating)); assert_param(IS_HRTIM_MASTER_IT(pTimerCfg->InterruptRequests)); assert_param(IS_HRTIM_MASTER_DMA(pTimerCfg->DMARequests)); /* 配置Master Timer */ HRTIM_MasterWaveform_Config(hhrtim, pTimerCfg); } else { /* 檢查參數 */ assert_param(IS_HRTIM_UPDATEGATING_TIM(pTimerCfg->UpdateGating)); assert_param(IS_HRTIM_TIM_IT(pTimerCfg->InterruptRequests)); assert_param(IS_HRTIM_TIM_DMA(pTimerCfg->DMARequests)); assert_param(IS_HRTIM_TIMPUSHPULLMODE(pTimerCfg->PushPull)); assert_param(IS_HRTIM_TIMFAULTENABLE(pTimerCfg->FaultEnable)); assert_param(IS_HRTIM_TIMFAULTLOCK(pTimerCfg->FaultLock)); assert_param(IS_HRTIM_TIMDEADTIMEINSERTION(pTimerCfg->PushPull, pTimerCfg->DeadTimeInsertion)); assert_param(IS_HRTIM_TIMDELAYEDPROTECTION(pTimerCfg->PushPull, pTimerCfg->DelayedProtectionMode)); assert_param(IS_HRTIM_TIMUPDATETRIGGER(pTimerCfg->UpdateTrigger)); assert_param(IS_HRTIM_TIMRESETTRIGGER(pTimerCfg->ResetTrigger)); assert_param(IS_HRTIM_TIMUPDATEONRESET(pTimerCfg->ResetUpdate)); /* 配置時序單元,從TIMER A到TIMER D */ HRTIM_TimingUnitWaveform_Config(hhrtim, TimerIdx, pTimerCfg); } /* 更新定時器參數 */ hhrtim->TimerParam[TimerIdx].InterruptRequests = pTimerCfg->InterruptRequests; hhrtim->TimerParam[TimerIdx].DMARequests = pTimerCfg->DMARequests; hhrtim->TimerParam[TimerIdx].DMASrcAddress = pTimerCfg->DMASrcAddress; hhrtim->TimerParam[TimerIdx].DMADstAddress = pTimerCfg->DMADstAddress; hhrtim->TimerParam[TimerIdx].DMASize = pTimerCfg->DMASize; /* 強制軟件更新 */ HRTIM_ForceRegistersUpdate(hhrtim, TimerIdx); hhrtim->State = HAL_HRTIM_STATE_READY; /* 解鎖 */ __HAL_UNLOCK(hhrtim); return HAL_OK; }
函數描述:
此函數用於配置HRTIM在waveform模式的工作方式。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 第2個參數是使用的定時器索引,支持的參數如下:
- HRTIM_TIMERINDEX_MASTER。
- HRTIM_TIMERINDEX_TIMER_A。
- HRTIM_TIMERINDEX_TIMER_B。
- HRTIM_TIMERINDEX_TIMER_C。
- HRTIM_TIMERINDEX_TIMER_D。
- HRTIM_TIMERINDEX_TIMER_E。
- 第3個參數是HRTIM_TimerCfgTypeDef類型結構指針變量。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
- 啟動定時器前,優先調用此函數。
- HRTIM工作在waveform模式才能發揮HRTIM全功能特性。
使用舉例:
HRTIM_TimerCfgTypeDef sConfig_timerD = {0}; sConfig_timerD.DMARequests = HRTIM_TIM_DMA_NONE; /* 不使用DMA */ sConfig_timerD.HalfModeEnable = HRTIM_HALFMODE_DISABLED;/* 關閉HALF模式 */ sConfig_timerD.StartOnSync = HRTIM_SYNCSTART_DISABLED; /* 設置同步輸入端接收到上升沿信號后,不啟動定時器 */ sConfig_timerD.ResetOnSync = HRTIM_SYNCRESET_DISABLED; /* 設置同步輸入端接收到上升沿信號后,不復位定時器 */ sConfig_timerD.DACSynchro = HRTIM_DACSYNC_NONE; /* 不使用DAC同步事件 */ sConfig_timerD.PreloadEnable = HRTIM_PRELOAD_ENABLED; /* 使能寄存器預加載 */ sConfig_timerD.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT; /* 獨立更新,與DMA突發傳輸完成無關 */ sConfig_timerD.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK; /* 在突發模式下,定時器正常運行 */ sConfig_timerD.RepetitionUpdate = HRTIM_UPDATEONREPETITION_ENABLED;/* 設置重計數器事件可以觸發寄存器更新 */ /* 當HRTIM TIMER的計數器復位時或者計數回滾到0時,不觸發寄存器更新 */ sConfig_timerD.ResetUpdate = HRTIM_TIMUPDATEONRESET_DISABLED; sConfig_timerD.InterruptRequests = HRTIM_TIM_IT_NONE; /* 不使用中斷 */ sConfig_timerD.PushPull = HRTIM_TIMPUSHPULLMODE_DISABLED; /* 不開啟推挽模式 */ sConfig_timerD.FaultEnable = HRTIM_TIMFAULTENABLE_NONE; /* 不使用HRTIM TIMER的Fault通道 */ sConfig_timerD.FaultLock = HRTIM_TIMFAULTLOCK_READWRITE; /* 不開啟HRTIM TIMER的異常使能狀態寫保護 */ sConfig_timerD.DeadTimeInsertion = HRTIM_TIMDEADTIMEINSERTION_DISABLED;/* 不開啟死區時間插入 */ /* 不開啟HRTIM TIMER的延遲保護模式 */ sConfig_timerD.DelayedProtectionMode = HRTIM_TIMER_D_E_DELAYEDPROTECTION_DISABLED; /* Master或TIMER(A到E)更新時,不同步更新寄存器 */ sConfig_timerD.UpdateTrigger= HRTIM_TIMUPDATETRIGGER_NONE; sConfig_timerD.ResetTrigger = HRTIM_TIMRESETTRIGGER_NONE; /* 無復位觸發 */ HAL_HRTIM_WaveformTimerConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, &sConfig_timerD);
63.4.4 函數HAL_HRTIM_WaveformCompareConfig
函數原型:
HAL_StatusTypeDef HAL_HRTIM_WaveformCompareConfig(HRTIM_HandleTypeDef * hhrtim, uint32_t TimerIdx, uint32_t CompareUnit, HRTIM_CompareCfgTypeDef* pCompareCfg) { /* 檢查參數 */ assert_param(IS_HRTIM_TIMERINDEX(TimerIdx)); if(hhrtim->State == HAL_HRTIM_STATE_BUSY) { return HAL_BUSY; } /* 處理過程上鎖 */ __HAL_LOCK(hhrtim); hhrtim->State = HAL_HRTIM_STATE_BUSY; /* 配置比較單元 */ if (TimerIdx == HRTIM_TIMERINDEX_MASTER) { /* 省略switch里面的具體內容 */ switch (CompareUnit) { case HRTIM_COMPAREUNIT_1: case HRTIM_COMPAREUNIT_2: case HRTIM_COMPAREUNIT_3: case HRTIM_COMPAREUNIT_4: default: } if(hhrtim->State == HAL_HRTIM_STATE_ERROR) { return HAL_ERROR; } } else { /* 省略switch里面的具體內容 */ switch (CompareUnit) { case HRTIM_COMPAREUNIT_1: case HRTIM_COMPAREUNIT_2: case HRTIM_COMPAREUNIT_3: case HRTIM_COMPAREUNIT_4: default: } if(hhrtim->State == HAL_HRTIM_STATE_ERROR) { return HAL_ERROR; } } hhrtim->State = HAL_HRTIM_STATE_READY; /* 解鎖 */ __HAL_UNLOCK(hhrtim); return HAL_OK; }
函數描述:
此函數用於配置HRTIM的定時器比較單元。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 第2個參數是使用的定時器索引,支持的參數如下:
- HRTIM_TIMERINDEX_MASTER。
- HRTIM_TIMERINDEX_TIMER_A。
- HRTIM_TIMERINDEX_TIMER_B。
- HRTIM_TIMERINDEX_TIMER_C。
- HRTIM_TIMERINDEX_TIMER_D。
- HRTIM_TIMERINDEX_TIMER_E
- 第3個參數是比較單元,支持的參數如下:
- HRTIM_COMPAREUNIT_1。
- HRTIM_COMPAREUNIT_2。
- HRTIM_COMPAREUNIT_3。
- HRTIM_COMPAREUNIT_4。
- 第4個參數是HRTIM_CompareCfgTypeDef類型結構體變量。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
- 啟動定時器前,優先調用此函數。
- 如果比較單元2或比較單元4需要自動延遲模式,應用程序必須單獨配置捕獲單元。
-
- 輸出比較2的自動延遲:捕獲單元1必須配置。
- 輸出比較4的自定延遲:捕獲單元2必須配置。
使用舉例:
HRTIM_CompareCfgTypeDef sConfig_compare = {0}; sConfig_compare.AutoDelayedMode = HRTIM_AUTODELAYEDMODE_REGULAR; /* 這里使用標准模式,即未使用自動延遲 */ sConfig_compare.AutoDelayedTimeout = 0; /* 由於前面的參數未使用自動延遲模式,此參數無作用 */ /* 設置定時器比較單元的比較值: 最小值要大於等於3個HRTIM時鍾周期。 最大值要小於等於0xFFFF – 1 */ sConfig_compare.CompareValue = 4000 / 2; /* 占空比50% */ HAL_HRTIM_WaveformCompareConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_1, &sConfig_compare);
63.4.5 函數HAL_HRTIM_WaveformOutputConfig
函數原型:
HAL_StatusTypeDef HAL_HRTIM_WaveformOutputConfig(HRTIM_HandleTypeDef * hhrtim, uint32_t TimerIdx, uint32_t Output, HRTIM_OutputCfgTypeDef * pOutputCfg) { /* 檢查參數 */ assert_param(IS_HRTIM_TIMER_OUTPUT(TimerIdx, Output)); assert_param(IS_HRTIM_OUTPUTPOLARITY(pOutputCfg->Polarity)); assert_param(IS_HRTIM_OUTPUTIDLELEVEL(pOutputCfg->IdleLevel)); assert_param(IS_HRTIM_OUTPUTIDLEMODE(pOutputCfg->IdleMode)); assert_param(IS_HRTIM_OUTPUTFAULTLEVEL(pOutputCfg->FaultLevel)); assert_param(IS_HRTIM_OUTPUTCHOPPERMODE(pOutputCfg->ChopperModeEnable)); assert_param(IS_HRTIM_OUTPUTBURSTMODEENTRY(pOutputCfg->BurstModeEntryDelayed)); if(hhrtim->State == HAL_HRTIM_STATE_BUSY) { return HAL_BUSY; } /* 處理過程上鎖 */ __HAL_LOCK(hhrtim); hhrtim->State = HAL_HRTIM_STATE_BUSY; /* 配置定時器輸出 */ HRTIM_OutputConfig(hhrtim, TimerIdx, Output, pOutputCfg); hhrtim->State = HAL_HRTIM_STATE_READY; /* 解鎖 */ __HAL_UNLOCK(hhrtim); return HAL_OK; }
函數描述:
此函數用於配置HRTIM的定時器(TIMER A到TIMER E)在waveform模式下的輸出。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 第2個參數是使用的定時器索引,支持的參數如下:
- HRTIM_TIMERINDEX_TIMER_A。
- HRTIM_TIMERINDEX_TIMER_B。
- HRTIM_TIMERINDEX_TIMER_C。
- HRTIM_TIMERINDEX_TIMER_D。
- HRTIM_TIMERINDEX_TIMER_E
- 第3個參數是具體的輸出通道,支持的參數如下:
- HRTIM_OUTPUT_TA1: Timer A - Output 1
- HRTIM_OUTPUT_TA2: Timer A - Output 2
- HRTIM_OUTPUT_TB1: Timer B - Output 1
- HRTIM_OUTPUT_TB2: Timer B - Output 2
- HRTIM_OUTPUT_TC1: Timer C - Output 1
- HRTIM_OUTPUT_TC2: Timer C - Output 2
- HRTIM_OUTPUT_TD1: Timer D - Output 1
- HRTIM_OUTPUT_TD2: Timer D - Output 2
- HRTIM_OUTPUT_TE1: Timer E - Output 1
- HRTIM_OUTPUT_TE2: Timer E - Output 2
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
- 配置定時器前,必須調用此函數。並且在配置死區時間插入之前調用(如果需要配置死區時間)。
使用舉例:
HRTIM_OutputCfgTypeDef sConfig_output_config = {0}; sConfig_output_config.Polarity = HRTIM_OUTPUTPOLARITY_LOW; /* 設置定時器輸出極性 */ sConfig_output_config.SetSource = HRTIM_OUTPUTRESET_TIMCMP1; /* 定時器比較事件1可以將輸出置位 */ sConfig_output_config.ResetSource = HRTIM_OUTPUTSET_TIMPER; /* 定時器周期性更新事件可以將輸出清零 */ sConfig_output_config.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE; /* 輸出不受突發模式影響 */ sConfig_output_config.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE; /* 設置空閑狀態輸出低電平 */ sConfig_output_config.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_NONE; /* 輸出不受異常輸入影響 */ sConfig_output_config.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED; /* 關閉Chopper模式 */ sConfig_output_config.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR; /* 設置從突發模式切換到空 閑模式,不插入死區時間 */ HAL_HRTIM_WaveformOutputConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, HRTIM_OUTPUT_TD1, &sConfig_output_config);
63.4.6 函數HAL_HRTIM_WaveformOutputStart
函數原型:
HAL_StatusTypeDef HAL_HRTIM_WaveformOutputStart(HRTIM_HandleTypeDef * hhrtim, uint32_t OutputsToStart) { /* 檢查參數 */ assert_param(IS_HRTIM_OUTPUT(OutputsToStart)); /* 處理過程上鎖 */ __HAL_LOCK(hhrtim); hhrtim->State = HAL_HRTIM_STATE_BUSY; /* 使能HRTIM輸出 */ hhrtim->Instance->sCommonRegs.OENR |= (OutputsToStart); hhrtim->State = HAL_HRTIM_STATE_READY; /* 處理完畢解鎖 */ __HAL_UNLOCK(hhrtim); return HAL_OK; }
函數描述:
此函數用於啟動HRTIM的waveform模式輸出。支持多個通道同時配置,即參數支持或操作。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 第2個參數用於使能要輸出的通道,這些參數支持或操作。
- HRTIM_OUTPUT_TA1: Timer A - Output 1
- HRTIM_OUTPUT_TA2: Timer A - Output 2
- HRTIM_OUTPUT_TB1: Timer B - Output 1
- HRTIM_OUTPUT_TB2: Timer B - Output 2
- HRTIM_OUTPUT_TC1: Timer C - Output 1
- HRTIM_OUTPUT_TC2: Timer C - Output 2
- HRTIM_OUTPUT_TD1: Timer D - Output 1
- HRTIM_OUTPUT_TD2: Timer D - Output 2
- HRTIM_OUTPUT_TE1: Timer E - Output 1
- HRTIM_OUTPUT_TE2: Timer E - Output 2
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
/* 啟動Timer D的通道1和通道2的PWM */ if (HAL_HRTIM_WaveformOutputStart(&HrtimHandle, HRTIM_OUTPUT_TD1 + HRTIM_OUTPUT_TD2) != HAL_OK) { Error_Handler(__FILE__, __LINE__); }
63.4.7 函數HAL_HRTIM_WaveformCounterStart
函數原型:
#define HAL_HRTIM_WaveformCounterStart HAL_HRTIM_WaveformCountStart HAL_StatusTypeDef HAL_HRTIM_WaveformCountStart(HRTIM_HandleTypeDef * hhrtim, uint32_t Timers) { /* 檢查參數 */ assert_param(IS_HRTIM_TIMERID(Timers)); /* 處理過程上鎖 */ __HAL_LOCK(hhrtim); hhrtim->State = HAL_HRTIM_STATE_BUSY; /* 使能定時器計數器 */ hhrtim->Instance->sMasterRegs.MCR |= (Timers); hhrtim->State = HAL_HRTIM_STATE_READY; /* 處理過程解鎖 */ __HAL_UNLOCK(hhrtim); return HAL_OK; }
函數描述:
此函數用於啟動定時器計數。
函數參數:
- 第1個參數是HRTIM_HandleTypeDef類型結構體指針變量。
- 第2個參數是定時器索引,支持以下參數,支持或操作:
- HRTIM_TIMERID_MASTER
- HRTIM_TIMERID_TIMER_A
- HRTIM_TIMERID_TIMER_B
- HRTIM_TIMERID_TIMER_C
- HRTIM_TIMERID_TIMER_D
- HRTIM_TIMERID_TIMER_E
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
/* 啟動Timer D的計數器 */ if (HAL_HRTIM_WaveformCounterStart(&HrtimHandle, HRTIM_TIMERID_TIMER_D) != HAL_OK) { Error_Handler(__FILE__, __LINE__); }
63.5 總結
本章節就為大家講解這么多,HRTIM涉及到的知識點非常多,大家看完本章節后可以再學習STM32H7的參考手冊做進一步了解。