当前位置: 首页 > news >正文

STM32G474的HRTIM用作时基定时器

STM32G474的HRTIM由7个定时器组成,分别是主定时器,定时器A,定时器B,定时器C,定时器D,定时器E和定时器F,每个定时器均可单独配置,独立工作。每个定时器都有1个独立的计数器和4个独立的比较器

STM32G474的HRTIM用作定时器,通过对输入时钟计数,验证每个定时器是不是独立工作。理论再好,不如使用程序说明。搜索网络,少有人用。

1、HRTIM计数器的输入时钟频率

当系统时钟为170MHz时,则HRTIM的计数器的输入时钟频率为170*32=5,440MHz

pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32;
//HRTIM主定时器配置:HRTIM_MCR寄存器bit2:0(CKPSC[2:0])
//HRTIM定时器A控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])
//CKPSC[2:0]=000b,则“主定时器和定时器A”的输入时钟的分频值为1
//“主定时器和定时器A”分频后的输入时钟频率为:fHRCK=170 x 32 MHz = 5.44 GHz

2、测试程序

1)、HRTIM.c如下:

#include "HRTIM.h"
#include "delay.h"
#include "LED.h"/*
STM32G474的HRTIM由7个定时器组成,分别是主定时器,定时器A,定时器B,定时器C,定时器D,定时器E和定时器F;
每个定时器都有1个独立的计数器和4个独立的比较器;
PA8映射到HRTIM1_CHA1,PA9映射到HRTIM1_CHA2,由定时器A控制,可用作输入捕获引脚,或者用作比较器输出引脚;
PA10映射到HRTIM1_CHB1,PA11映射到HRTIM1_CHB2,由定时器B控制,可用作输入捕获引脚,或者用作比较器输出引脚;
PB12映射到HRTIM1_CHC1,PB13映射到HRTIM1_CHC2,由定时器C控制,可用作输入捕获引脚,或者用作比较器输出引脚;
PB14映射到HRTIM1_CHD1,PB15映射到HRTIM1_CHD2,由定时器D控制,可用作输入捕获引脚,或者用作比较器输出引脚;
PC8映射到HRTIM1_CHE1,PC9映射到HRTIM1_CHE2,由定时器E控制,可用作输入捕获引脚,或者用作比较器输出引脚;
PC6映射到HRTIM1_CHF1,PC7映射到HRTIM1_CHF2,由定时器A控制,可用作输入捕获引脚,或者用作比较器输出引脚;
时基定时器中断
*/uint32_t HRTIM_MASTER_cnt;
uint32_t HRTIM_A_cnt;
uint32_t HRTIM_B_cnt;void HRTIM_Init(void);void HRTIM_Init(void)
{HRTIM_HandleTypeDef  HRTIM1_structure;HRTIM_TimeBaseCfgTypeDef   pTimeBaseCfg  = {0};//HRTIM定时器基本参数描述结构体__HAL_RCC_HRTIM1_CLK_ENABLE();//设置RCC->APB2ENR寄存器bit16(HRTIM1EN),令HRTIM1EN=1,HRTIM1时钟使能,开启HRTIM1时钟主定时器,定时器A,定时器B,定时器C,定时器D,定时器E和定时器F初始化开始///	HRTIM1_structure.Instance = HRTIM1;                            //调用HRTIM1HRTIM1_structure.Init.HRTIMInterruptResquests = HRTIM_IT_NONE; //No interrupt enabledHRTIM1_structure.Init.SyncOptions = HRTIM_SYNCOPTION_NONE;     //HRTIM是否和外部定时器同步HAL_HRTIM_Init(&HRTIM1_structure);//初始化HRTIM1//HRTIM1_structure.TimerParam[0].CaptureTrigger1=HRTIM_CAPTURETRIGGER_NONE//HRTIM1_structure.TimerParam[0].CaptureTrigger2=HRTIM_CAPTURETRIGGER_NONE//HRTIM1_structure.TimerParam[0].InterruptRequests=HRTIM_IT_NONE//HRTIM1_structure.TimerParam[0].DMARequests=HRTIM_IT_NONE//HRTIM1_structure.TimerParam[0].DMASrcAddress=0//HRTIM1_structure.TimerParam[0].DMADstAddress//HRTIM1_structure.TimerParam[0].DMASize=0//直到HRTIM1_structure.TimerParam[6]//HRTIM1_structure.State=HAL_HRTIM_STATE_READY
主定时器,定时器A,定时器B,定时器C,定时器D,定时器E和定时器F初始化开始///pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32;//HRTIM主定时器配置:HRTIM_MCR寄存器bit2:0(CKPSC[2:0])//HRTIM定时器A控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])//CKPSC[2:0]=000b,则“主定时器和定时器A”的输入时钟的分频值为1//“主定时器和定时器A”分频后的输入时钟频率为:fHRCK=170 x 32 MHz = 5.44 GHzpTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS;//连续计数,周而复始//HRTIM主定时器配置:HRTIM_MCR寄存器bit4:3(RETRIG:CONT)//HRTIM定时器A控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])//RETRIG=0,计时器不能重复触发:只有当计数器停止(周期已过去)时,才能进行计数器重置 //CONT=1,计时器在连续(自由运行)模式下运行,当它达到MPER值时滚转为零pTimeBaseCfg.Period = MASTER_PERIOD;//主定时器溢出周期为5us//HRTIM主定时器周期配置:HRTIM_MPER寄存器bit15:0(MPER[15:0])//HRTIM定时器A周期寄存器配置;HRTIM_PERxR寄存器bit15:0(PERx[15:0])pTimeBaseCfg.RepetitionCounter = 9;//重复(9+1)个周期,发生1次中断//HRTIM主定时器重复周期值配置:HRTIM_MREP寄存器bit7:0(MREP[7:0]),MREP[7:0]=0x00//HRTIM定时器A重复周期值配置:HRTIM_REPxR寄存器bit7:0(MREP[7:0]),MREP[7:0]=0x00HAL_HRTIM_TimeBaseConfig(&HRTIM1_structure, HRTIM_TIMERINDEX_MASTER, &pTimeBaseCfg);//初始化HRTIM主定时器HAL_NVIC_SetPriority(HRTIM1_Master_IRQn,3,0);//“主定时器”抢占优先级为3,响应优先级为0//设置NVIC中断分组4:4位抢占优先级,0位响应优先级//选择中断优先级组4,即抢占优先级为4位,取值为0~15,响应优先级组为0位,取值为0HAL_NVIC_EnableIRQ(HRTIM1_Master_IRQn);      //使能“主定时器”中断HAL_HRTIM_SimpleBaseStart_IT(&HRTIM1_structure,HRTIM_TIMERINDEX_MASTER);//启动主定时器HRTIM_MASTER_cnt=0;/定时器A初始化开始//pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32;//HRTIM定时器A配置:HRTIM_MCR寄存器bit2:0(CKPSC[2:0])//HRTIM定时器A控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])//CKPSC[2:0]=000b,则“定时器A”的输入时钟的分频值为1//“定时器A”分频后的输入时钟频率为:fHRCK=170 x 32 MHz = 5.44 GHzpTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS;//连续计数,周而复始//HRTIM定时器A配置:HRTIM_MCR寄存器bit4:3(RETRIG:CONT)//HRTIM定时器A控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])//RETRIG=0,计时器不能重复触发:只有当计数器停止(周期已过去)时,才能进行计数器重置 //CONT=1,计时器在连续(自由运行)模式下运行,当它达到MPER值时滚转为零pTimeBaseCfg.Period = TIM_A_PERIOD;//HRTIM定时器A溢出周期为10us//HRTIM定时器A周期配置:HRTIM_MPER寄存器bit15:0(MPER[15:0])//HRTIM定时器A周期寄存器配置;HRTIM_PERxR寄存器bit15:0(PERx[15:0])pTimeBaseCfg.RepetitionCounter = 9;//重复(9+1)个周期,发生1次中断//HRTIM定时器A重复周期值配置:HRTIM_MREP寄存器bit7:0(MREP[7:0]),MREP[7:0]=0x00//HRTIM定时器A重复周期值配置:HRTIM_REPxR寄存器bit7:0(MREP[7:0]),MREP[7:0]=0x00HAL_HRTIM_TimeBaseConfig(&HRTIM1_structure, HRTIM_TIMERINDEX_TIMER_A, &pTimeBaseCfg);//初始化HRTIM定时器A__HAL_HRTIM_TIMER_ENABLE_IT(&HRTIM1_structure,HRTIM_TIMERINDEX_TIMER_A,HRTIM_TIM_IT_REP);//使能“定时器A”重复中断HAL_NVIC_SetPriority(HRTIM1_TIMA_IRQn,3,0);//“定时器A”抢占优先级为3,响应优先级为0//设置NVIC中断分组4:4位抢占优先级,0位响应优先级//选择中断优先级组4,即抢占优先级为4位,取值为0~15,响应优先级组为0位,取值为0HAL_NVIC_EnableIRQ(HRTIM1_TIMA_IRQn);      //使能“定时器A”中断HAL_HRTIM_SimpleBaseStart_IT(&HRTIM1_structure,HRTIM_TIMERINDEX_TIMER_A);//启动主定时器HRTIM_A_cnt=0;/定时器B初始化开始//pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32;//HRTIM定时器B配置:HRTIM_MCR寄存器bit2:0(CKPSC[2:0])//HRTIM定时器B控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])//CKPSC[2:0]=000b,则“定时器B”的输入时钟的分频值为1//“定时器B”分频后的输入时钟频率为:fHRCK=170 x 32 MHz = 5.44 GHzpTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS;//连续计数,周而复始//HRTIM定时器B配置:HRTIM_MCR寄存器bit4:3(RETRIG:CONT)//HRTIM定时器B控制寄存器配置:HRTIM_TIMxCR寄存器bit2:0(CKPSC[2:0])//RETRIG=0,计时器不能重复触发:只有当计数器停止(周期已过去)时,才能进行计数器重置 //CONT=1,计时器在连续(自由运行)模式下运行,当它达到MPER值时滚转为零pTimeBaseCfg.Period = TIM_B_PERIOD;//HRTIM定时器B溢出周期为2us//HRTIM定时器B周期配置:HRTIM_MPER寄存器bit15:0(MPER[15:0])//HRTIM定时器B周期寄存器配置;HRTIM_PERxR寄存器bit15:0(PERx[15:0])pTimeBaseCfg.RepetitionCounter = 9;//重复(9+1)个周期,发生1次中断//HRTIM定时器B重复周期值配置:HRTIM_MREP寄存器bit7:0(MREP[7:0]),MREP[7:0]=0x00//HRTIM定时器B重复周期值配置:HRTIM_REPxR寄存器bit7:0(MREP[7:0]),MREP[7:0]=0x00HAL_HRTIM_TimeBaseConfig(&HRTIM1_structure, HRTIM_TIMERINDEX_TIMER_B, &pTimeBaseCfg);//初始化HRTIM定时器B__HAL_HRTIM_TIMER_ENABLE_IT(&HRTIM1_structure,HRTIM_TIMERINDEX_TIMER_B,HRTIM_TIM_IT_REP);//使能“定时器B”重复中断HAL_NVIC_SetPriority(HRTIM1_TIMB_IRQn,2,0);//“定时器B”抢占优先级为3,响应优先级为0//设置NVIC中断分组4:4位抢占优先级,0位响应优先级//选择中断优先级组4,即抢占优先级为4位,取值为0~15,响应优先级组为0位,取值为0HAL_NVIC_EnableIRQ(HRTIM1_TIMB_IRQn);      //使能“定时器B”中断HAL_HRTIM_SimpleBaseStart_IT(&HRTIM1_structure,HRTIM_TIMERINDEX_TIMER_B);//启动主定时器HRTIM_B_cnt=0;}//函数功能:HRTIM的主定时器50us中断一次
void HRTIM1_Master_IRQHandler(void)
{if((HRTIM1->sMasterRegs.MDIER & HRTIM_MASTER_IT_MREP) == HRTIM_MASTER_IT_MREP){//Timer repetition interrupt enableHRTIM1->sMasterRegs.MICR = HRTIM_MASTER_IT_MREP;//HRTIM_TIMxICR为TIMx中断清除寄存器//这里是将“定时器A”的HRTIM_TIMAICR的bit4(REPC),令REPC=1,清除重复中断标志位HRTIM_MASTER_cnt++;if(HRTIM_MASTER_cnt>20)//t=20*50us=1ms{HRTIM_MASTER_cnt=0;LED1_Toggle(); //LED1引脚输出电平翻转}}
}//函数功能:HRTIM的定时器A为100us中断一次
void HRTIM1_TIMA_IRQHandler(void)
{if((HRTIM1->sTimerxRegs[HRTIM_TIMERINDEX_TIMER_A].TIMxDIER & HRTIM_TIM_IT_REP) == HRTIM_TIM_IT_REP){//Timer repetition interrupt enableHRTIM1->sTimerxRegs[HRTIM_TIMERINDEX_TIMER_A].TIMxICR = HRTIM_TIM_IT_REP;//HRTIM_TIMxICR为TIMx中断清除寄存器//这里是将“定时器A”的HRTIM_TIMAICR的bit4(REPC),令REPC=1,清除重复中断标志位HRTIM_A_cnt++;if(HRTIM_A_cnt>20)//t=20*100us=2ms{HRTIM_A_cnt=0;LED2_Toggle(); //LED2引脚输出电平翻转}}
}//函数功能:HRTIM的定时器B为20us中断一次
void HRTIM1_TIMB_IRQHandler(void)
{if((HRTIM1->sTimerxRegs[HRTIM_TIMERINDEX_TIMER_B].TIMxDIER & HRTIM_TIM_IT_REP) == HRTIM_TIM_IT_REP){//Timer repetition interrupt enableHRTIM1->sTimerxRegs[HRTIM_TIMERINDEX_TIMER_B].TIMxICR = HRTIM_TIM_IT_REP;//HRTIM_TIMxICR为TIMx中断清除寄存器//这里是将“定时器B”的HRTIM_TIMAICR的bit4(REPC),令REPC=1,清除重复中断标志位HRTIM_B_cnt++;if(HRTIM_B_cnt>20)//t=20*20us=0.4ms{HRTIM_B_cnt=0;LED3_Toggle(); //LED3引脚输出电平翻转}}
}

2)、HRTIM.h如下:

#ifndef __HRTIM_H__
#define __HRTIM_H__#include "stm32g4xx_hal.h"
//#include "main.h"#define HRTIM_INPUT_CLOCK   170000000  //HRTIM的输入时钟频率为170MHz#define TIM_MASTER_FREQ     200000     //HRTIM主定时器中断频率为200KHz,周期为5us
#define MASTER_PERIOD ((uint16_t)(((uint64_t)HRTIM_INPUT_CLOCK * 32) / TIM_MASTER_FREQ))
//HRTIM主定时器周期:170000000*32/200000=27200,配置HRTIM主定时器中断频率为200KHz
//HRTIM主定时器计数器输入时钟频率:170000000*32=5440000000Hz=5.440GHz
//HRTIM主定时器计数器输入时钟周期:1/(170000000*32)=0.1838235294117647纳秒=183.8235294117647皮秒#define TIM_A_FREQ     100000     //HRTIM定时器A中断频率为100KHz,周期为10us
#define TIM_A_PERIOD ((uint16_t)(((uint64_t)HRTIM_INPUT_CLOCK * 32) / TIM_A_FREQ))
//HRTIM主定时器周期:170000000*32/200000=54400,配置HRTIM主定时器中断频率为100KHz#define TIM_B_FREQ     500000     //HRTIM定时器B中断频率为500KHz,周期为2us
#define TIM_B_PERIOD ((uint16_t)(((uint64_t)HRTIM_INPUT_CLOCK * 32) / TIM_B_FREQ))
//HRTIM主定时器周期:170000000*32/500000=1088,配置HRTIM主定时器中断频率为100KHzextern void HRTIM_Init(void);#endif /* __HRTIM_H */

3)、LED.c如下

#include "LED.h"void LED_Init(void);//函数功能:配置PC13为输出,无上拉或下拉,输出速度为5MHz
void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOC_CLK_ENABLE();                   //GPIOC时钟使能GPIO_InitStruct.Pin = GPIO_PIN_13;              //选择引脚号码GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;     //推挽输出模式GPIO_InitStruct.Pull = GPIO_NOPULL;             //引脚上拉和下拉都没有被激活
//	GPIO_InitStruct.Pull = GPIO_PULLUP;           //设置上拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;    //引脚的输出速度为5MHzHAL_GPIO_Init(GPIOC, &GPIO_InitStruct);//根据GPIO_InitStruct结构变量指定的参数初始化GPIOC的外设寄存器LED1_Off();__HAL_RCC_GPIOB_CLK_ENABLE(); //使能PB端口的时钟GPIO_InitStruct.Pin = GPIO_PIN_15;              //选择引脚号码GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;     //推挽输出模式GPIO_InitStruct.Pull = GPIO_PULLUP;             //设置上拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;    //引脚的输出速度为5MHzHAL_GPIO_Init(GPIOB, &GPIO_InitStruct);LED2_Off();__HAL_RCC_GPIOA_CLK_ENABLE(); //使能PA端口的时钟GPIO_InitStruct.Pin = GPIO_PIN_0;              //选择引脚号码GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;     //推挽输出模式GPIO_InitStruct.Pull = GPIO_PULLUP;             //设置上拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;    //引脚的输出速度为5MHzHAL_GPIO_Init(GPIOA, &GPIO_InitStruct);LED3_Off();
}

4)、LED.h如下

