这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » LPC2104 怎样调通LPC2104的外部中断!!!

共2条 1/1 1 跳转至

LPC2104 怎样调通LPC2104的外部中断!!!

院士
2006-09-17 18:14:16     打赏
LPC2104 怎样调通LPC2104的外部中断!!!



关键词: LPC2104     怎样     调通     外部     中断    

院士
2006-12-22 22:43:00     打赏
2楼
问 经过3天的时间,终于调通了2104开发板的外部非向量中断。

我的开发板是esayARM2104,跑例子程序EINT1_test没有问题,而我自己用LPC21XX的工程模板建立的项目,把原来的EINT1_LED.c拷过来,编译,调试,却无法进入中断,在论坛上我发现很多人也遇到了同样的问题。

今天,我终于把这个程序给调通了,在此传上来供大家参考。注意:我的程序是在flsah中调试,所以没有进行remap,编译时必须选择DebugInFlash。

其实,LPC2104的非向量中断很简单,只是由于工程模板的启动代码和例子程序不一样,所以不能直接运行,要自己进行修改。
1. 首先要打开IRQ中断。就是cpsr的i为必须清零。这一步可以在InitStack里加上。
2. 要在自己的c程序EINT1_LED.c中加上对 VICDefVectAddr的赋值操作,制定中断服务程序的地址。
3. 要在中断服务程序的末尾对VICVectAddr清零,以便能够再次进入中断。

以下是经过修改的EINT1_LED.c程序:
/****************************************************************************
* File:EINT1_LED.C
* 功能:使用外部中断1进行LED4的控制,每当有一次中断时,即取反LED4,
*      以便指示中断输入。
* 说明:将跳线器JP8_LED4短接。
****************************************************************************/
#include  "config.h"
  

#define      LEDCON    0x00002000        /* P0.13引脚控制LED4,低电平点亮*/


/****************************************************************************
* 名称:IRQ_Eint1()
* 功能:外部中断EINT1服务函数,取反LED4。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void   __irq IRQ_Eint1(void)
{  uint32  i;

   i = VICIRQStatus;                // 读出VICIRQStatus的值
   
   i = IOSET;                        // 读取当前LED4控制值
   if( (i&LEDCON)==0 )                // 控制LED4输出
   {  IOSET = LEDCON;
   }
   else
   {  IOCLR = LEDCON;
   }
   
   while( (EXTINT&0x02)!=0 )        // 等待外部中断信号恢复为高电平    
   {  EXTINT = 0x02;                // 清除EINT1中断标志
   
   }
   VICVectAddr=0;//清零,下次可以进入中断
   
   
}        
            

/****************************************************************************
* 名称:main()
* 功能:初始化外部中断1及IO连接等。
****************************************************************************/
int  main(void)
{  PINSEL0 = 0x20000000;        // 设置I/O口工作模式,P0.14设置为EINT1
   PINSEL1 = 0x00000000;
   IODIR = LEDCON;                // 设置LED4控制口为输出,其它I/O为输入

   VICDefVectAddr=(int)IRQ_Eint1;//设置中断服务程序的地址
    
   /*  打开EINT1中断(不设置向量控制器,即使用非向量IRQ) */
   VICIntSelect = 0x00000000;
   VICIntEnable = 0x00008000;
   EXTINT = 0x07;                // 清除外部中断标志    
   
   while(1);                    // 等待中断
   return(0);
}

