这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » ARM,ARTX,RealView ARM水鸟外部中断ARTX之RealView

共2条 1/1 1 跳转至

ARM,ARTX,RealView ARM水鸟外部中断ARTX之RealView C++笔记

院士
2006-09-17 18:14:16     打赏
ARM,ARTX,RealView ARM水鸟外部中断ARTX之RealView C++笔记



关键词: RealView     水鸟     外部     中断     笔记    

院士
2006-12-22 22:43:00     打赏
2楼
问 /*----------------------------------------------------------------------
              ARM水鸟外部中断ARTXRealView C++笔记
HotPower@126.com  2006.2.18 于西安大雁塔村队部
http://blog.21ic.com/blog.asp?name=hotpower
-----------------------------------------------------------------------*/
/***********************************************************************/
/*  This file is part of the CA ARM C Compiler package                 */
/*  Copyright KEIL ELEKTRONIK GmbH 2002 - 2004                         */
/***********************************************************************/
/*                                                                     */
/*  MAIN.CPP:  Demonstration of various interrupt functions            */
/*                                                                     */
/***********************************************************************/

#include <LPC213x.H>    // Philips Peripheral Registers
#include <LPC213xDEF.H>    //ARM菜鸟HotPower创建定义文件(最新为情人节修改版)
/*
*具有特权保护的用户非向量中断,它只能在VICProtection=0时在用户模式下调用,比SWI更安全
*/

extern "C"
void Undef_Handler(void) __irq{
  if (VICIRQStatus & (unsigned long)(1 << VICIntSel_SoftInt31)) {
    IOPIN1 ^= (1 << P1_19);    //取反P1.19
    EXTINT = (unsigned char)(1 << VICIntSel_SoftInt31);    //清除VICIntSel_SoftInt31中断标志
    VICSoftIntClr = (unsigned long)(1 << VICIntSel_SoftInt31);
  }
  VICVectAddr = 0;
}

/*
extern "C"
void IRQ_Handler (void) __irq{//VICIntSelect=0且VICVectCntl0~VICVectCntl15都未中断使能
unsigned long temp;
  temp = VICIRQStatus;
  if (temp & (1 << VICIntSel_EINT0)) {
    IOPIN1 ^= (1 << P1_16);    //取反P1.16
    EXTINT = (1 << EINT0);    //清除INT0中断标志
  }
  else if (temp & (1 << VICIntSel_EINT1)) {
    IOPIN1 ^= (1 << P1_17);    //取反P1.17
    while(EXTINT & (1 << EINT1)) {
      EXTINT = (1 << EINT1);    //清除INT1中断标志
    }
  }
  else if (temp & (1 << VICIntSel_EINT2)) {
    IOPIN1 ^= (1 << P1_18);    //取反P1.18
    EXTINT = (1 << EINT2);    //清除INT2中断标志
  }
  else if (temp & (1 << VICIntSel_EINT3)) {
    IOPIN1 ^= (1 << P1_19);    //取反P1.19
    EXTINT = (1 << EINT3);    //清除INT3中断标志
  }
  else {//其他干扰源
//再次填入干扰处理代码
  }
  VICSoftIntClr = temp;//抗击无效VICSoftInt=XXX的入侵
  VICVectAddr = 0;
}
*/

extern "C"
void EINT0IRQ (void) __irq{//IRQ中断函数EINT0IRQ被挂接在VICVectCntl0
  __enable_irq();
  if (VICIRQStatus & (1 << VICIntSel_EINT0)) {
    IOPIN1 ^= (1 << P1_16);    //取反P1.16
  }
  VICSoftIntClr = (1 << VICIntSel_EINT0);
  EXTINT = (1 << EINT0);    //清除INT0中断标志
  VICVectAddr = 0;
}

