实验原理
同上多中断源实验相同,ARM开启两个中断源Eint1与Eint2,分别用一个按钮来控制。在没有中断的时候两个LED都缓慢闪烁,当任何一个中断被出发的时候,对应的LED会急促闪烁,逐渐回复正常。
此外,使用一个串口来发送当前状态,在无中断的时候发送正常状态报告,当有中断的时候,串口发送中断源。
Proteus仿真电路图
image.png
C语言源程序
#include <LPC21XX.H>
  • #include "uart0.h"
  • #define LED1 0x02000000/*LED1接在P0.25上*/
  • #define LED0 0x01000000/*LED0接在P0.24上*/
  • typedef unsigned int uint32;
  • void Eint1_ISR(void) __attribute__ ((interrupt));/*声明某函数为中断服务子程序的方法*/
  • void Eint0_ISR(void) __attribute__ ((interrupt));
  • uint32 times = 40;/*循环次数默认为40*/
  • char status[] = "Everytnig is fine.";
  • char eint0Str[] = "Interruption EINT0 activated!!!";
  • char eint1Str[] = "Interruption EINT1 activated!!!";
  • void delay40(void)  {                        
  •   unsigned volatile long i,j;
  •   for(i=0;i<10000;i++)
  •   for(j=0;j<times;j++)
  •   ;
  •   if(times > 40){
  •                 times-=2;
  •   }else if(times <40){
  •                 times+=2;
  •   }
  • }
  • void Eint0_ISR(void){  
  •   times = 0;
  •   while(times!=40){
  •               IO0CLR = LED0;
  •               delay40();
  •               IO0SET = LED0;
  •               delay40();
  •               serialPuts(eint0Str);                              
  •   }
  •   while((EXTINT&0x01)!=0){
  •    EXTINT=0x01;/*清除EINT0中断标志*/
  •   }
  •   VICVectAddr=0x00;
  • }
  • void Eint1_ISR(void){
  •   times = 0;
  •   while(times!=40){
  •               IO0CLR = LED1;
  •               delay40();
  •               IO0SET = LED1;
  •               delay40();
  •               serialPuts(eint1Str);               
  •   }
  •   while((EXTINT&0x02)!=0){
  •                 EXTINT=0x02;/*清除EINT1中断标志*/
  •   }
  •   VICVectAddr=0;
  • }
  • int  main(void)
  •               {
  •               IO0DIR = LED1|LED0;
  •               PINSEL0 = 0x20000005;/*引脚选中EINT1功能,开串口UART0*/
  •               PINSEL1 = 0x00000001;/*引脚选中EINT0功能*/
  • /*以下为中断控制部分*/                           
  •               VICIntSelect=0;/*全部中断设置为IRQ,若某位为1是FIQ*/
  •               VICIntEnable=0x0000C000;/*使能EINT1、0,EINT1为第15位,0为14位*/
  •               VICVectCntl0=0x2E;/*EINT0最高优先级*/
  •               VICVectAddr0=(int)Eint0_ISR;/*设置EINT0向量地址*/
  •               VICVectCntl1=0x2F;/*0xF,15号中断*/
  •               VICVectAddr1=(int)Eint1_ISR;/*设置中断服务子程序*/
  •               EXTINT=0x07;
  •               uart0Init();              
  •                 while (1)  {/*无中断时,两灯一起缓慢闪烁*/
  •                               IO0CLR = LED1|LED0;
  •                             delay40();
  •                               IO0SET = LED1|LED0;
  •                             delay40();
  •                             serialPuts(status);
  •                 }  
  • }
  • 复制代码
    文件二:uart0.c
    #include <LPC21XX.H>
  • #include "uart0.h"
  • #define CR 0x0D
  • int putchar (int ch)  {/* 向串口输出一个字符 */
  •   if (ch == '\n')  {
  •     while (!(U0LSR & 0x20));
  •     U0THR = CR;
  •   }
  •   while (!(U0LSR & 0x20));
  •   return (U0THR = ch);
  • }
  • void serialPuts(char *p){/* 向串口输出字符串 */
  •   while (*p != '\0'){
  •                 putchar(*p++);
  •   }
  •   putchar('\n');
  • }
  • void uart0Init(void){
  •   U0LCR = 0x83;/* 8位数据,无效验,一个停止位 */
  •   U0DLL = 97;/* VPB 15MHz的时候波特率为9600 */
  •   U0LCR = 0x03;/* DLAB = 0 */
  • }
  • 复制代码