PS:以下程序都运行在由EasyARM开发板提供的 ARM Executable Image for lpc2103 模板上。
这几天都在调ARM7TDMI的定时器,把定时器01调好后,发现把寄存器和中断源改成定时器23之后就不能用了。所以我就写了这样的测试程序v1.1:
程序清单 1 V1.1版程序
#include "config.h"
#define LED (1 << 17)
void __irq Timer0ISR (void)
{
if ((IO0PIN & LED) == 0)
{
IO0SET = LED; /* 点亮发光二极管 */
}
else IO0CLR = LED; /* 熄灭发光二极管 */
T0IR = 0x01; /* 清除中断标志 */
VICVectAddr = 0x00; /* 中断向量结束 */
}
void Timer0Init(void)
{
T0TCR = 0x02; /* 定时器0复位 */
T0PR = 0; /* 不设时钟分频 */
T0MCR = 0x03; /* 匹配后复位TC,并产生中断 */
T0MR0 = Fpclk / 2; /* 设置0.5秒匹配值 */
T0IR = 0x01; /* 清除中断标志 */
T0TCR = 0x01;
}
int main (void)
{// add user source code
PINSEL1 = PINSEL1 & 0xFFFFFFF3; /* 选择P0.17 的GPIO功能 */
IO0DIR = LED; /* 设置P0.17 为输出 */
IO0SET = LED; /* 设置输出高电平 */
Timer0Init(); /* 定时器0初始化 */
IRQEnable(); /* IRQ中断使能 */
/* 设置向量中断控制器 */
VICIntSelect = VICIntSelect & (~(1 << 4); /* 定时器0分配为IRQ中断 */
VICVectCntl0 = 0x20 | 4; /* 定时器0分配为向量IRQ 通道0 */
VICVectAddr0 = (uint32) Timer2ISR; /* 分配中断服务程序地址 */
VICIntEnable = 1 << 4; /* 定时器0中断使能 */
while(1);
return 0;
}
测试后,LED能正常闪烁,这个是使用定时器0的匹配0功能来定时器的,但是如果我改成定时器2的时候就不行了。程序如下V1.2:
程序清单:V1.2
#include "config.h"
#define LED (1 << 17)
void __irq Timer2ISR (void)
{
if ((IO0PIN & LED) == 0)
{
IO0SET = LED; /* 点亮发光二极管 */
}
else IO0CLR = LED; /* 熄灭发光二极管 */
T2IR = 0x01; /* 清除中断标志 */
VICVectAddr = 0x00; /* 中断向量结束 */
}
void Timer0Init(void)
{
T2TCR = 0x02; /* 定时器2复位 */
T2PR = 0; /* 不设时钟分频 */
T2MCR = 0x03; /* 匹配后复位TC,并产生中断 */
T2MR0 = Fpclk / 2; /* 设置0.5秒匹配值 */
T2IR = 0x01; /* 清除中断标志 */
T2TCR = 0x01;
}
int main (void)
{// add user source code
PINSEL1 = PINSEL1 & 0xFFFFFFF3; /* 选择P0.17 的GPIO功能 */
IO0DIR = LED; /* 设置P0.17 为输出 */
IO0SET = LED; /* 设置输出高电平 */
Timer2Init(); /* 定时器0初始化 */
IRQEnable(); /* IRQ中断使能 */
/* 设置向量中断控制器 */
VICIntSelect = VICIntSelect & (~(1 << 26); /* 定时器0分配为IRQ中断 */
VICVectCntl0 = 0x20 | 26; /* 定时器0分配为向量IRQ 通道0 */
VICVectAddr0 = (uint32) Timer2ISR; /* 分配中断服务程序地址 */
VICIntEnable = 1 << 26; /* 定时器0中断使能 */
while(1);
return 0;
}
如果使用V1.2的程序,在单步执行的时候可以进中断,在中断中LED也会亮和灭,但是全速执行的时候却不会理想的按所匹配的时间闪烁。而是长亮,并且亮度比原来要暗一点点,这里我初步判断是周期过短,但是1S的周期也不短啊。我把周期加到2S,5S,甚至10S之后还是相同是现象。在请教了其他的同学之后,同学给了我这个程序V1.3:
程序清单:V1.3
#include "config.h"
#define LED (1 << 17)
uint32 Flag; /*定义中断标志位*/
void __irq Timer2ISR (void)
{
Flag = 1;
T2IR = 0x01; /* 清除中断标志 */
VICVectAddr = 0x00; /* 中断向量结束 */
}
void Timer2Init(void)
{
T2TCR = 0x02; /* 定时器2复位 */
T2PR = 0; /* 不设时钟分频 */
T2MCR = 0x03; /* 匹配后复位TC,并产生中断 */
T2MR0 = Fpclk / 2; /* 设置0.5秒匹配值 */
T2IR = 0x01; /* 清除中断标志 */
T2TCR = 0x01;
}
void Delay()
{
uint32 i,j;
for(i=0;i<5000;i++)
for(j=0;j<130;j++);
}
int main (void)
{// add user source code
PINSEL1 = PINSEL1 & 0xFFFFFFF3; /* 选择P0.17 的GPIO功能 */
IO0DIR = LED; /* 设置P0.17 为输出 */
IO0SET = LED; /* 设置输出高电平 */
Timer2Init(); /* 定时器0初始化 */
IRQEnable(); /* IRQ中断使能 */
/* 设置向量中断控制器 */
VICIntSelect = VICIntSelect & (~(1 << 26)); /* 定时器0分配为IRQ中断 */
VICVectCntl0 = 0x20 | 26; /* 定时器0分配为向量IRQ 通道0 */
VICVectAddr0 = (uint32) Timer2ISR; /* 分配中断服务程序地址 */
VICIntEnable = 1 << 26; /* 定时器0中断使能 */
while(1)
{
if(Flag)
{
Flag = 0;
IO0CLR = LED; //点亮LED
Delay();
IO0SET = LED; //熄灭LED
Delay();
}
}
return 0;
}
如果按照这个程序执行的话,LED就能正常的闪烁,恳请高手解释为什么V1.2的程序不行。。。。 |