首页->【玩CortexM0】

273 0

[Nuvoton M0516] 实验五 Timer中断实验

M0516的定时器控制器包括4组32位的定时器——TIMER0~TIMER3。实际上她的定时器是24位+1个8位预分频器。定时器模块可支持例如频率测量,时间延迟,时钟产生,时间计数和间隔测量等功能。本例利用定时器产生定时中断,另外利用定时器控制产生输出一个脉冲信号。本例需要两个独立的定时器,一个为固定定时器,另一个产生一个输出脉冲。

先阅读6.13 定时器控制器(TMR)章的各节。编程需要仔细阅读6.6章节。

理解前边所述,固定时间和输出脉冲属于定时器工作在周期模式,所以比较简单,基本思路就是将时钟分频[可以通过预分频器或直接],经过24位计时器分频得到所需。。

目前的实验都是采用内部时钟:22,118,400=22.1184MHz,比如想得到10ms的周期,那么计数器的预填值就是221184,大约为2exp17~2exp18之间,而后输出一个中断产生一个事件完成所需。这个实验采用Timer0来实现,Timer0初始化函数,这段函数代码加在主函数main的前边:

//Timer0 Initial

void time0Init(void){

  IPRSTC2 |= TMR0_RST;  //ReStore Timer0

  IPRSTC2 &= ~TMR0_RST; //ReStore Timer0

  APBCLK |= TMR0_CLKEN; //Enable Timer0 Systime

  CLKSEL1 = (CLKSEL1 & (~TM0_CLK)) | TM0_22M;//Select Int 22M for Timer0 Clock

  //TCSR0 = TCSR0 & (~TMR_MODE) | MODE_ONE_SHOT;//One's Mode

  TCSR0 = TCSR0 & (~TMR_MODE) | MODE_PERIOD;//Period Mode

  TCSR0 = TCSR0 & 0xFFFFFF00;//No Frequency DIV

  TCMPR0 = 221184;     //Interupt Time=SysClock-Value

  TCSR0 |= TMR_IE;     //Enable Interupt

  NVIC_ISER = TMR0_INT;//Time0 Interupt enabla

  TCSR0 |= CRST;       //Reset Timer0

  TCSR0 |= CEN;        //Start Timer0

}

下边为中断处理函数,加在主函数main的后边即可:

Timer0的时钟计数为221184,1秒钟可以产生100次中断,中断函数为:

//Timer0 Interrupt

void TMR0_IRQHandler(void){

  TISR0 |= TMR_TIF;//Clear Int Flag

  jsq++;

  TCSR0 |= CEN;//Open Timer0

}

需要修改的地方是:将主函数main里加入Timer0初始化一句:

time0Init();

另外将主函数main中的循环语句中的jsq++;注释掉,因为在Timer0的中断处理函数中实现计数器累加的功能。由于Timer0是中断工作方式,因此主函数中没有timer0的其他语句。完成好下载测试结果如图51。51-Timer0中断产生计数值.JPG现实的计数值大约1秒增加100。

接着我们完成用Timer1实现输出脉冲实验。

首先在自定义区增加一个IO定义:

#define plus27  P27_DOUT//Plus output P27

接着在初始化Time0的后边增加初始化Timer1的函数:

//Time1 Predil Counter with Interrupt

void time1Init(void){

  IPRSTC2 |=TMR1_RST; //ReStore Timer1

  IPRSTC2 &=~TMR1_RST;//ReStore Timer1

  APBCLK |=TMR1_CLKEN;//Enable Timer1 Systime

  CLKSEL1=(CLKSEL1 & (~TM1_CLK)) | TM1_22M;//Select Int 22M for Timer1 Clock

  TCSR1 =TCSR1 & (~TMR_MODE) | MODE_PERIOD;//Period Mode

  TCSR1 =TCSR1 & 0xFFFFFF00;//No Frequency DIV

  TCMPR1 =22118;      //Interupt Time=SysClock-Value=1000Hz

  TCSR1 |=TMR_IE;     //Enable Interupt

  NVIC_ISER =TMR1_INT;//Time1 Interupt enabla

  TCSR1 |=CRST;       //Reset Timer1

  TCSR1 |=CEN;        //Start Timer1

}

在主函数main初始化执行增加Timer的初始化:

time1Init();

在主函数main后边增加Timer1中断执行函数:

//TMR1 Interrutp handle

void TMR1_IRQHandler(void){

  TISR1 |= TMR_TIF;//Clear INTflag

  if(plus27) plus27=0;else plus27=1;

  TCSR2 |= CEN;//Open Time2

}

同样,Timer1由中断执行,主循环函数中没有任何语句。结果见图52-硬件连接,52-Timer1中断产生P27输出脉冲.JPG

图53-示波器显示波形,53-示波器测P27输出脉冲~499Hz.JPG499Hz有点误差,需要改变Timer1的计数值校正。


楼主可见