原创 LPC2103定时器0定时实验-中断方式

2009-3-15 14:53 5398 5 6 分类: MCU/ 嵌入式

      这两天在学LPC2103的定时器,其中要用到中断这一功能,看了例子后,感觉ARM的中断设置可是真复杂啊,看了两天我才稍微有一点明白。


      lpc2103的向量中断寄存器(VIC)有32个中断请求输入,可将其分为3类:FIQ(快速中断)、向量IRQ和非向量IRQ,其中FIQ优先级最高,向量IRQ次之,


非向量IRQ最低。


      VIC的基本操作方法如下:


       1、设置中断是FIQ还是IRQ,若是IRQ,再设置向量中断,并分配中断优先级。


      2、设置中断允许,以及乡里向量中断对应地址或非向量中断默认地址。


      3、有中断之后,若是IRQ中断,则可读取向量地址寄存器,然后跳转到该地址所在的响应服务代码。


     4、当要推出中断时,对向量地址寄存器写0,通知VIC中断结束。


     上次做的实验是采用查询的方式实现LED闪烁,因为在查询的时候CPU只能做一件事,极大地降低了CPU 的使用效率,所以一般情况下,采用中断方式来实现更经济实惠。


    程序如下:
#include <intrinsics.h>
#include <stdio.h>
#include <iolpc2103.h>


// OSC [Hz]              外部晶振
#define FOSC            11059200UL
// Core clk [Hz]         处理器当前时钟
#define FCCLK           FOSC
// Per clk [Hz]          外部器件时钟,由VPB分频器决定其与FCCLK的关系
#define PCCLK           (FOSC/4)
// Timer tick per second 定时器分频
#define TICK_PER_SEC    (2UL)
#define TIM_PER_S(Val)  (PCCLK/Val)


#define MAX_TICK_PER    TIM_PER_S(20)
#define MIN_TICK_PER    TIM_PER_S(5)


// Timer Delta period [ms]
#define DELTA_PER       (50UL)
#define TIM_DPER        ((PCCLK*DELTA_PER)/1000UL)


#define LED_MASK        1<<18
/*************************************************************************
 * 函数名称:irq_handler
 * 入口参数:无
 *
 * 返回参数:无
 *
 * 描    述:IRQ handler
 *
 *************************************************************************/
#pragma vector="IRQV"         //中断向量地址
__irq __arm void irq_handler (void)
{
void (*interrupt_function)();
unsigned int vector;


  vector = VICVectAddr;     //获得中断向量
  interrupt_function = (void(*)())vector;
  if(interrupt_function != NULL)   //如果不是空函数
  {
    interrupt_function();  //调用中断指向的函数
  }
  else
  {
    VICVectAddr = 0;      //清除在VIC中的中断
  }
}
/*************************************************************************
 * 函数名称: Timer0Handler
 * 入口参数: 无
 *
 * 返回参数: 无
 *
 * 说    明: Timer 0 handler
 *
 *************************************************************************/
void Timer0Handler (void)
{
  // clear interrupt flag            清除中断标志
  T0IR_bit.MR0INT = 1;
  // Change patern
  if ((IOSET & LED_MASK) == 0)
    IOSET = LED_MASK;      //关闭LED
  else
    IOCLR = LED_MASK;
  //pNextPattern = pNextPattern->pNextPattern;        //调整当前的链表
  T0IR=0x02;
  VICVectAddr = 0;
}
/*************************************************************************
 * 函数名称: VicInit 中断初始化子程序
 * 入口参数: 无
 *
 * 返回参数: 无
 *
 * 说    明: Init VIC module
 *
 *************************************************************************/
void VicInit (void)
{
  // 初始化中断选择寄存器,写0是IRQ,写1是FIQ,这里写0,选择IRQ.
  VICIntSelect  =  0;
  // 中断使能清零寄存器,写1清零中断使能寄存器的对应位,并禁止对应的中断请求
  VICIntEnClear = 0xFFFFFFFF;
  // 软件中断清零寄存器,写1清零软件中断寄存器的相应位,并解除强制的中断请求
  VICSoftIntClear = 0xFFFFFFFF;
  // 保护使能寄存器 写0允许在用户和特权模式下都可以访问VIC寄存器,写1只能在用户模式下访问
  VICProtection = 0;
  // 向量地址寄存器 清零
  VICVectAddr = 0;
  // 默认向量地址寄存器 清零
  VICDefVectAddr = 0;
  // Clear address of the Interrupt Service routine (ISR) for vectored IRQs.
  VICVectAddr0  = VICVectAddr1  = VICVectAddr2  = VICVectAddr3  =\
  VICVectAddr4  = VICVectAddr5  = VICVectAddr6  = VICVectAddr7  =\
  VICVectAddr8  = VICVectAddr9  = VICVectAddr10 = VICVectAddr11 =\
  VICVectAddr12 = VICVectAddr13 = VICVectAddr14 = VICVectAddr15 = 0;
  // Disable all vectored IRQ slots
  VICVectCntl0  = VICVectCntl1  = VICVectCntl2  = VICVectCntl3  =\
  VICVectCntl4  = VICVectCntl5  = VICVectCntl6  = VICVectCntl7  =\
  VICVectCntl8  = VICVectCntl9  = VICVectCntl10 = VICVectCntl11 =\
  VICVectCntl12 = VICVectCntl13 = VICVectCntl14 = VICVectCntl15 = 0;
}
/*************************************************************************
 * 函数名称: Init_timer0
 * 入口参数: 无
 *
 * 返回参数: 无
 *
 * 说    明: Init tiner0
 *
 *************************************************************************/
