Cortex-M4的基本简介

Posted

tags:

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

参考技术A


ARMCortex™-M4处理器是由ARM专门开发的最新嵌入式处理器,在M3的基础上强化了运算能力,新加了浮点、DSP、并行计算等,用以满足需要有效且易于使用的控制和信号处理功能混合的数字信号控制市场。其高效的信号处理功能与Cortex-M处理器系列的低功耗、低成本和易于使用的优点的组合,旨在满足专门面向电动机控制、汽车、电源管理、嵌入式音频和工业自动化市场的新兴类别的灵活解决方案。

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-M4的基本简介的主要内容,如果未能解决你的问题,请参考以下文章

Cortex-M3&Cortex-M4-技术综述

《基于Cortex-M4的ucOS-III的应用》课程设计 结题报告

Cortex-M3&Cortex-M4-嵌入式软件开发

Arm Cortex-M4 LDRD 指令导致硬故障

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

Cortex-M4 SIMD 比 Scalar 慢