LPC2478(8)定时器

1、开发环境

LPC-2478STK+IAR+JINK

2、特性

  • 32 位的定时器/计数器,带有一个可编程的 32 位预分频器。
  • 计数器或定时器操作。
  • 每个定时器包含多达 4 个 32 位的捕获通道,可以在输入信号变化时捕捉定时器的瞬时值。捕获事件也可以选择产生中断。
  • 4 个 32 位匹配寄存器,允许执行以下操作:
    • 连续工作,在匹配时可选择产生中断
    • 在匹配时停止定时器运行,可选择产生中断
    • 在匹配时复位定时器,可选择产生中断
  • 有多达 4 个外部输出与匹配寄存器相对应,这些输出具有以下功能:
    • - 匹配时设为低电平。
    • - 匹配时设为高电平。
    • - 匹配时翻转。
    • - 匹配时不执行任何操作。

3、相关寄存器

3.1、中断寄存器T[0/1/2/3]IR

中断寄存器包含 4 个位用于匹配中断, 4 个位用于捕获中断。如果有中断产生, IR 中的对应位会置位,否则为 0。向对应的 IR 位写入 1 会复位中断。写入 0 无效。

3.2、定时器控制寄存器T[0/1/2/3]CR

定时器控制寄存器(TCR)用来控制定时器/计数器的操作。

3.3、计数控制寄存器T[0/1/2/3]CTCR

计数控制寄存器(CTCR)用来在定时器模式和计数器模式之间进行选择,在计数器模式中选择计数的管脚和边沿

3.4、匹配寄存器MR0 – MR3

匹配寄存器值连续与定时器计数值相比较。当两个值相等时自动触发相应动作。这些动作包括产生中断,复位定时器计数器或停止定时器。所执行的动作由 MCR 寄存器控制。

3.5、匹配控制寄存器T[0/1/2/3]MCR

匹配控制寄存器用来控制在发生匹配时所执行的操作

3.6、捕获寄存器CR0-CR3

每个捕获寄存器都与一个器件管脚相关联。当管脚发生特定的事件时,可将定时器计数器的值装入该寄存器。捕获控制寄存器的设定决定捕获功能是否被使能以及捕获事件在管脚的上升沿、下降沿还是双边沿发生。

3.7、捕获控制寄存器T[0/1/2/3]CCR

捕获控制寄存器用来控制在捕获事件发生时是否将定时器计数器的值装入其中一个捕获寄存器以及是否产生中断。同时设置上升沿和下降沿位也是有效的配置,这样会在两个边沿都触发捕获事件。在下面的描述中,“n”代表定时器的编号 0 或 1。

3.8、外部匹配寄存器T[0/1/2/3]EMR

外部匹配寄存器提供外部匹配管脚的控制和状态。在下面的描述中,“n”代表定时器编号,值为 0 或 1;“m”代表匹配编号,值为 0~3

3.9、其他寄存器

  • PR->预分频寄存器
  • TC->定时器计数器
  • PC->预分频计数器

4、代码实现

代码功能:实现LED周期性闪烁

#include <nxp/iolpc2478.h>
#include <intrinsics.h>
typedef unsigned char  u8;
typedef unsigned short u16;
typedef unsigned int  u64;
typedef unsigned long  u32;

#ifndef NULL
#define NULL ((void*)0)
#endif
/* P1[13] 低电平导通 */
#define led1            13
/* P1[18] 低电平导通 */
#define led2            18
/* P2[19] 按下低电平,悬空高电平 */
#define but1            19
/* P2[21] 按下低电平,悬空高电平 */
#define but2            21

#define led1_on         (FIO1CLR |= 0x01 << led1)
#define led1_off        (FIO1SET |= 0x01 << led1)
#define led2_on         (FIO1CLR |= 0x01 << led2)
#define led2_off        (FIO1SET |= 0x01 << led2)

void enable_fast_port()
{
  SCS |= 1 << 0;
}
void gpio_init()
{
  PINSEL2 &= ~(0x03 << led1*2);  
  FIO1DIR &= ~(0x01 << led1);  
  FIO1DIR |=   0x01 << led1;   
  led1_off;   
  PINSEL3 &= ~(0x03 << ((led2 % 16)*2));  
  FIO1DIR &= ~(0x01 << led2);  
  FIO1DIR |=   0x01 << led2;   
  led2_off; 
  
  PINSEL5 &= ~(0x03 << ((but1 % 16)*2));  
  PINSEL5 |=   (0x0 << ((but1 % 16)*2));  
  FIO2DIR &= ~(0x01 << but1); 
  
  PINSEL5 &= ~(0x03 << ((but2 % 16)*2));  
  PINSEL5 |=   (0x0 << ((but2 % 16)*2));  
  FIO2DIR &= ~(0x01 << but2); 
}
void led1_reverse(void)
{   
  if ((FIO1SET & (0x01 << led1)) == 0) 
    led1_off;
  else
    led1_on;						
}