extern "C"
void EINT1IRQ (void) __irq{//IRQ中断函数EINT1IRQ被挂接在VICVectCntl1
  if (VICIRQStatus & (1 << VICIntSel_EINT1)) {
    IOSET1 = (1 << P1_17);    //P1.17=1
    while(EXTINT & (1 << EINT1)) {
      EXTINT = (1 << EINT1);    //清除INT1中断标志
    }
    IOCLR1 = (1 << P1_17);    //P1.17=0
    VICSoftIntClr = (1 << VICIntSel_EINT1);
  }
  VICVectAddr = 0;
}

extern "C"
void EINT2IRQ (void) __irq{//IRQ中断函数EINT2IRQ被挂接在VICVectCntl2
  if (VICIRQStatus & (1 << VICIntSel_EINT2)) {
    IOPIN1 ^= (1 << P1_18);    //取反P1.18
  }
  EXTINT = (1 << EINT2);    //清除INT2中断标志
  VICSoftIntClr = (1 << VICIntSel_EINT2);
  VICVectAddr = 0;
}

extern "C"
void EINT3IRQ (void) __irq{//IRQ中断函数EINT3IRQ被挂接在VICVectCntl3
  if (VICIRQStatus & (1 << VICIntSel_EINT3)) {
    IOPIN1 ^= (1 << P1_19);    //取反P1.19
  }
  EXTINT = (1 << EINT3);    //清除INT3中断标志
  VICSoftIntClr = (1 << VICIntSel_EINT3);
  VICVectAddr = 0;
}


extern "C"
void FIQ_Handler (void) __irq{//VICIntSelect非0
unsigned long temp;
  temp = VICFIQStatus;
  if (temp & (1 << VICIntSel_EINT0)) {
    IOPIN1 ^= (1 << P1_16);    //取反P1.16
    EXTINT = (1 << EINT0);    //清除INT0中断标志
  }
  else if (temp & (1 << VICIntSel_EINT1)) {
    IOSET1 = (1 << P1_17);    //P1.17=1
    while(EXTINT & (1 << EINT1)) {
      EXTINT = (1 << EINT1);    //清除INT1中断标志
    }
    IOCLR1 = (1 << P1_17);    //P1.17=0
  }
  else if (temp & (1 << VICIntSel_EINT2)) {
    IOPIN1 ^= (1 << P1_18);    //取反P1.18
    EXTINT = (1 << EINT2);    //清除INT2中断标志
  }
  else if (temp & (1 << VICIntSel_EINT3)) {
    IOPIN1 ^= (1 << P1_19);    //取反P1.19
    EXTINT = (1 << EINT3);    //清除INT3中断标志
  }
  else {//其他干扰源
//再次填入干扰处理代码
  }
  VICSoftIntClr = temp;//抗击无效VICSoftInt=XXX的入侵
  VICVectAddr = 0;
}


extern "C" int __swi(0)  myfunc1 (int i1, long i2);
extern "C" int __SWI_0           (int i1, long i2){
  return (i1 / i2);
}

extern "C" int __swi(1) myfunc2 (int i1);
extern "C" int __SWI_1             (int i1) {
  return (i1<<4);
}

extern "C" void __swi(2) SetVICProtection(unsigned long val);
extern "C" void __SWI_2                  (unsigned long val){
  VICProtection = val;//VICProtection可以随意置'1',但清'0'必须在管理模式下
}

extern "C" __inline void __enable_IRQ(void)
{
int tmp;
  __asm
  {
    MRS tmp, SPSR
    BIC tmp, tmp, #0x80
    MSR SPSR_cxsf, tmp
  }
}
extern "C" __inline void __disable_IRQ(void)
{
int tmp;
  __asm
  {
    MRS tmp, SPSR
    ORR tmp, tmp, #0x80
    MSR SPSR_cxsf, tmp
  }
}

extern "C" void __swi(3) Enable_IRQ(void);
extern "C" void __SWI_3               (void) {
  __enable_IRQ();
}

extern "C" void __swi(4) Disable_IRQ(void);
extern "C" void __SWI_4               (void) {//最大的SWI数
  __disable_IRQ();
}