void Init_timer0(void)
{
  // Init timer
  // 定时器中断不允许,并且计数器TC和定时器分频器复位
  T0TCR = 2;
  // 计数控制寄存器,复位清零
  T0CTCR = 0;
  // 分频寄存器不分频
  T0PR  = 0;
  // 匹配寄存器 给定初值
  T0MR0 = PCCLK/TICK_PER_SEC;
  // 匹配控制寄存器 匹配时产生中断并复位
  T0MCR = 3;
  // 没有外部中断
  T0EMR = 0;
  
 
  // 设置为向量IRQ
  VICIntSelect_bit.TIMER0 = 0;
  // 设置为TIMER0中断,使能定时器中断
  VICVectAddr0 = (unsigned int) Timer0Handler;
  VICVectCntl0_bit.NUMBER = VIC_TIMER0;
  VICVectCntl0_bit.ENABLED = 1;
  // Timer 0 interrupt enable
  VICIntEnable_bit.TIMER0 = 1;
  // Enable timer0
  T0TCR = 1;
}
/*************************************************************************
 * 函数名称: Init_Gpio
 * 入口参数: 无
 *
 * 返回参数: 无
 *
 * 说    明: Init GPIO
 *
 *************************************************************************/
void Init_Gpio(void)
{
    // Init GPIO
  PINSEL0 = PINSEL1 = 0;
  // Disable fast IO
  SCS_bit.GPIO0M = 0;
 
  // Set pins connect to LEDs as outputs
  IODIR = LED_MASK;
  // All LEDs off
  IOCLR = LED_MASK;
}
/*************************************************************************
 * 函数名称: Init_pll
 * 入口参数: 无
 *
 * 返回参数: 无
 *
 * 说    明: Init PLL
 *
 *************************************************************************/
void Init_pll(void)
{
  // Disable PLL
  PLLCON = 0;
  // Write Feed
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
  // Set periphery divider /4
  APBDIV_bit.APBDIV  = 0;
  // Set MAM fully enable
  MAMCR_bit.MODECTRL = 0;
  MAMTIM_bit.CYCLES  = 3;
  MAMCR_bit.MODECTRL = 2;
}
/*************************************************************************
 * 函数名称: main
 * 入口参数: 无
 *
 * 返回参数: 无
 *
 * 描    述: main
 *
 *************************************************************************/
void main(void)
{
  Init_pll();
  // Memory map init flash memory is maped on 0 address
#ifdef FLASH
  MEMMAP_bit.MAP = 1;
#else
  MEMMAP_bit.MAP = 2;
#endif
  __disable_interrupt();
  VicInit();
  Init_Gpio();
  Init_timer0();
  __enable_interrupt();


  while(1)
  {};
}


视频效果如下:


http://player.youku.com/player.php/sid/XNzc5NjA3NDg=/v.swf

大家如果有什么问题,请和我一起交流,QQ:272564309

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户557576 2011-2-19 15:08

我也在用力天这个学习板,这个程序就是不能下到FLASH里,你的可以吗?
相关推荐阅读
用户191889 2009-08-15 14:59
1602+DS1302+18B20
https://static.assets-stash.eet-china.com/album/old-resources/2009/8/15/0883e80c-7762-44d3-ab2e-51e5...
用户191889 2009-08-14 16:11
液晶12864显示时钟和李白诗
https://static.assets-stash.eet-china.com/album/old-resources/2009/8/14/5ba7aa9b-adb9-45fc-8899-b4ba...
用户191889 2009-08-09 15:38
1602液晶+DS1302实时时钟
https://static.assets-stash.eet-china.com/album/old-resources/2009/8/9/0e92eee0-74a9-4f80-8a98-3f7a6...
用户191889 2009-07-03 19:55
【基础知识二】阻容降压的原理--转载
    最近研究公司里简单的单相电表的电压部分用到了阻容降压的方法取得电源,不太懂这个阻容降压,学习学习下面的内容。电容降压的工作原理   电容降压的工作原理并不复杂。他的工作原理是利用电容在一定的交...
用户191889 2009-06-29 22:06
[基础知识一]数字地和模拟地的区别--转载
      模拟电路涉及弱小信号,但是数字电路门限电平较高,对电源的要求就比模拟电路低些。既有数字电路又有模拟电路的系统中,数字电路产生的噪声会影响模拟电路,使模拟电路的小信号指标变差,克服的办法是分...
用户191889 2009-05-24 14:33
模拟电子很重要
      最近感觉模拟电子非常重要,大家如果是搞设计,一定要学好模拟电子。...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条