void led2_reverse(void)
{   
  if ((FIO1SET & (0x01 << led2)) == 0)
    led2_off;
  else 
    led2_on;
}

__irq __arm void IRQ_Handler (void)
{
void (*interrupt_function)();
unsigned int vector;

  vector = VICADDRESS;     // Get interrupt vector.
  interrupt_function = (void(*)())vector;
  if(interrupt_function != NULL)
  {
    interrupt_function();  // Call vectored interrupt function.
  }
  else
  {
    VICADDRESS = 0;      // Clear interrupt in VIC.
  }
}

void VIC_SetVectoredIRQ(void(*pIRQSub)(), unsigned int Priority,
                        unsigned int VicIntSource)
{
unsigned long volatile *pReg;
  // load base address of vectored address registers
  pReg = &VICVECTADDR0;
  // Set Address of callback function to corresponding Slot
  *(pReg+VicIntSource) = (unsigned long)pIRQSub;
  // load base address of ctrl registers
  pReg = &VICVECTPRIORITY0;
  // Set source channel and enable the slot
  *(pReg+VicIntSource) = Priority;
  // Clear FIQ select bit
  VICINTSELECT &= ~(1<<VicIntSource);
}
/* 正常寄存器写法 */
void timer0_irq(void)
{
  led1_reverse();
  T0IR |= 1;                           
  VICADDRESS = 0; 
}
void timer0_init(void)
{
  PCONP |= 1 << 1;
  T0MR0 = 1000000;/* 1s一次 */		
  T0MCR = 3;    
  T0IR = 1;   		
  VIC_SetVectoredIRQ(timer0_irq,1,VIC_TIMER0);
  VICINTENABLE |= 1 << VIC_TIMER0;				
  T0TCR = 1;    
  __enable_interrupt();	
}
/* lpc2470版的位域写法 */
void timer1_irq(void)
{
  led2_reverse();
  T1IR_bit.MR0INT = 1;
  VICADDRESS = 0;
}
void timer1_init(void)
{
  PCONP_bit.PCTIM1 = 1;
  // Init Time0
  T1TCR_bit.CE = 0;     // counting  disable
  T1TCR_bit.CR = 1;     // set reset
  T1TCR_bit.CR = 0;     // release reset
  T1CTCR_bit.CTM = 0;   // Timer Mode: every rising PCLK edge
  T1MCR_bit.MR0I = 1;   // Enable Interrupt on MR0
  T1MCR_bit.MR0R = 1;   // Enable reset on MR0
  T1MCR_bit.MR0S = 0;   // Disable stop on MR0
  // set timer 0 period
  T1PR = 0;
  T1MR0 = 1000000;
  // init timer 0 interrupt
  T1IR_bit.MR0INT = 1;  // clear pending interrupt
  VIC_SetVectoredIRQ(timer1_irq,1,VIC_TIMER1);
  VICINTENABLE |= 1UL << VIC_TIMER1;
  T1TCR_bit.CE = 1;     // counting Enable
  __enable_interrupt();
}
/* 当多个引脚使用同一个定时器的MAT输出时,频率需要一致,否则不一致的将无效 */
void timer2_mat_init(void)
{
  PINSEL0 &= ~(0x03 << (9*2));  /* p0[9] MAT2[3]*/
  PINSEL0 |= (0x03 << (9*2));  
  PCONP  |= 1 << 22; 
  T2PR    = 0; /* 分频 */
  T2MCR   = 0x03 << 9; /* 并且匹配时产生中断 */
  T2EMR   = 0x03 << 10; /* T2MR3匹配后MAT2.3输出翻转 */
  T2MR3   = 1000000; /* 转输出(注意已经分了频) */
  T2TCR   = 0x03; 
  VICIntSelect  = 0x00; /* 所有的中断连接IRQ中断 */
  VIC_SetVectoredIRQ(timer1_irq,1,VIC_TIMER2);
  VICINTENABLE |= 1UL << VIC_TIMER2; /* 使能定时器 */
  T2TCR   = 0x01;	
}
int main(void)
{
  enable_fast_port();
  gpio_init();
  timer0_init();
  timer1_init();
  while(1)
  { 
    
  }
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值