微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM中外部中断

ARM中外部中断

时间:11-20 来源:互联网 点击:

需要注意的是:在do_irq()函数中有一个清中断的操作,否则,将会告诉中断控制器处理好了中断,以免一直触发外部中断:

87 void do_irq()
88 {
89 printf("key 1 down\n");
90 static int flag=1;
91 if(flag)
92 {
93 printf("wtc_on\n");
94 led_on();
95 pwm_on();
96 flag=0;
97 }
98 else if(flag == 0)
99 {
100 printf("wtc_off\n");
101 led_off();
102 pwm_off();
103 flag=1;
104 }
105

EXT_INT43PEND = (1 < 2);//清中断
106 }

当程序运行成功了之后,按下按键,LED和蜂鸣器就会工作,再按下按键,LED和蜂鸣器就会停止!

接下来,将以前的中断问题综合起来:写了一个用外部中断来控制LED灯闪烁的例子

流程图是:

主要是do_rirq()函数:代码如下:

87 void do_irq()88     {89             printf("key 1 down\n");90             static int flag=1;91             if(flag)92             {93                 printf("wtc_on\n");94                 led_on();95                 pwm_on();96                 flag=0;97             }98             else if(flag == 0)99             {100                 printf("wtc_off\n");101                 led_off();102                 pwm_off();103                 flag=1;104             }105             EXT_INT43PEND = (1 < 2);//清中断106     }

接下来是整个程序的代码:

1 #include"regs.h"2 3 int (*printf)(char *, ...) = 0xc3e114d8;4 int(*delay)(int)=0xc3e25f90;5 6 void init_ttb(unsigned long *addr);7 void enable_mmu(void);8 unsigned long data_abort_init();9 void memcopy(unsigned long* dest,unsigned long* source,int len);10 void do_irq();11 void wtc_on();12 void wtc_off();13 void pwm_on(void);14 void pwm_off(void);15 void led_on(void);16 void led_on(void);17 18 19 20 int main()21 {22      *(unsigned long *)0x66 = do_irq;23 24     //发生异常时会进入异常模式跳转到0 4地址处理异常事件   25     unsigned long source_addr=data_abort_init();26     //异常事件处理函数27     printf("swi_souce addr is %x\n",source_addr);28     //将异常处理地址的值放到0x6429     memcopy(0x60,source_addr,0x1);30 31     enable_mmu();32     //内存映射将0x04映射到0x6004    33 34      //step 1: cpu cpsr35       __asm__ __volatile__(36           "mrs r0, cpsr\n"37           "bic r0, r0, #0x80\n"//设置CPSR的I位,将IRQ位打开38           "msr cpsr, r0\n"39           ::: "r0"40       );41 42     //setp1:GIC43     ICCICR_CPU0 = 1;44     ICCPMR_CPU0 = 0xff;45 46     //6447     ICDDCR = 1;48     ICDIPR16_CPU0 = (0x0 < 0);//ICD第16个寄存器,第0位49     ICDIPTR16_CPU0 = (0x1 < 0);//优先级,最高50     ICDISER2_CPU0 = (1 < 0);//一共五个,第2个使能中断51 52     //7553      ICDIPR18_CPU0 = (0x0 < 24);54     //ICDIPTR0_CPU0 = 1;55     ICDIPTR18_CPU0 = (0x1 < 24);56     //ICDISER0_CPU0 = (1 < 0);57     ICDISER2_CPU0 = (1 < 11);58 59     //step 3: set gpio60     GPX3CON = (0xf < 8);//是GPXCON为外部中断功能61 62     //step 4: extern63     EXT_INT43CON = (2 < 8);//设置上升沿触发64     EXT_INT43MASK = 0;//使能中断65 66     /////////////////////////狗67 68     //step 5: sourcevoid pwm_on(void)69 70 71 72     printf("welcome back! \n");73 }74 75 void pwm_on(void)76     {77         GPD0CON &= ~0xffff;78         GPD0CON = 0x1;//配置寄存器为279         GPD0DAT = 0x1;//date=0xf80     }81 82 void pwm_off(void)83     {84         GPD0CON &= ~0xffff;85         GPD0CON = 0x0;86     //  GPD0DAT &=0x0 ;//date=0xf87 88     }89 void led_off(void)90     {91         GPM4CON &= ~0xffff;//清零92         GPM4CON = 0x0;//03位清零93         GPM4DAT = 0x0;//date=0xf关闭置一94     }95 void led_on(void)96     {97         GPM4CON &= ~0xffff;98         GPM4CON = 0x1;//配置寄存器3-0--3-3全为1,全为输出模式99         GPM4DAT &= ~0xf;//打开置0-4位为0100     }101 102 void wtc_on()103     {104             //step 3: interrupt source watchdog105         WTCON = 0  (1 < 2)  (3 < 3)  (1 < 5)  (20 < 8);106         WTCNT = 0x8;107         WTDAT = 0x2;108     }109 110 void wtc_off(){112         WTCON = 0;113 }114 115 void do_irq()116     {117     //   pwm_on();118     //   led_on();119      //    delay(6);120     //   pwm_off();121     //   led_off();122 123     unsigned long data = ICCIAR_CPU0;124     unsigned long irq_id = data & 0x3ff;125     unsigned long cpu_id = (data >> 10) & 0x7;126     ICCEOIR_CPU0 = irq_id  (cpu_id < 10);127     printf("irq is %d, cpu is %d\n", irq_id, cpu_id);128     if(irq_id==64)//如果按键中断129     {130         if(EXT_INT43PEND & (1 < 2))131         {132             EXT_INT43PEND = (1 < 2);//清中断133             printf("key 1 down\n");134             static int flag=1;135             if(flag)136             {137                 printf("wtc_on\n");138                 wtc_on();139                 flag=0;140             }141             else if(flag == 0)142             {143                 printf("wtc_off\n");144                 wtc_off();145                 led_off();146                 pwm_off();147                 flag=1;148             }149         }150     }151     if(irq_id==75)//如果DOG中断152     {153         printf("dog  dog   dog  \n");154         static int flag=1;155         if(flag)156         {157             led_on();158             pwm_on();159             flag=0;160         }161         else162         {163             led_off();164             pwm_off();165             flag=1;166         }167       WTCLRINT = 100;//清狗中断168     }169 170     }171 172 void memcopy(unsigned long* dest, unsigned long* source,int len)173 {174     int i=0;;175     for(i=0;i> 20] = pa  2;280         //2的目的是将0-2位置为10此时将是小页模式4K281     }282 283     //00-10   ====  6070284     for(va=0x00; va<=0x10; va+=0x100){285         pa = va+0x60;286         addr[va >> 20] = pa  2;287     }288 289     //10-14   ====  1014290     for(va=0x10; va<=0x14; va+=0x100){291         pa = va;292         addr[va >> 20] = pa  2;293     }294 295     //30-40   ====  5060296     for(va=0x30; va<0x40; va+=0x100){297         pa = va + 0x20;298         addr[va >> 20] = pa  2;299     }300 }301 302 void enable_mmu(void)303 304 {305     unsigned long addr = 0x70;306     init_ttb(addr);307     //step:初始化页表308 309     unsigned long mmu = 1  (1 < 1)  (1 < 8);310     //将MMU的第0,1,8位置1311     __asm__ __volatile__(312         "mov r0, #3\n"313         "MCR p15, 0, r0, c3, c0, 0\n"//manager314         "MCR p15, 0, %0, c2, c0, 0\n"//addr  315         "MCR p15, 0, %1, c1, c0, 0\n"// enable mmu316         :317         : "r" (addr), "r" (mmu)318         : "r0"319     );320     printf("MMU is enable!\n");321 }322 

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top