实验五--中断系统

发布时间:2023-06-13  

一。平台

  系统:ubuntu12.04

  开发板:jz2440

  编译器:gcc

二。中断简略

  大概除了FPGA这种并行的cpu才不需要中断,像51,AVR,arm这类串行的芯片中断是他们不被淘汰的利器。没有中断,他们不可能得到这么广泛的应用。

  arm中断和51的类似,无非就是设置相关寄存器、中断开关,中断源,中断分辨之类的东西;但是注意,arm的中断只是7个模式下的一个,此外,中断还有普通中断和快速中断之分。

  而快速中断不需要进行中断的分辨,因为每次最多只有一个被设置为快速中断。

  

     这里看中断源分为两部分。一个是with sub-register,另一个是without,有何区别?试想下,串口会有几个中断?发送中断,接受中断,至少两个吧,那么中断源是怎么做的呢,是当做两个来,那么就得给分配很多中断向量吧。实际上,with sub-register就是把中断源进行归类。看:

比如uart0  有3个子源,

在60个中断源里面只当做一个;

当然后面会进行分别中断,像

若OFFSET=12,说明中断是串口0.

然后就是中断屏蔽 和优先级的问题。

这个寄存器设置快速中断的,每次只能有一位设置成快速中断。

三。看代码先

Makefile

 1 objs := head.o init.o interrupt.o main.o

 2 

 3 int.bin: $(objs)

 4     arm-linux-ld -Ttext 0x00000000 -o int_elf $^

 5     arm-linux-objcopy -O binary -S int_elf $@

 6     arm-linux-objdump -D -m arm int_elf > int.dis

 7     

 8 %.o:%.c

 9     arm-linux-gcc -Wall -O2 -c -o $@ $<

10 

11 %.o:%.S

12     arm-linux-gcc -Wall -O2 -c -o $@ $<

13 

14 clean:

15     rm -f int.bin int_elf int.dis *.o        

16     


head.S


 1 @******************************************************************************

 2 @ File:head.S

 3 @ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数

 4 @******************************************************************************       

 5    

 6 .extern     main

 7 .text 

 8 .global _start 

 9 _start:

10 @******************************************************************************       

11 @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用

12 @******************************************************************************       

13     b   Reset

14 

15 @ 0x04: 未定义指令中止模式的向量地址

16 HandleUndef:

17     b   HandleUndef 

18  

19 @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式

20 HandleSWI:

21     b   HandleSWI

22 

23 @ 0x0c: 指令预取终止导致的异常的向量地址

24 HandlePrefetchAbort:

25     b   HandlePrefetchAbort

26 

27 @ 0x10: 数据访问终止导致的异常的向量地址

28 HandleDataAbort:

29     b   HandleDataAbort

30 

31 @ 0x14: 保留

32 HandleNotUsed:

33     b   HandleNotUsed

34 

35 @ 0x18: 中断模式的向量地址

36     b   HandleIRQ

37 

38 @ 0x1c: 快中断模式的向量地址

39 HandleFIQ:

40     b   HandleFIQ

41 

42 Reset:                  

43     ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈

44     bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启

45     

46     msr cpsr_c, #0xd2       @ 进入中断模式

47     ldr sp, =3072           @ 设置中断模式栈指针    因为下面代码都是管理模式下,所以先设置中断模式的栈

48 

49     msr cpsr_c, #0xd3       @ 进入管理模式

50     ldr sp, =4096           @ 设置管理模式栈指针,

51                             @ 其实复位之后,CPU就处于管理模式,

52                             @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略

53 

54     bl  init_led            @ 初始化LED的GPIO管脚

55     bl  init_irq            @ 调用中断初始化函数,在init.c中

56     msr cpsr_c, #0x5f       @ 设置I-bit=0,开IRQ中断

57     

58     ldr lr, =halt_loop      @ 设置返回地址

59     ldr pc, =main           @ 调用main函数

