Cortex-m0之DualTimers定时器

Posted annabelle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cortex-m0之DualTimers定时器相关的知识,希望对你有一定的参考价值。

 1. DualTimers简介

cortex m0是ARM公司推出的一款小型低功耗处理器,集成了dualtimers双定时器。

dualtimers是挂在APB总线上的从外设,有如下特性:

  • 可配置16位或32位计数器,采用向下计数的方式
  • 支持1/16/256分频
  • 每个定时器有独立的使能信号
  • 三种定时模式:单次计时one-shot,周期计时periodic,自由运行模式free-running
  • 周期装载寄存器period load register和后台装载寄存器background load register

 

2. DualTimers特性

2.1 三种定时模式

dualtimers有三种计时模式,分别是

1. 自由运行模式:从最大值向下计数,每计到0就产生一次中断,不断循环。

2.周期计时模式:从重装载值向下计数,每计到0就产生一次中断,不断循环。重装载值可在定时器初始化时进行配置。如果在counter正常计数时配置重装载值,那么counter会立即从重装载值重新向下计数。

3.单次计时模式:计数器只产生一次中断,计数器向下计到0时就会停止。

 

 

 技术图片

 

 

2.2 16bit或32bit宽度counter计数器

 计数器counter可选16bit宽度或32bit宽度

2.3 定时器分频

 

技术图片

配置寄存器:control register [3:2] TimerPre

定时器支持1分频,16分频和256分频。

 一般微秒、毫秒、秒级的延时,完全可以使用1分频作为分频因子,且更加准确。

由于这里使用的系统时钟是50MHz,希望产生1秒中的时间间隔,只需要将分频模式设为1分频,装载值设为50M即可。

 

2.4 装载值和当前值

定时器采用的是向下计数的方式,因此配置装载值后,计时器从装载值向下计数直至计至0并产生中断。

在周期定时模式下,计至0后会重新从装载值向下计数并循环往复。

对装载寄存器Load Register写值,能够直接将向下计数的counter重设到新装载值(也就是说如果上次计数还没有计到0,这一修改就使得上次计数还没有进入中断就重新计数)。

如果对后台装载寄存器Background Load Register写值,则不会立即修改counter,而是counter向下计数至0后开始下一次计数时,从后台装载寄存器的值开始计时。

 

3. 配置寄存器

DualTimers控制较为简单,寄存器较少。

 TIMER1LOAD    装载寄存器。向这一寄存器写入装载值。

TIMER1VALUE    当前值寄存器,可从这一寄存器将counter当前的值读出来。

TIMER1CONTROL  控制寄存器。用于初始化过程中的定时器配置

TIMER1INTCLR    中断清除寄存器。向这一寄存器写入任何值将清除中断

TIMER1RIS      原始中断寄存器。未经过屏蔽的原始中断

TIMER1MIS      中断状态寄存器。判断中断是否产生

TIMER1BGLOAD    后台装载寄存器。区别于装载寄存器,向这一寄存器写装载值,在counter下次向下计数时进行装载,而不会立即打断本次计数。

 

技术图片

 

 

3.1 控制寄存器

配置三种定时模式的寄存器为控制寄存器control register

技术图片

 

 

Bits  名称 描述
[31:8] - 保留
[7]

Timer Enable

定时器使能

0  失能(缺省)

1  使能

[6]

 Timer Mode

定时器模式

0  free-running自由运行模式(缺省)

1  periodic周期定时模式

[5]

Interrupt Enable

中断使能

0  中断失能

1  中断使能(缺省)

[4]

-

保留

[3:2]

TimerPre

定时器预分频

00  1分频(缺省)

01  16分频

10  256分频

[1]

Timer Size

 

0  16-bit宽度计数器(缺省)

1  32-bit宽度计数器

[0]

 One-shot Count

单次计数模式

0  循环模式(缺省)

1  单次计数模式

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.2 中断相关寄存器

