首页 > 其他分享 >定时器

定时器

时间:2023-08-22 21:24:45浏览次数:37  
标签:TIM2 TimeBaseInitStructure 定时器 NVIC TIM InitStructure

 

 

基本定时器,只能使用内部时钟

 时基单元包括:PSC预分频器、CNT计数器、自动重装寄存器

 当PSC=0时不分频,还是72MHz; 当PSC=1时就是2分频,等于72/2=36MHz     16位

 CNT计数器对分频后的脉冲计数,通过上升沿+1     16位, // 当值增加到65535后再增加就清零,触发中断,运行定时任务?

自动重装寄存器,写入需要计数的目标,达到这个计数就产生一个中断,并且清零计数器 。这个中断叫  “更新中断”,通往配置好的NVIC的定时器通道.同时还有产生的U“更新事件”,不能被CPU执行,可以被其他外设执行。

void Timer_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    TIM_InternalClockConfig(TIM2);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//输入滤波ETRP那里使用,内部时钟分频多少
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
    TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;   //ARR自动重装器的值?
    TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;  //PSC  预分频器的值
    //目标频率=CK_PSC/(psc+1)/(ARR+1)   这里定时1S
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;  //重复计数器的值 (高级定时器才有,不用的话给0)
    //这里没有计数器的值,后期可以使用SetCounter和GetCounter函数来操作
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
    
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);  //??  用来避免初始化完就立刻进中断,
    //因为写的预分频器的值只有在更新事件时起作用,为了立刻起作用,就手动生成一个事件
    //同时更新事件和更新中断同时发生,当上电后自动触发一次中断,所以计数会直接从1开始
    //这里手动把中断标志位清除一下,避免刚初始化完就进中断的问题
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使用更新中断   开始到NVIC的通路
    
    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);
}
View Code
void TIM2_IRQHandler(void)  //中断函数可以放在任何地方
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
        Num ++;
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}
View Code

定时器主模式

用DAC输出一段波形,每隔一段时间来触发一次DAC。让它输出下一个电压点:

就是先设置一个定时器产生中断,然后就可以每隔一段时间在中断程序中调用代码手动触发一次DAC转换。然后DAC输出(缺点:主程序频繁被中断)

使用定时器主模式可以(硬件自动化DAC),节省CPU资源

 

通用定时器

 包含基本定时器所有功能

有向上计数,向下计数,中央对齐三种计数模式

输入捕获

输出比较功能

 

 

 

外部时钟

外部触发输入ETR

 作为外部时钟使用的时候走上面ETRF那条路线的叫:外部时钟模式2  ; 走中间TRGI路线的叫:外部时钟模式1

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);
    //外部时钟配置  (TIM2,不需要分频,正向【高电平上升沿有效】,滤波参数【多少频率下几个点一样】)
    TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 10-1;  //计次10次触发 +1
    TIM_TimeBaseInitStructure.TIM_Prescaler = 0x01;  //OLED屏幕熄灭??
    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);
}
View Code

为什么TIM2  ETR的外部中断要接PA0呢?因为引脚物理固定

 

TRGI  触发输入,主要触发定时的从模式

对于时钟输入而言,ETR红色线也可以走绿色线路,只不过会占用通道

 ITR0-3紫色线路信号来自其他4个定时器

 ITR0-3 来自其他定时器的信号 (可以接受其他定时器的TRGO信号)

 具体怎么连接(绿色主,红色从)

 解读:TIM2的ITR0连接在TIM1的TRGO上

 PWM相关 

高级定时器

 增加了这个,可以实现每隔几个周期再触发比如之前的59S可以再*65536

 

计数器预装时序

ARPE=1时,当设定的计数值改变,等本次周期运行完后,下一轮使用新值(使值的变化与更新事件同步发生)

ARPE=0时,当设定的计数值改变,本次周期直接使用新值,到新值则更新(两者不同步)

RCC时钟树讲解42分

 

先启动内部8M RC时钟,再启动外部8M石英时钟,通过PLL锁相环倍频到72M,稳定后作为系统时钟

CSS可以检测外部时钟是否失效

 

标签:TIM2,TimeBaseInitStructure,定时器,NVIC,TIM,InitStructure
From: https://www.cnblogs.com/liujinmeng/p/17636068.html

相关文章

  • 10 JavaScrit定时器
    10JavaScrit定时器在JS中,有两种设置定时器的方案://语法规则t=setTimeout(函数,时间) //经过xxx时间后,执行xxx函数//5秒后打印我爱你t=setTimeout(function(){console.log("我爱你")},5);window.clearTimeout(t)//停止一个定时器//语法规则t=se......
  • 立式门禁软件定时器问题
    论坛文章:文章1文章2注意:rttgpio驱动有问题,使用时注意啦......
  • CH32V003的系统定时器SysTick
    在CH32V003内部有一个特殊的定时器——系统定时器(SysTick),它位于青稞V2微处理内核里面,是RISC-V内核的一个组成部分,主要用来给操作系统提供时间片轮转的定时,一般固定为10ms的定时,所以中文也称它为“嘀嗒”定时器(也称“心跳”定时器)。在不跑操作系统时,可以把它当作普通定时器来使用,一......
  • Linux之定时器
    Linux下的实现方式socket选项SO_RECVTIMEO和SO_SNDTIMEOSIGALRM信号信号相关笔记:Linux之信号I/O复用系统调用的超时参数定时器及其容器定时器封装了以下内容超时时间回调函数:就是每次时间到了要干嘛连接资源:包括客户端socket地址、socket文件描述符、定......
  • 高级定时器寄存器
    TIMx_CR1TIM1&TIM8controlregister1TIM1和TIM8控制寄存器1TIMx_CR2TIM1&TIM8controlregister2TIM1和TIM8控制寄存器2TIMx_SMCRTIM1&TIM8slavemodecontrolregisterTIM1和TIM8从模式控制寄存器TIMx_DIERTIM1&TIM8DMA/interruptenablereg......
  • 高级定时器 捕获比较通道
    捕获比较输入阶段TIMx_CH1通道输入阶段详细 输入阶段滤波器采样频率  CKD[1:0]滤波器边沿检测器,检测上升沿和下降沿TI1F_ED双边沿信号选择上升沿或下降沿来自CH2的信号信号选择分频通道使能信号进入主电路捕......
  • Advanced-control timer 高级定时器 时钟源
    Advanced-controltimer TIM1TIM8TIM8isnotavailableinSTM32F411xC/E.Clockselection时钟选择Internalclock(CK_INT)内部时钟(CK_INT),来自APB总线Externalclockmode1:externalinputpin外部时钟模式1:外部输入引脚来自CH1,CH2ED:双边沿检测(e......
  • 定时器之PWM
      voidPWM_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,......
  • 单片机原理2:定时器和中断
    定时器定时器寄存器:TMOD:方式寄存器,设定定时器0和定时器1的工作方式C/T:0为定时,1为计数TCON:控制寄存器,可位寻址TCON:TF1|TR1|TF0|TR0|IE1|IT1|IE0|IT0前面四位用于定时/计数,后面四位用于控制外部中断两个模式:定时和计数模式中断:主程序因为随机事件发生,暂停现行程序的运行,......
  • prometheus的sdk client_golang 使用 定时器
    之前线上监控的agent都是直接  time.Sleep(time.Duration(collectInterval)*time.Second),多少有些许的low,每次开始采集数据的时间都是从程序开始执行就开始采集,很显然这种偷懒的方式是不合理的。1、简单复制粘贴一下funcAbNormalLoglistener(collectIntervalint){......