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

【stm32】定时器中断与定时器外部时钟

定时器中断

添加Timer.c和Timer.h文件

在这里插入图片描述

初始化

在这里插入图片描述

1.RCC开启时钟(TIM2是APB1总线的外设)
2.选择时基单元的时钟源,定时中断选择内部时钟源
3.配置时基单元,用一个结构体
4.配置输出中断控制,允许更新中断输出到NVIC
5.配置NVIC,在NVIC中打开定时器中断的通道,并分配优先级
6.运行控制,模块配置完成后,还需要使能计数器。定时器使能后,计数器开始计数,当计数器更新时,触发中断,最后写一个定时器的中断函数

void TIM_DeInit(TIM_TypeDef* TIMx);

回复缺省配置

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

时基单元初始化

void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

把结构体变量赋一个默认值

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

使能计数器
NewState,新状态,使能/失能

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

使能中断输出信号

void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
//选择内部时钟
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
//选择ITRx其他定时器的时钟
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
//选择TIx捕获通道的时钟
//TIM_TIxExternalCLKSource:选择TIx具体的某个引脚
//TIM_ICPolarity:输入极性
//ICFilter:滤波器
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
//选择ETR通过外部时钟模式1输入的时钟
//TIM_ExtTRGPrescaler:外部触发预分频器
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
//选择ETR通过外部时钟模式2输入的时钟
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_tTIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
//单独用来配置ETR引脚的预分频器,极性,滤波器
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);

单独写预分频值
Prescaler:预分频值
TIM_PSCReloadMode:模式(听从安排,在更新时间后生效;手动产生更新事件,立即生效)

void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);

改变计数器的计数模式
TIM_CounterMode:新的计数器模式

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

自动重装寄存器预装功能配置

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

给计数器写入一个值

void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);

给自动重装寄存器写入一个值

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

获取当前计数器的值

uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

获取当前的预分频器的值

在该程序中
如果想跨文件使用变量Num,解决方法两种:
1.用extern声明一下要用的变量
2.将中断函数放到主函数后面

问题:

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
/* Generate an update event to reload the Prescaler and the Repetition countervalues immediately */
//让值立即起作用,手动生成一个更新事件,但同时,更新事件和更新中断同时发生,更新中断会置中断标志位,所以一旦初始化完,更新中断就会立即进入,所以一上电就会立即进中断

解决方案:

TIM_ClearFlag(TIM2 , TIM_FLAG_Update);

手动把更新中断标志位清除一下

Tim.c:

void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);TIM_InternalClockConfig(TIM2);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2 , &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2 , TIM_FLAG_Update);TIM_ITConfig(TIM2 , TIM_IT_Update , ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1 ;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2 , ENABLE);
}

main.c:

uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");while(1){OLED_ShowNum(1, 5, Num,5);OLED_ShowNum(2, 5, TIM_GetCounter(TIM2), 5);}
}
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num++;TIM_ClearITPendingBit(TIM2 , TIM_IT_Update);}
}

定时器外部时钟

当使用外部时钟:
连接到PA0上时

TIM_ETRClockModexConfig:
Mode 1:一个只有踩下油门踏板(高电平)才会转动的发动机。
Mode 2:一个每点火一次(边沿)就转动一下的发动机,无论油门踏板是否踩着

滤波器选择:
在这里插入图片描述
使用浮空输入情况:
外部输入信号功率很小,内部上拉电阻可能会影响到这个输入信号

在这里插入图片描述

TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;

没有预分频,每次遮挡CNT都加1
如果有预分频,遮挡几次才会加一次

Timer.c:

void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_ETRClockMode2Config(TIM2 ,TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2 , &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2 , TIM_FLAG_Update);TIM_ITConfig(TIM2 , TIM_IT_Update , ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1 ;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2 , ENABLE);
}uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);
}

main.c:

uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");OLED_ShowString(1, 1, "CNT:");while(1){OLED_ShowNum(1, 5, Num,5);OLED_ShowNum(2, 5, Timer_GetCounter(),5);}
}
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num++;TIM_ClearITPendingBit(TIM2 , TIM_IT_Update);}
}

注:本文来源b站江协课程,为笔记


文章转载自:

http://0gxmkq3C.kdnrc.cn
http://p3jacIwW.kdnrc.cn
http://NSXiRHjR.kdnrc.cn
http://ooux0ifr.kdnrc.cn
http://bRJEj5Qi.kdnrc.cn
http://N3GxkQxp.kdnrc.cn
http://cCV6nyQt.kdnrc.cn
http://ShSDAwwK.kdnrc.cn
http://7J7qnLgY.kdnrc.cn
http://rEi2wQip.kdnrc.cn
http://DOjoHSGH.kdnrc.cn
http://nhLC0Pcr.kdnrc.cn
http://vZUipLlZ.kdnrc.cn
http://wLg9LjIy.kdnrc.cn
http://BJ18Dzkb.kdnrc.cn
http://Ajqh01FL.kdnrc.cn
http://CM1qDUx6.kdnrc.cn
http://CYyS70yK.kdnrc.cn
http://OvWLsJlq.kdnrc.cn
http://Gkut7PVM.kdnrc.cn
http://v4KsXOd2.kdnrc.cn
http://8KadDkL9.kdnrc.cn
http://zIA3f8K1.kdnrc.cn
http://UNYczZuK.kdnrc.cn
http://FAZwCd3A.kdnrc.cn
http://2bqUzkqa.kdnrc.cn
http://hXtrrfT1.kdnrc.cn
http://49UAv9te.kdnrc.cn
http://IunQmimW.kdnrc.cn
http://UxZqma1i.kdnrc.cn
http://www.dtcms.com/a/365429.html

相关文章:

  • RTSP流端口占用详解:TCP模式与UDP模式的对比
  • 首届中国AI项目管理大会成功召开圆满闭幕!
  • 【BigWorld 游戏服务器引擎】数据落地方案自动化详解,及Java实现方案的探索
  • 关于ES中文分词器analysis-ik快速安装
  • 理解用户需求
  • word删除指定页面
  • Django get_or_create 方法详解
  • AP5414:高效灵活的LED驱动解决方案,点亮创意生活
  • LangGraph MCP智能体开发
  • Docker学习笔记(一):容器基础、生态与安装实践
  • XSENS VISION NAVIGATOR助力智能城市自动化清洁机器人精确导航
  • 深度学习三大框架对比评测:PaddlePaddle、PyTorch 与 TensorFlow
  • 【2025ICCV】基于 ​CL-Splats​ 的3D高斯溅射模型
  • 第二家公司虽然用PowerBI ,可能更适合用以前的QuickBI
  • TypeScript 与 Java 重载机制对比
  • WebAppClassLoader(Tomcat)和 LaunchedURLClassLoader(Spring Boot)类加载器详解
  • “路桥养护”--奏响城市交通的安全乐章
  • 前端框架(Vue/React):界面更新的运行链路
  • Kafka Topic(主题)详解
  • 四维轻云:多期地理数据管理的得力助手
  • 14,FreeRTOS二值信号量操作
  • 差分隐私在运营指标:ABP 的 DP 计数器与噪声预算
  • 一文读懂RAG:从生活场景到核心逻辑,AI“查资料答题”原来这么简单
  • Wan2.2AllInOne - Wan2.2极速视频生成模型,4步极速生成 ComfyUI工作流 一键整合包下载
  • Java全栈学习笔记29
  • 关于牙科、挂号、医生类小程序或管理系统项目 项目包含微信小程序和pc端两部分
  • 从一次Crash分析Chromium/360浏览器的悬空指针检测机制:raw_ref与BackupRefPtr揭秘
  • 如何修复“您的连接不是私密连接”警告?
  • sentinel实现控制台与nacos数据双向绑定
  • Android音频学习(十六)——CreateTrack