M0的DualTimers在count向下计至0时出发中断。

其中需要在初始化时在控制寄存器中使能中断,产生中断后在中断服务程序中将中断清除,并执行相应操作。

Interrup Clear Register     对其进行写入操作将清除中断。

Raw Interrupt Status Register  原始中断状态寄存器。

Interrupt Status Register     中断状态寄存器。

 

4. DualTimers使用示例

使用过程中,和M3定时器配置大体一致。

在程序运行时首先对其进行初始化配置。

如:将TIM1配置成循环计数,这样每当counter向下计数至0时,就会产生一次中断,并从重装载值继续向下计数,循环往复。

void TIM1_Config( void )

    TIM_InitTypeDef Time_InitStruct;
    
    Time_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//1分频
    Time_InitStruct.TIM_CounterMode = TIM_Mode_Periodic;//周期计数
    Time_InitStruct.TIM_CounterbitWide = TIM_Wide32Bit;//32位宽counter
    Time_InitStruct.TIM_Period = 1000;//重装载值
    TIM_Init(CMSDK_TIMER1,&Time_InitStruct);
    
    TIM_CmdEnable(CMSDK_TIMER1,ENABLE);//使能定时器
    TIM_ITCmdEnable(CMSDK_TIMER1,ENABLE);//TIM中断使能
    
    NVIC_ClearPendingIRQ(DUALTIMER_IRQn);
    NVIC_EnableIRQ(DUALTIMER_IRQn);

 

将TIM0配置成单次计数,可以用于延时函数,如delay_ms()

void TIM0_Config( void )

    TIM_InitTypeDef Time_InitStruct;
    
    Time_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//1分频
    Time_InitStruct.TIM_CounterMode = TIM_Mode_OneShort;//单次计数
    Time_InitStruct.TIM_CounterMode = TIM_Mode_Periodic;
    Time_InitStruct.TIM_CounterbitWide = TIM_Wide32Bit;
    Time_InitStruct.TIM_Period = 1000;//重装载值
    TIM_Init(CMSDK_TIMER0,&Time_InitStruct);
    
    TIM_CmdEnable(CMSDK_TIMER0,ENABLE);//使能定时器
    TIM_ITCmdEnable(CMSDK_TIMER0,ENABLE);//TIM中断使能
    
    NVIC_ClearPendingIRQ(DUALTIMER_IRQn);
    NVIC_EnableIRQ(DUALTIMER_IRQn);

这样接下来就可以在延时函数中使用TIM0,其中TIM0_delayFlag作为完成一次计时的标志。

系统使用了50MHz时钟,当我们需要1ms的延时时,可以通过一分频,配置重装载值为50_000_000/1000-1

void delay_ms(uint32_t nms)

    TIM0_delayFlag = 0;
    TIM_SetLoadValue(CMSDK_TIMER0,nms*50*1000-1);
    while(TIM0_delayFlag != 1);//等待延时结束

 

中断服务函数:

void DUALTIMER_HANDLER(void)

    if((CMSDK_TIMER0->TimerMIS&0x01) == 1)//TIM0中断
    
        TIM0_delayFlag = 1;//用于延时
        TIM_ClearITFlag(CMSDK_TIMER0);
    
    if((CMSDK_TIMER1->TimerMIS&0x01) == 1)//TIM1中断
    
        TIM_ClearITFlag(CMSDK_TIMER1);
    

 

再通过中断使能等操作,定时器就可以正常使用了。

 

以上是关于Cortex-m0之DualTimers定时器的主要内容,如果未能解决你的问题,请参考以下文章

Cortex-M4 上的 Systick 定时器:它的预分频器是啥?

使用系统定时器SysTick实现精确延时微秒和毫秒函数

FreeRTO之Cortex-M中断管理

系统定时器SysTick

Cortex-M3之STM32嵌入式系统设计的内容简介

STM32 系统定时器(SysTick)