||
LPC含有两个 32 位定时器:定时器 0 和定时器 1,这两个定时器除了外设基地址不同外,其它都相同。定时器/计数器对外设时钟(PCLK)或外部提供的时钟周期进行计数,可选择产生中断或根据 4 个匹配寄存器的设定,在到达指定的定时值时执行其它动作。它还包括 4 个捕获输入,用于在输入信号发生跳变时捕获定时器值,并可选择产生中断。
具有以下特点特性
z 两个 32 位定时器/计数器各含有一个可编程 32 位预分频器;
z 计数器或定时器操作;
z 定时器 0 有3 路、定时器1 有4 路捕获通道。当输入信号跳变时可取得定时器的瞬时值。也可选择使捕获事件产生中断;
z 每个定时器共有 4 个32位匹配寄存器,匹配时的动作有如下 3 种:
匹配时定时器继续工作,可选择产生中断;
匹配时停止定时器,可选择产生中断;
匹配时复位定时器,可选择产生中断。
z 定时器 0 有3 个、定时器1 有4 个对应于匹配寄存器的外部输出,匹配时的输出有如下 4 种:
匹配时设置为低电平;
匹配时设置为高电平;
匹配时翻转;
匹配时无动作。
z 对于每个定时器,多达 4 个匹配寄存器可配置为 PWM,允许使用多达 3 个匹配输出作为单边沿控制的 PWM 输出。
今天的实验内容是使用定时器让蜂鸣器周期性发出声音.主要代码如下:
int main(void)
{
// 初始化IO端口
IO0DIR = BEEP_MASK;
IO0CLR = BEEP_MASK;
//定时器0初始化
T0IR=0xFF; // reset match and capture event interrupts
T0TC=0; // Clear timer counter
T0PR= 0; // No Prescalar
T0MR0=XTALFREQ/100; // Count up to 36,864 for 100Hz interrupt, period = 10ms
T0MCR = 3; // Reset Timer Counter & Interrupt on match
T0TCR = 1; // Counting enable
//初始化中断
VICIntSelect = 0; // Set all VIC interrupts to IRQ for now
VICIntEnClear = 0xFFFFFFFF; // Diasable all interrupts
VICProtection = 0; // VIC registers can be accessed in User or
// privileged mode
VICVectAddr = 0; // Clear interrupt
VICProtection = 0; // Accesss VIC in USR | PROTECT
VICIntSelect &= ~(1<<VIC_TIMER0); // Timer 0 intrpt is an IRQ (VIC_TIMER0 = 4)
VICVectAddr0 = (unsigned int)&MM_TIMER0_ISR; // Install ISR in VIC addr slot 0
VICVectCntl0 = 0x20 | VIC_TIMER0; // IRQ type, TIMER 0 int enabled
VICIntEnable |= (1<<VIC_TIMER0); // Turn on Timer0 Interrupt
__enable_interrupt(); // Global interrupt enable
while(TRUE)
{}
}
/******************************************************************************
* 函数名称: irq_handler
* 入口参数: void
* 返回参数: void
*
* 描述: IRQ exception handler, this will call appropriate isr after
* reading value out of VICVectAddr
* 注意: This is ARM mode code - full 32 bit code
*****************************************************************************/
__irq __arm void irq_handler (void)
{
void (*interrupt_function)();
unsigned int vector;
vector = VICVectAddr; // Get interrupt vector.
interrupt_function = (void(*)())vector; // Call MM_TIMER0_ISR thru pointer
(*interrupt_function)(); // Call vectored interrupt function
VICVectAddr = 0; // Clear interrupt in VIC
}
/*************************************************************************
* 函数名称: fiq_handler
* 入口参数: void
* 返回参数: void
*
* 描述: FIQ subroutine
* 注意: This is ARM mode code - full 32 bit code
*************************************************************************/
__fiq __arm void fiq_handler (void)
{
while(1);
}
//定时器中断服务函数
void MM_TIMER0_ISR()
{
static unsigned int us_Ticks;
us_Ticks++;
if(us_Ticks == TICKS_PER_SECOND)
{
if ((IO0SET & BEEP_MASK) == 0)
IO0SET = BEEP_MASK; //关闭LED
else
IO0CLR = BEEP_MASK;
us_Ticks = 0;
}
T0IR = 1; // Clear timer interrupt
}