ARM学习随笔(12)定时器查询方式和中断方式

来源:互联网 发布:哈鲁留学怎么样 知乎 编辑:程序博客网 时间:2024/06/09 18:40
定时器详细讲解【百度文库】点击打开链接

(一) 查询方式和中断方式的区别在于:查询方式不断查询标志位然后进行处理,而中断要编写中断服务子程序来处理中断事件。

(二) 内部中断是指内部定时器、串口、AD、IIC、SPI等等资源的中断,而外部中断则是外部信号引起的中断,如高电平、低电平、上升沿、下降沿等。

(三)定时器属于内部中断,如果选择中断方式则只要设置VIC即可。

 

ARM7的定时器是采用分频的方式来实现定时的,也就是说在配置定时器之前,一定要弄清楚Fpclk的频率是多少。

(ARM7的时钟概念,Fosc是晶振的频率,Fcclk是PLL输出频率(也就是处理器的时钟频率),Fcclk=M×Fosc,M是PLLCFG寄存器中的MSEL位的倍增器值。PLLCFG的MSEL[0~4].其中Fcclk最大不能超过60MHz)

      定时器操作步骤(相关头文件中宏定义实际硬件电路晶振频率Fosc,处理器时钟频率Fcclk VPB外设时钟频率Fpclk):

1.初始化定时器

①定时器计数器TC清0,由0开始计数,(设置其他值也行)。

②配置计数器的分频值PR  (PR=0表示不分频)  TC每经过PR+1个PCLK的周期[即没经过(PR+1)/Fpclk秒]加1.

③配置匹配控制寄存器MCR

④配置匹配寄存器MR0

⑤配置定时器控制寄存器TCR(使能定时器) 了保证定时器计时的正确性,在启动定时器之前,一定要先复位定时器。一般而言,启动定时器的顺序如下: 
T0TCR = 1<<1;//复位预分频计数器和定时器计数器 T0TCR = 1<<0;//启动定时器

 

2.若采用中断方式,则设置VIC。若采用查询方式,则检测IR中的中断标志,处理过后写1清零。

下图是Fosc  CCLK PCLK之间的关系图。

PLL 输入和设定必须满足下面的条件:
FOSC 的范围:10MHz~25MHz
CCLK 的范围:10MHz~Fmax(微控制器的最大允许频率-由内置的系统微控制器
决定)
FCCO 的范围:156MHz~320MHz

FPCLK:

VPB 总线时钟为处理器时钟的1/4。
VPB 总线时钟与处理器时钟相同。
VPB 总线时钟为处理器时钟的1/2。

因此总是为FCCLK与FPCLK之间设置关系

 

 


 

 

中断方式程序代码:

#include<lpc213x.h>
#define led 1<<18
#define TIME0 4
#define Fosc 11059200ul
#define Fcclk Fosc*4
#define Fpclk (Fcclk/4)*1 //即VPB外设频率域Fosc频率相同,1秒钟计Fpclk个数

void time_init(void)
{
 T0TC=0;//定时器计数器清0,由0开始计数
 T0PR=0;//不分频
 T0MR0=Fpclk; //匹配值设为Fpclk,达到时刚好经过1秒
 T0MCR=0X0003; //MR0与TC值匹配产生中断,且复位(中断方式)
 T0TCR=1<<1;   //先复位
 T0TCR=1<<0;   //后启动
}
void __irq timeintr(void)

{
 unsigned int i;
 i=IO1PIN;   

 T0IR = 0x01;  //清零
 
 if((i&led)==0)
  IO1SET=led;
 else
  IO1CLR=led;
 VICVectAddr=0;//中断结束
}
void intr_init(void)
{
 VICIntSelect=0x00000000;
 VICVectCntl0=0x20|TIME0;
 VICVectAddr0=(unsigned int)timeintr;
 T0IR = 0x01;   //清零中断标志位
 VICIntEnable=1<<TIME0;
  
}
int main (void)
{
  PINSEL2=0X00000000;   //选择GPIO功能
  IO1DIR=led;
  IO1SET=led;
   
  intr_init();
  time_init();

  while(1);  //由于中断结束以后回到原来的地方重新开始计时,然后又会产生中断,所以while语句中没有语句
 
}

 

查询方式代码:

#include<lpc213x.h>
#define led 1<<17
#define TIME0 4
#define Fosc 11059200ul
#define Fcclk Fosc*4
#define Fpclk (Fcclk/4)*1 //即VPB外设频率域Fosc频率相同,1秒钟计Fpclk个数

void time_init(void)
{
 T0TC=0;//定时器计数器清0,由0开始计数
 T0PR=0;//不分频
 T0MR0=Fpclk; //匹配值设为Fpclk,达到时刚好经过1秒
 T0MCR=0X0003; //MR0与TC值匹配产生中断,且复位(中断方式)
 T0TCR=1<<1;   //先复位
 T0TCR=1<<0;   //后启动
}
void display(void)
{
 unsigned int i;
 while ((T0IR & 0x01) == 0); /* 等待定时时间到,一直询问时间是否到*/   区别在这里,一直询问
 T0IR = 0x01;    /* 清除中断标志     */

 i=IO1PIN;
 if((i&led)==0)
  IO1SET=led;
 else
  IO1CLR=led;
 
}

int main (void)
{
  PINSEL2=0X00000000;   //选择GPIO功能
  IO1DIR=led;
  IO1SET=led;
   
  time_init();

  while(1)
  {
   display();  //由于没有使用中断,所以要有语句
  }
 
}

 

 

0 0
原创粉丝点击