微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > NEC V850 之 定时器TAB (计数溢出功能)

NEC V850 之 定时器TAB (计数溢出功能)

时间:12-03 来源:互联网 点击:
前说过了比较简单的TMM0 ,只有一个溢出功能,简单实用,今天把TAB的溢出功能说明一下。TAB是一个比较高级的定时器,有输入捕获和输出比较,他的比较溢出功能也比较有特点,这次Kiwi项目就是用了这个特点才完成了间隔发送CAN信息的功能。首先TAB是能够自动重装的,另外它有2个定时器单元TAB0和TAB1,每个定时器单元有4个中断源。

定时器的使用还是蛮简答的,首先初始化定时器,然后把定时器的使能端和屏蔽位全部都打开,就可以使用了,因为其是自动重装定时器,在中断服务函数里面也不需要进行数值的重装。

定时的初始化有如下步骤:(以TAB0为例,TAB1同TAB0)

  1. 关闭定时器所有功能的使能位以及清零相应的中断标志位,这些寄存器还是在中断里使用xxMKn及xxIFn;
  2. 设置4个中断源的中断优先级,操作对应的寄存器xxICn;
  3. 设置中断的时钟,4个中断源共用一个时钟源,所以这个只需要设置一次,其相关寄存器为TABnCTLx;
  4. 设置4个定时器中断的计数时间,其相关寄存器为TABnCCRx。

通过上面4步定时器就初始化好了,下面是初始化代码:

代码源自 Timer_TAB.c

void TAB0_Init(void)
{
TAB0CE = 0; /* TAB0 operation disable */
TAB0CCMK0 = 1; /* INTTAB0CC0 interrupt disable */
TAB0CCIF0 = 0; /* clear INTTAB0CC0 interrupt flag */
TAB0CCMK1 = 1; /* INTTAB0CC1 interrupt disable */
TAB0CCIF1 = 0; /* clear INTTAB0CC1 interrupt flag */
TAB0CCMK2 = 1; /* INTTAB0CC2 interrupt disable */
TAB0CCIF2 = 0; /* clear INTTAB0CC2 interrupt flag */
TAB0CCMK3 = 1; /* INTTAB0CC3 interrupt disable */
TAB0CCIF3 = 0; /* clear INTTAB0CC3 interrupt flag */
TAB0OVMK = 1; /* INTTAB0OV interrupt disable */
TAB0OVIF = 0; /* clear INTTAB0OV interrupt flag */

/* Set INTTAB0CC0 level 2 priority */
TAB0CCIC0 &= 0xF8;
TAB0CCIC0 |= 0x02;
/* Set INTTAB0CC1 level 2 priority */
TAB0CCIC1 &= 0xF8;
TAB0CCIC1 |= 0x02;
/* Set INTTAB0CC2 level 2 priority */
TAB0CCIC2 &= 0xF8;
TAB0CCIC2 |= 0x02;
/* Set INTTAB0CC3 level 2 priority */
TAB0CCIC3 &= 0xF8;
TAB0CCIC3 |= 0x02;

/* Interval timer mode setting */
TAB0CTL0 = TAB_INTERNAL_CLOCK6;
TAB0CTL1 = TAB_INTERNAL_CLOCK | TAB_MODE_INTERVAL;
TAB0CCR0 = TAB0_CCR0_VALUE;
TAB0CCR1 = TAB0_CCR1_VALUE;
TAB0CCR2 = TAB0_CCR2_VALUE;
TAB0CCR3 = TAB0_CCR3_VALUE;
}

初始化完定时器后,我们把我们用到的中断源给打开就好了,这里只使用了4个溢出中断源,下面是代码:

代码源自 Timer_TAB.c

void TAB0_Start(void)
{
TAB0CCIF0 = 0; /* clear INTTAB0CC0 interrupt flag */
TAB0CCMK0 = 0; /* INTTAB0CC0 interrupt enable */
TAB0CCIF1 = 0; /* clear INTTAB0CC1 interrupt flag */
TAB0CCMK1 = 0; /* INTTAB0CC1 interrupt enable */
TAB0CCIF2 = 0; /* clear INTTAB0CC2 interrupt flag */
TAB0CCMK2 = 0; /* INTTAB0CC2 interrupt enable */
TAB0CCIF3 = 0; /* clear INTTAB0CC3 interrupt flag */
TAB0CCMK3 = 0; /* INTTAB0CC3 interrupt enable */
TAB0CE = 1; /* TAB0 operation enable */
}

这两步操作完成后,定时器就在计数了,然后在各自计数值到后,就会进入相应的中断向量,下面是中断向量的代码,也看下:

代码源自:Timer_TAB.c

#pragma vector = INTTAB0CC0_vector
__interrupt void MD_INTTAB0CC0(void)
{/*中断向量0 服务函数*/}
#pragma vector = INTTAB0CC1_vector
__interrupt void MD_INTTAB0CC1(void)
{/*中断向量1 服务函数*/}
#pragma vector = INTTAB0CC2_vector
__interrupt void MD_INTTAB0CC2(void)
{/*中断向量2 服务函数*/}
#pragma vector = INTTAB0CC3_vector
__interrupt void MD_INTTAB0CC3(void)
{/*中断向量3 服务函数*/}

由代码可见,上面的中断向量0~3就是我们之前说的一个定时器内有4个中断向量分别为CC0,CC1,CC2,CC3。但是这4个中断向量的关系是比较奇特的。虽然它有4个中断源,但是只有CC0这个中断来的时候定时计数器才会置零重新计数,CC1~CC3中断都是过程中断,所以CC0~CC3的定时间隔都是一样的,比如100ms来一次中断,CC0~CC3都是每隔100ms中断一次,他们的区别在于可以在这个定时间隔内的不同的时间点进行触发中断,如下图时间轴所示: |________|______________|________________|________________________| 0ms 10ms(CC1) 30ms(CC2) 60ms(CC3) 100ms(CC0)(计数器溢出) 上图显示的CC1,CC2,CC3就是所谓的过            

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top