60 halt_loop:

61     b   halt_loop

62 

63 HandleIRQ:

64     sub lr, lr, #4                  @ 计算返回地址

65     stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器

66                                     @ 注意,此时的sp是中断模式的sp

67                                     @ 初始值是上面设置的3072

68     

69     ldr lr, =int_return             @ 设置调用ISR即EINT_Handle函数后的返回地址  

70     ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中

71 int_return:

72     ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr

73     


init.c


 1 /*

 2  * init.c: 进行一些初始化

 3  */ 

 4 

 5 #include "s3c24xx.h"

 6 

 7 /*

 8  * LED1,LED2,LED4对应GPF4、GPF5、GPF6

 9  */

10 #define    GPF4_out    (1<11 #define    GPF5_out    (1<12 #define    GPF6_out    (1<13 

14 #define    GPF4_msk    (3<15 #define    GPF5_msk    (3<16 #define    GPF6_msk    (3<17 

18 /*

19  * S2,S3,S4对应GPF0、GPF2、GPG3

20  */

21 #define GPF0_eint     (0x2<22 #define GPF2_eint     (0x2<23 #define GPG3_eint     (0x2<24 

25 #define GPF0_msk    (3<26 #define GPF2_msk    (3<27 #define GPG3_msk    (3<28 

29 /*

30  * 关闭WATCHDOG,否则CPU会不断重启

31  */

32 void disable_watch_dog(void)

33 {

34     WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可

35 }

36 

37 void init_led(void)

38 {

39     // LED1,LED2,LED4对应的3根引脚设为输出

40     GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);

41     GPFCON |= GPF4_out | GPF5_out | GPF6_out;

42 }

43 

44 /*

45  * 初始化GPIO引脚为外部中断

46  * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)  设置第二功能

47  */ 

48 void init_irq( )

49 {

50     // S2,S3对应的2根引脚设为中断引脚 EINT0,ENT2

51     GPFCON &= ~(GPF0_msk | GPF2_msk);

52     GPFCON |= GPF0_eint | GPF2_eint;

53 

54     // S4对应的引脚设为中断引脚EINT11

55     GPGCON &= ~GPG3_msk;

56     GPGCON |= GPG3_eint;

57     

58     // 对于EINT11,需要在EINTMASK寄存器中使能它

59     EINTMASK &= ~(1<<11);

60         

61     /*

62      * 设定优先级:

63      * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2

64      * 仲裁器1、6无需设置

65      * 最终:

66      * EINT0 > EINT2 > EINT11即K2 > K3 > K4

67      */

68     PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;

69 

70     // EINT0、EINT2、EINT8_23使能

71     INTMSK   &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));

72 }


interrupt.c   识别中断  OFFSET寄存器


 1 #include "s3c24xx.h"

 2 

 3 void EINT_Handle()

 4 {

 5     unsigned long oft = INTOFFSET;

 6     unsigned long val;

 7     

 8     switch( oft )

 9     {

10         // S2被按下

11         case 0: 

12         {   

13             GPFDAT |= (0x7<<4);   // 所有LED熄灭

14             GPFDAT &= ~(1<<4);      // LED1点亮

15             break;

16         }

17         

18         // S3被按下

19         case 2:

20         {   

21             GPFDAT |= (0x7<<4);   // 所有LED熄灭

22             GPFDAT &= ~(1<<5);      // LED2点亮

23             break;

24         }

25 

26         // K4被按下

27         case 5:

28         {   

29             GPFDAT |= (0x7<<4);   // 所有LED熄灭

30             GPFDAT &= ~(1<<6);      // LED4点亮                

31             break;

32         }

33 

34         default:

35             break;

36     }

37 

38     //清中断

39     if( oft == 5 ) 

40         EINTPEND = (1<<11);   // EINT8_23合用IRQ5

41     SRCPND = 1<42     INTPND = 1<43 }


最后main里面就是空循环,等待中断。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>