本帖最后由 hotpower 于 2012-9-22 12:41 编辑
新唐MINI51给我一个印象是各模块的时钟基本上都独立地,比如PWM有PWM时钏,TIMER有TIMER时钟及分频这样各自为政用起来很方便。
MINI51定时器有两个,有以下特点:
每个通道独立的时钟源选择
内部24-bit 上数计数值可以通过TDR (Timer Data Register)寄存器读取
超时周期 = (Period of timer clock input) * (8-bit pre-scale counter + 1) * (24-bit TCMP).
最大超时时间= (1 / 25 MHz) * (2^8) * (2^24 - 1), if TMR_CLK = 25 MHz.
One –Shot 模式
如果定时器操作在one-shot 模式并且CEN (TCSR[30] timer enable bit) 被设为 “1”, 定时器计数器开始上数. 一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 如果IE (TCSR[29] interrupt enable bit) 被设为 “1”, 定时器中断标志将被设并且中断将发生. 如果IE 被设为“0”, 没有中断发生. 这个操作模式下,一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 定时器计数值将返回初始值,CEN被定时器控制器清成“0”. 一旦定时器计数值达到比较寄存器 (TCMPR) 的值,计数将停止. 也就是说, 编程定时器比较寄存器(TCMPR)并使能CEN之后,定时器计数并达到比较寄存器TCMPR的值只一次. 所以,这个操作模式称为 One-Shot 模式.
周期模式
如果定时器操作在周期模式并且CEN 被设成“1”, 定时器计数器开始计数. 一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 如果IE (TCSR[29] interrupt enable bit) 被设为 “1”, 定时器中断标志将被设并且中断将发生. 如果IE 被设为“0”, 没有中断发生. 这个操作模式下,一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 定时器计数值将返回初始值,CEN维持“1” (counting enable continuously)不变. 定时器计数器再次上数. 如果中断标志由软件清除, 一旦定时器计数值达到比较寄存器 (TCMPR) 的值并且 IE 被设为 “1”, 中断标志被设定时器将再次发生中断. 也就是说, 定时器计数并达到比较寄存器TCMPR的值周期性发生. 直到CEN被设为”0”定时器才会停止计数. 中断也会周期性产生.所以这种模式称为周期模式.
Toggle 模式
如果定时器操作在Toggle模式并且CEN 被设成“1”, 定时器计数器开始计数. 一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 如果IE (TCSR[29] 中断使能位) 被设为 “1”, 定时器中断标志将被设并且中断将发生. 相应的切换输出 (tout) 信号被设成 “1”. 这个操作模式下,一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 定时器计数值将返回初始值,CEN维持“1” (counting enable continuously)不变. 定时器计数器再次上数. 如果中断标志由软件清除, 一旦定时器计数值达到比较寄存器 (TCMPR) 的值并且 IE 被设为 “1”, 中断标志被设定时器将再次发生中断. 相应的切换输出 (tout) 信号被设成“0”. 直到CEN被设为”0”定时器才会停止计数. 因而, 切换输出(tout) 信号来回改变,占空比50%.所以这种模式称为Toggle模式.
连续计数模式
如果定时器操作在连续计数模式并且CEN 被设成“1”, 定时器计数器开始计数, 一旦定时器计数值达到比较寄存器 (TCMPR) 的值, 如果IE (TCSR[29] 中断使能位) 被设为 “1”, 定时器中断标志将被设并且中断将发生. 用户可以立即改变TCMPR的值不用关闭定时器计数器再重新计数. 例如,首先 TCMPR 被设成80. (TCMPR 应该小于224 -1 大于 1). 当TDR的值等于80的时候, 如果IE使能,定时器中断标志TIF将被设并且中断将发生. 但是CEN维持“1” (counting enable continuously) 不变并且TDR的值也不会变回0, 而是继续数81, 82, 83,... 直到 224 -1, 0, 1, 2, 3, ...直到 224 -1 一次又一次. 接下来, 如果用户编程TCMPR 为 200 ,TIF被清成 “0”, 当TDR的值等于200的时候, 如果IE使能,定时器中断标志TIF将被设并且中断将再次发生. 最后, 用户又编程TCMPR 等于 500 并再次清除TIF 成“0”, 当TDR的值等于500的时候, 如果IE使能,定时器中断标志TIF将被设并且中断将再次发生. 从应用的角度来看, 中断依靠TCMPR的值产生TCMPR. 这种模式下, 定时器连续计数. 所以这种模式称为连续计数模式.
搞清楚上述概念后编程用库就很方便了,我的编程思想是,定时器每分钟4次中断并立即处理中断,在中断中设一个旗标,通过旗标来点亮和关闭四个LED。
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
#include "includes.h" //包含所需的头文件
int8_t flag;
void TMR0_Callback(void)
{
flag = ~flag;
if(flag)
{
DrvGPIO_SetBit(E_PORT3, 1); //LED0-OFF
DrvGPIO_SetBit(E_PORT3, 6); //LED1-OFF
DrvGPIO_SetBit(E_PORT5, 2); //LED2-OFF
DrvGPIO_SetBit(E_PORT2, 6); //LED3-OFF
}
else
{
DrvGPIO_ClrBit(E_PORT3, 1); //LED0-ON
DrvGPIO_ClrBit(E_PORT3, 6); //LED1-ON
DrvGPIO_ClrBit(E_PORT5, 2); //LED2-ON
DrvGPIO_ClrBit(E_PORT2, 6); //LED3-ON
}
}
/*************************************************************************************
** Function name: main
** Descriptions: GPIOINT
** input parameters: 无
** output parameters: 无
** Returned value: 无
*************************************************************************************/
int main (void)
{
Set_System(); //调用系统初始化函数
DrvTIMER_Init(); //第一次运行定时器都运行一下这个函数
DrvTIMER_Open(E_TMR0, 5, E_PERIODIC_MODE); //每期模式这种模式下连续发生中断
/* 设置计时器零回拨函数, 发生一次中断后执行 */
DrvTIMER_SetTimerEvent(E_TMR0, 1, (TIMER_CALLBACK)TMR0_Callback, 0);
/* 始能计时器零中断 */
DrvTIMER_EnableInt(E_TMR0);
/* 开始记数 */
DrvTIMER_Start(E_TMR0);
while(1); //死循环
}
TIMER.rar
(666 KB)
|