#ifndef __LED_H__
#define __LED_H__#include "stm32g4xx_hal.h"#define LED1_On()      HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET)  //输出低电平开灯
#define LED1_Off()     HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET)    //输出高电平关灯
#define LED1_Toggle()  HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13)                //LED1引脚输出电平翻转#define LED2_On()      HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET)  //输出低电平开灯
#define LED2_Off()     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET)    //输出高电平关灯
#define LED2_Toggle()  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15)                //LED2引脚输出电平翻转#define LED3_On()      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET)  //输出低电平开灯
#define LED3_Off()     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET)    //输出高电平关灯
#define LED3_Toggle()  HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0)                //LED3引脚输出电平翻转
extern void LED_Init(void);#endif /*__ GPIO_H__ */

3、测试结果

经过测试, 发现主定时器,定时器A和定时器B,在用作时基定时器时,它们是独立工作的,由此可知,定时器C,定时器D,定时器E和定时器F也是可以独立工作的。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • R语言统计分析——回归分析的改进措施
  • 【机器学习】YOLO 关闭控制台推理日志
  • 2024前端面试题-js篇
  • ffmpeg6.1集成Plus-OpenGL-Patch滤镜
  • Java二十三种设计模式-解释器模式(23/23)
  • web开发html前端使用javascript脚本库JsBarcode生成条形码(条码)
  • Vue的生命周期了解
  • 数学基础 -- 线性代数之行列式不变性推导
  • linux文本分析工具grep、sed和awk打印输出文本的单双奇偶行(grep也可以打印奇偶行)以及熟悉的ssh命令却有你不知道的一些用法
  • 记录一下在IIS上部署服务器上遇到的一系列问题及解决方案
  • 创建github个人站点
  • CF 965 C. Perform Operations to Maximize Score
  • 深度学习从入门到精通——大模型认知理解
  • vue.js的设计与实现(响应系统1)
  • 【嵌入式】总结指南——Linux下的裸机驱动开发
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • python3 使用 asyncio 代替线程
  • React as a UI Runtime(五、列表)
  • 给github项目添加CI badge
  • 删除表内多余的重复数据
  • 什么是Javascript函数节流?
  • 手写双向链表LinkedList的几个常用功能
  • 我建了一个叫Hello World的项目
  • 学习笔记TF060:图像语音结合,看图说话
  • 以太坊客户端Geth命令参数详解
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​MySQL主从复制一致性检测
  • #、%和$符号在OGNL表达式中经常出现
  • $(selector).each()和$.each()的区别
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (1)STL算法之遍历容器
  • (1)svelte 教程:hello world
  • (2)(2.10) LTM telemetry
  • (PADS学习)第二章:原理图绘制 第一部分
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (面试必看!)锁策略
  • (七)理解angular中的module和injector,即依赖注入
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (算法)Travel Information Center
  • (一)Neo4j下载安装以及初次使用
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (原創) 物件導向與老子思想 (OO)
  • (转)菜鸟学数据库(三)——存储过程
  • (转)项目管理杂谈-我所期望的新人
  • (自用)交互协议设计——protobuf序列化
  • .env.development、.env.production、.env.staging
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • @GetMapping和@RequestMapping的区别