码迷,mamicode.com
首页 > 其他好文 > 详细

Cortex-m0之DualTimers定时器

时间:2019-07-28 17:13:47      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:init   clock   时钟   时间   cin   png   center   延时   初始   

 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定时器

标签:init   clock   时钟   时间   cin   png   center   延时   初始   

原文地址:https://www.cnblogs.com/Annabelle/p/11253261.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!