您的位置:首页 > 其它

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

2014-07-26 19:09 459 查看
定时器详细讲解【百度文库】点击打开链接
(一) 查询方式和中断方式的区别在于:查询方式不断查询标志位然后进行处理,而中断要编写中断服务子程序来处理中断事件。

(二) 内部中断是指内部定时器、串口、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(); //由于没有使用中断,所以要有语句

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: