完整教程下载地址: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的参考手册做进一步了解。