定时器

发布时间 2023-08-22 21:15:36作者: 磕伴

 

 

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

 时基单元包括: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可以检测外部时钟是否失效