以下是修改过的启动代码Startup.s
;/****************************************Copyright (c)**************************************************
;**                               广州周立功单片机发展有限公司
;**                                     研    究    所
;**                                        产品一部
;**
;**                                 http://www.zlgmcu.com
;**
;**--------------文件信息--------------------------------------------------------------------------------
;**文   件   名: Startup.s
;**创   建   人: 陈明计
;**最后修改日期: 2004年3月3日
;**描        述: lpc21xx的启动代码,包含异常向量入口、初始化堆栈的代码等
;**              每个工程应当有独立的这个文件的拷贝,并进行相应的修改   
;**--------------历史版本信息----------------------------------------------------------------------------
;** 创建人: 陈明计
;** 版  本: v1.0
;** 日 期: 2004年2月2日
;** 描 述: 原始版本
;**
;**------------------------------------------------------------------------------------------------------
;** 修改人:
;** 版  本:
;** 日 期:
;** 描 述:
;**
;**--------------当前版本修订------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;** 描 述:
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/

;定义堆栈的大小
SVC_STACK_LEGTH         EQU         0
FIQ_STACK_LEGTH         EQU         0
IRQ_STACK_LEGTH         EQU         256
ABT_STACK_LEGTH         EQU         0
UND_STACK_LEGTH         EQU         0

NoInt       EQU 0x80

USR32Mode   EQU 0x10
SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f
IRQ32Mode   EQU 0x12
FIQ32Mode   EQU 0x11

PINSEL2     EQU 0xE002C014


;引入的外部标号在这声明
    IMPORT  FIQ_Exception                   ;快速中断异常处理程序
    IMPORT  __main                          ;C语言主程序入口
    IMPORT  TargetResetInit                 ;目标板基本初始化
    IMPORT  StackUsr
    IMPORT  bottom_of_heap

;给外部使用的标号在这声明
    EXPORT  Reset
    EXPORT __rt_div0
    EXPORT __user_initial_stackheap

    CODE32

    AREA    vectors,CODE,READONLY
        ENTRY
;中断向量表
Reset
        LDR     PC, ResetAddr
        LDR     PC, UndefinedAddr
        LDR     PC, SWI_Addr
        LDR     PC, PrefetchAddr
        LDR     PC, DataAbortAddr
        DCD     0xb9205f80
        LDR     PC, [PC, #-0xff0]
        LDR     PC, FIQ_Addr

ResetAddr           DCD     ResetInit
UndefinedAddr       DCD     Undefined
SWI_Addr            DCD     SoftwareInterrupt
PrefetchAddr        DCD     PrefetchAbort
DataAbortAddr       DCD     DataAbort
Nouse               DCD     0
IRQ_Addr            DCD     0
FIQ_Addr            DCD     FIQ_Handler

;未定义指令
Undefined
        B       Undefined

;软中断
SoftwareInterrupt
        B       SoftwareInterrupt

;取指令中止
PrefetchAbort
        B       PrefetchAbort

;取数据中止
DataAbort
        B       DataAbort

;快速中断
FIQ_Handler
        STMFD   SP!, {R0-R3, LR}
        BL      FIQ_Exception
        LDMFD   SP!, {R0-R3, LR}
        SUBS    PC,  LR,  #4

;/*********************************************************************************************************
;** 函数名称: InitStack
;** 功能描述: 初始化堆栈
;** 输 入:   无
;** 输 出 :  无
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修 改:
;** 日 期:
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
InitStack    
        MOV     R0, LR

;设置管理模式堆栈
        MSR     CPSR_c, #0xd3
        LDR     SP, StackSvc
;设置中断模式堆栈
        MSR     CPSR_c, #0xd2
        LDR     SP, StackIrq
;设置快速中断模式堆栈
        MSR     CPSR_c, #0xd1
        LDR     SP, StackFiq
;设置中止模式堆栈
        MSR     CPSR_c, #0xd7
        LDR     SP, StackAbt
;设置未定义模式堆栈
        MSR     CPSR_c, #0xdb
        LDR     SP, StackUnd
;设置系统模式堆栈
        MSR     CPSR_c, #0xdf
        LDR     SP, =StackUsr
        
        MSR     CPSR_c,#0x1f   ;这行程序使能IRQ中断,清零cpsr的I位
        MOV     PC, R0

;/*********************************************************************************************************
;** 函数名称: ResetInit
;** 功能描述: 复位入口
;**
;** 输 入: 无
;**
;** 输 出: 无
;**         
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修改人: 陈明计
;** 日 期: 2004年3月3日
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
ResetInit     
        BL      InitStack               ;初始化堆栈
        BL      TargetResetInit         ;目标板基本初始化
                                        
        B       __main            ;跳转到c语言入口


;/*********************************************************************************************************
;** 函数名称: __user_initial_stackheap
;** 功能描述: 库函数初始化堆和栈,不能删除
;**
;** 输 入: 参考库函数手册
;**
;** 输 出: 参考库函数手册
;**         
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
__user_initial_stackheap    
    LDR   r0,=bottom_of_heap
    MOV   pc,lr


;/*********************************************************************************************************
;** 函数名称: __rt_div0
;** 功能描述: 整数除法除数为0错误处理函数,替代原始的__rt_div0减少目标代码大小
;**
;** 输 入: 参考库函数手册
;**
;** 输 出: 无
;**         
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
__rt_div0

        B       __rt_div0

StackSvc           DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq           DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt           DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd           DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)* 4


;/* 分配堆栈空间 */
        AREA    MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间
UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈
    END
;/*********************************************************************************************************
;**                            End Of File
;********************************************************************************************************/

其他文件不需要改动。就可以了!!!

如果想在ram里调试,加上remap程序即可。

以上只是个人的一点心得,希望能让学习ARM的人少走些弯路。同时我也在学习ARM,希望大家共同进步!!!
1: 是在Vectors.s中修改吗?实在无奈,只好闯老帖子了!
我怎么编译都通不过?是在init.s还是 Vectors.s中修改
刚开始学ARM,还没能力自己写启动代码,在做这个试验时也遇到中断进不去的问题,希得到帮助!

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]