/*
注意:在Keil RealView编译器软中断SWI.S通用代码中应该进行以下设置
Artx_SETUP      EQU     0;0-在非ARTX上运行  1-在ARTX上运行
Store_SPSR        EQU     1;0-在非ARTX上可以修改I/F
;                         1-在非ARTX上不可以修改I/F,即对Disable_IRQ()函数无效
Swi_COUNT       EQU     4 + 1;__SWI_4(在ARTX时至少取Swi_COUNT=8+1)
*/
int res;

int main (void)
{
  for(int i =0; i < 10; i ++) {
    IODIR1 = i;
  }
//  __enable_irq();//RV自带的只能在特权模式下使用
//  __disable_irq();//RV自带的只能在特权模式下使用
  Disable_IRQ();//关向量中断
  __nop();//RV自带NOP
  Enable_IRQ();//开向量中断
  IODIR1         = (1 << P1_23) | (1 << P1_22) | (1 << P1_21) | (1 << P1_20)
                  |(1 << P1_19) | (1 << P1_18) | (1 << P1_17) | (1 << P1_16);//设置LED输出方式

  PINSEL0          |= (P0_14_EINT1 << P0_14_PINSEL) //选择P0.14为INT1外部中断引脚
//                     | (P0_7_EINT2 << P0_7_PINSEL)   //选择P0.7为INT2外部中断引脚
                     | (P0_15_EINT2 << P0_15_PINSEL); //选择P0.15为INT2外部中断引脚
//                     | (P0_9_EINT3 << P0_9_PINSEL)   //选择P0.9也为INT3外部中断引脚
//                     | (P0_1_EINT0 << P0_1_PINSEL)   //选择P0.1也为INT0外部中断引脚
//                     | (P0_3_EINT1 << P0_3_PINSEL);  //选择P0.3也为INT1外部中断引脚

  PINSEL1          |= (P0_16_EINT0 << P0_16_PINSEL) //选择P0.16为INT0外部中断引脚
                     | (P0_20_EINT3 << P0_20_PINSEL); //选择P0.20也为INT3外部中断引脚
//                     | (P0_30_EINT3 << P0_30_PINSEL);//选择P0.30也为INT3外部中断引脚(Keil仿真不了)
  
  EXTPOLAR       &= ~((1 << EXTPOLAR0) //INT0为低电平有效
                  |  (1 << EXTPOLAR1)  //INT1为低电平有效
                  |  (1 << EXTPOLAR2)  //INT2为低电平有效
                  |  (1 << EXTPOLAR3));//INT3为低电平有效

  EXTPOLAR       |= (1 << EXTPOLAR0); //INT0为高电平有效


  EXTMODE        |= (1 << EXTMODE0) //设置INT0为边沿触发
                  | (1 << EXTMODE2) //设置INT2为边沿触发
                  | (1 << EXTMODE3);//设置INT3为边沿触发

  EXTMODE        &= ~(1 << EXTMODE1);//设置INT1为电平触发

  VICVectCntl0   = VICIntSel_Enable//使能IRQ中断
                 | VICIntSel_EINT0;//获取EINT0的IRQ级别
  VICVectAddr0   = (unsigned long) EINT0IRQ;//取INT0中断服务地址


  VICVectCntl1   = VICIntSel_Enable//使能IRQ中断
                 | VICIntSel_EINT1;//获取EINT1的IRQ级别
  VICVectAddr1   = (unsigned long)EINT1IRQ;//取INT1中断服务地址

  VICVectCntl2   = VICIntSel_Enable//使能IRQ中断
                 | VICIntSel_EINT2;//获取EINT2的IRQ级别
  VICVectAddr2   = (unsigned long)EINT2IRQ;//取INT2中断服务地址

  VICVectCntl3   = VICIntSel_Enable//使能IRQ中断
                 | VICIntSel_EINT3;//获取EINT3的IRQ级别
  VICVectAddr3   = (unsigned long)EINT3IRQ;//取INT3中断服务地址

  VICVectCntl4   = VICIntSel_Enable//使能IRQ中断
                 | VICIntSel_SoftInt31;//获取VICIntSel_SoftInt31的IRQ级别
  VICVectAddr4   = (unsigned long)Undef_Handler;//取VicInt31中断服务地址


//  VICVectCntl0  &= ~VICIntSel_Enable;//放弃EINT0的IRQ级别,获取默认中断级别
//  VICVectCntl1  &= ~VICIntSel_Enable;//放弃EINT1的IRQ级别,获取默认中断级别
//  VICVectCntl2  &= ~VICIntSel_Enable;//放弃EINT2的IRQ级别,获取默认中断级别

//  VICDefVectAddr = (long)IRQ_Handler;//取默认中断服务地址

  VICIntSelect   = 0;//全部中断为IRQ中断或默认中断
  VICIntSelect   = (1 << VICIntSel_EINT3); //设置EINT3为FIQ中断

/*
  VICIntSelect   = (1 << VICIntSel_EINT0) //设置EINT0为FIQ中断
                 | (1 << VICIntSel_EINT1) //设置EINT1为FIQ中断
                 | (1 << VICIntSel_EINT2) //设置EINT2为FIQ中断
                 | (1 << VICIntSel_EINT3);//设置EINT2为FIQ中断
*/

  EXTINT = (1 << EINT0) | (1 << EINT1) | (1 << EINT2) | (1 << EINT3);    //清除INT中断标志


//  VICSoftIntClr = 0xffffffff;//清除所有软中断标志
  VICSoftIntClr  = (1 << VICIntSel_EINT0) //清除EINT0软中断标志
                 | (1 << VICIntSel_EINT1) //清除EINT1软中断标志
                 | (1 << VICIntSel_EINT2) //清除EINT2软中断标志
                 | (1 << VICIntSel_EINT3);//清除EINT3软中断标志

  VICIntEnable   = (1 << VICIntSel_EINT0) //使能EINT0中断
                 | (1 << VICIntSel_EINT1) //使能EINT1中断
                 | (1 << VICIntSel_EINT2) //使能EINT2中断
                 | (1 << VICIntSel_EINT3);//使能EINT3中断

  VICIntEnable  |= (unsigned long)(1 << VICIntSel_SoftInt31);//使能VICIntSel_SoftInt31中断

  SetVICProtection(1);//打开特权保护,阻止VICSoftInt软中断
  VICSoftInt     = (1 << VICIntSel_EINT0);//(VICIntEnable & (1 << VICIntSel_EINT0))使能才能软中断
            
  SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
  VICSoftInt     = (1 << VICIntSel_EINT1);//(VICIntEnable & (1 << VICIntSel_EINT1))使能才能软中断

  SetVICProtection(1);//打开特权保护,阻止VICSoftInt软中断
  VICSoftInt     = (1 << VICIntSel_EINT2);//(VICIntEnable & (1 << VICIntSel_EINT2))使能才能软中断

  SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
  VICSoftInt     = (1 << VICIntSel_EINT3);//(VICIntEnable & (1 << VICIntSel_EINT3))使能才能软中断

  SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
  VICSoftInt     = (unsigned long)(1 << VICIntSel_SoftInt31);//(VICIntEnable & (1 << VICIntSel_SoftInt31))使能才能软中断

  res = myfunc1 (10, 2);          // call SWI functions
  res += myfunc2 (res);


  while (1) {                      // endless loop
    __nop();
  }
}
1: 我怎么看好像和C一样啊?我怎么看好像和C一样啊? 2: 哈哈,只是不加C++的演示部分,主要为了测试通用SWI.S文件看看这个像吗??? 3: Store_SPSR=0/1时用Disable_IRQ()关向量中断的帖图这里今天晕图,给个链接吧...

共2条 1/1 1 跳转至

回复

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