STM32F407ZG TIM通用定时器

STM32F407ZG开发板学习(6)

  • 通用定时器简介
    • TIM2~TIM5
    • TIM9~TIM14
  • 原理
    • TIMx控制寄存器1(TIMx_CR1)
    • DMA/中断使能寄存器(TIMx_DIER)
    • 预分频寄存器(TIMx_PSC)
    • 计数器(TIMx_CNT)
    • 自动重载寄存器(TIMx_ARR)
    • 状态寄存器(TIMx_SR)
  • 实验
    • 配置步骤
    • 代码

通用定时器简介

STM32F4的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5、 TIM9~TIM14 等通用定时器,还有 TIME6 和 TIME7 等基本定时器 ,总共达 14 个定时器之多 。

通用定时器包含一个 16 位或 32 位自动重载计数器,该计数器由可编程预分频器驱动。
它们可用于多种用途,包括测量输入信号的脉冲宽度(输入捕获)或生成输出波形(输出比较和 PWM)。
使用定时器预分频器和 RCC 时钟控制器预分频器,可将脉冲宽度和波形周期从几微秒调制到几毫秒。
这些定时器彼此完全独立,不共享任何资源。

注:
32 位外设寄存器必须按字(32 位)写入数据。所有其它外设寄存器则必须按半字(16 位) 或字(32 位)写入数据。而读访问可支持字节(8 位)、半字(16 位)或字(32 位)。

TIM2~TIM5

具体功能使用时查看官方手册。
STM32F407ZG TIM通用定时器_第1张图片

TIM9~TIM14

STM32F407ZG TIM通用定时器_第2张图片
STM32F407ZG TIM通用定时器_第3张图片

原理

这里只贴出了一些常用的和此次实验需要用到的位。

TIMx控制寄存器1(TIMx_CR1)

计数器使能。STM32F407ZG TIM通用定时器_第4张图片

DMA/中断使能寄存器(TIMx_DIER)

更新中断使能。STM32F407ZG TIM通用定时器_第5张图片

预分频寄存器(TIMx_PSC)

存放预分频值,16位。STM32F407ZG TIM通用定时器_第6张图片

计数器(TIMx_CNT)

存放计数器值。

自动重载寄存器(TIMx_ARR)

自动重装载值。当计数器值达到设定情况时,将会重装载的值。
STM32F407ZG TIM通用定时器_第7张图片该寄存器在物理上实际对应着2个寄存器。一个是程序员可以直接操作的,另外一个是程序员看不到的,这个看不到的寄存器在《中文参考手册》里面被叫做影子寄存器。事实上真正起作用的是影子寄存器。根据TIMx_CR1TIMx_CR1寄存器中APRE位的设置:APRE=0时,预装载寄存器的内容可以随时传送到影子寄存器,此时2者是连通的;而APRE=1时,在每一次更新事件(UEV)时,才把预装载寄存器(ARR)的内容传送到影子寄存器。

状态寄存器(TIMx_SR)

硬件置1,软件清0!(实际上很多中断的处理都是硬件产生中断置1,在中断函数中由软件来清0)
STM32F407ZG TIM通用定时器_第8张图片

实验

配置TIM3,主循环中使LED0闪烁,定时器中断函数中更改LED1的引脚值,则定时器每计数到指定值产生中断,LED1就会闪烁,而LED0的闪烁用于判断主循环工作状况。

配置步骤

  1. 时钟使能。
  2. TIM初始化,用结构体TIM_TimeBaseInitTypeDef。
  3. 设置DIER使能中断void TIM_ITConfig(TIMx, TIM_IT, ENABLE/DISABLE);。
  4. 设置中断NVIC_Init。
  5. 使能TIM3,void TIM_Cmd(TIMx, ENABLE/DISABLE);。
  6. 实例中断服务函数。

代码

配置函数:

void tim3_init(uint16_t arr, uint16_t psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3时钟
    
    //定时器溢出时间计算方法 :Tout =((arr+1)*(psc+1))/Ft,Ft为定时器工作频率
    TIM_TimeBaseInitSructure.TIM_ClockDivision = TIM_CKD_DIV1; //分频因子
    TIM_TimeBaseInitSructure.TIM_CounterMode = TIM_CounterMode_Up; //计数模式 向上计数模式
    TIM_TimeBaseInitSructure.TIM_Period = arr; //周期,即自动重装值
    TIM_TimeBaseInitSructure.TIM_Prescaler = psc; //时钟分频数
    //TIM_TimeBaseInitSructure.TIM_RepetitionCounter = ; //高级定时器用
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitSructure);
    
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能中断,即设置DIER寄存器,此处为 更新(溢出)中断源
    
    TIM_Cmd(TIM3, ENABLE); //使能TIM3
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断函数
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
    NVIC_Init(&NVIC_InitStructure);
    
}

中断函数:

void TIM3_IRQHandler(void)
{
    
    if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //判断发生中断
    {
        if(get_LED1())
        {
            LED1_ON();
        }
        else {
            LED1_OFF();
        }
        
    }
    
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除更新中断标志位
}

main函数:

int main()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置系统中断优先级分组2
    LED_init();
    delay_init(168);
    tim3_init(2500 - 1, 8400 - 1); //定时器时钟84M,分频系数8400,所以84M/8400=10Khz
                                   //的计数频率,计数5000次为500ms
    while(1)
    {
        if(get_LED0())
        {
            LED0_ON();
        }
        else {
            LED0_OFF();
        }
        delay_ms(200);
    }
}

你可能感兴趣的:(STM32学习,stm32,单片机,arm)