Chinaunix首页 | 论坛 | 博客
  • 博客访问: 114684
  • 博文数量: 50
  • 博客积分: 968
  • 博客等级: 少尉
  • 技术积分: 492
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-17 09:51
文章分类

全部博文(50)

文章存档

2012年(2)

2011年(48)

我的朋友

分类: LINUX

2011-05-20 19:59:19


1 SUBSRCPNDSRCPND表明有哪些中断被触发了

    INTSUMMSKINTMSK寄存器用于屏蔽某些中断

中断触发→SUBSRCPND相应位置1INTSUBMSK未屏蔽→SRCPND相应位置1

                                                           

                                                      中断触发

→若是FIQ中断:INTMOD相应位置1(同一时间,只能有一位置1

INTMSK未屏蔽→INTPND相应位置1(同一时间,只能有一位置1

读取INTPNDINTOFFSET可以确定中断源

清除中断的顺序:SUBSRCPND(相应位写1)→SRCPND(相应位写1)→INTPND

自己觉得重要的几步:将相应引脚的功能设置为“外部中断”,设置中断触发条件,开启外设自己的屏蔽寄存器(若有)→INTSUBMSK中相应位设为0FIQINTMOD相应位设为1

                                                     IRQPRIORITY设置优先级

IRQINTMSK相应位设为0CPSR中的IF位设为0,使能IRQFIQ

中断控制寄存器

1SUBSRCPND中几位若有一位置位,且未被INTSUBMSK屏蔽,则SRCPND中相应有一位置1(多对1的关系)

2INTMOD中设为1的为快速中断,设为0的为普通中断

3PRIORITY:中断优先级仲裁器6个输入引脚;PRIORITY中三位控制一个中断优先级仲裁器(总共7个),一位为ARB_MODE(仲裁器工作模式位),两位用于控制输入信号的优先级

具体哪位对应哪位:请查看S3C2440官方手册,上面写的很详细

4INTOFFSETINTPND寄存器位[x]1时,INTOFFSET寄存器的值为x,在清除SRCPNDINTPND时,INTOFFSET自动清除

外部中断实验:(实验用板:mini2440,是S3C2440的处理器,再参照原理图即可作相应调整)

1head.S



  1. @******************************************************************************
  2. @ File:head.S
  3. @ 功能:初始化,设置中断模式、系统模式的栈,设置好中断处理函数
  4. @******************************************************************************
  5. .extern main @引用其它文件中的mian标号
  6. .text
  7. .global _start
  8. _start:
  9. @******************************************************************************
  10. @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用
  11. @******************************************************************************
  12. b Reset
  13. @ 0x04: 未定义指令中止模式的向量地址
  14. HandleUndef:
  15. b HandleUndef
  16. @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
  17. HandleSWI:
  18. b HandleSWI
  19. @ 0x0c: 指令预取终止导致的异常的向量地址
  20. HandlePrefetchAbort:
  21. b HandlePrefetchAbort
  22. @ 0x10: 数据访问终止导致的异常的向量地址
  23. HandleDataAbort:
  24. b HandleDataAbort
  25. @ 0x14: 保留
  26. HandleNotUsed:
  27. b HandleNotUsed
  28. @ 0x18: 中断模式的向量地址
  29. b HandleIRQ
  30. @ 0x1c: 快中断模式的向量地址
  31. HandleFIQ:
  32. b HandleFIQ
  33. Reset:
  34. ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
  35. bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
  36. msr cpsr_c, #0xd2 @ 进入中断模式
  37. ldr sp, =3072 @ 设置中断模式栈指针
  38. msr cpsr_c, #0xdf @ 进入系统模式
  39. ldr sp, =4096 @ 设置系统模式栈指针,
  40. @ 其实复位之后,CPU就处于系统模式,
  41. @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略
  42. bl init_led @ 初始化LED的GPIO管脚
  43. bl init_irq @ 调用中断初始化函数,在init.c中
  44. msr cpsr_c, #0x5f @ 设置I-bit=0,开IRQ中断
  45. ldr lr, =halt_loop @ 设置返回地址
  46. ldr pc, =main @ 调用main函数
  47. halt_loop:
  48. b halt_loop
  49. HandleIRQ:
  50. sub lr, lr, #4 @ 计算返回地址
  51. stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器
  52. @ 注意,此时的sp是中断模式的sp
  53. @ 初始值是上面设置的3072
  54. ldr lr, =int_return @ 设置调用ISR即EINT_Handle函数后的返回地址
  55. ldr pc, =EINT_Handle @ 调用中断服务函数,在interrupt.c中
  56. int_return:
  57. ldmia sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr


   

(2)init.c


  1. /*
  2.  * init.c: 进行一些初始化
  3.  */
  4.  
  5. #include "s3c24xx.h"
  6.  
  7. /*
  8.  * LED1-4对应GPB5、GPB6、GPB7、GPB8
  9.  */
  10. #define GPB5_out (1<<(5*2)) // LED1
  11. #define GPB6_out (1<<(6*2)) // LED2
  12. #define GPB7_out (1<<(7*2)) // LED3
  13. #define GPB8_out (1<<(8*2)) // LED4
  14.  
  15. /*
  16.  * K1-K4对应GPG0、GPG3、GPG5、GPG6
  17.  */
  18. #define GPG0_eint (2<<0) // K1,EINT8
  19. #define GPG3_eint (2<<(3*2)) // K2,EINT11
  20. #define GPG5_eint (2<<(5*2)) // K3,EINT13
  21. #define GPG6_eint (2<<(6*2)) // K4,EINT14
  22.  
  23.  
  24. /*
  25.  * 关闭WATCHDOG,否则CPU会不断重启
  26.  */
  27. void disable_watch_dog(void)
  28. {
  29.     WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可
  30. }
  31.  
  32. void init_led(void)
  33. {
  34.     GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ;
  35. }
  36.  
  37. /*
  38.  * 初始化GPIO引脚为外部中断
  39.  * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)
  40.  */
  41. void init_irq( )
  42. {
  43.  
  44.     GPGCON = GPG0_eint | GPG3_eint |GPG5_eint | GPG6_eint;
  45.  
  46.    //使能EINT8 EINT11 EINT13 EINT14
  47.     EINTMASK&=(~(1<<8)) & (~(1<<11)) & (~(1<<13)) & (~(1<<14));
  48.  
  49.    //EINT8 EINT11 EINT13 EINT14中断优先级一样,无需设置
  50.  
  51.     // EINT8、EINT11、EINT13、EINT14使能
  52.     INTMSK &=(~(1<<5));
  53. }


(3)interrupt.c


  1. #include "s3c24xx.h"
  2.  
  3. void EINT_Handle()
  4. {
  5.     unsigned long oft = INTOFFSET;
  6.     unsigned long val;
  7.    
  8.     if( oft==5)
  9.         {
  10.             GPBDAT |= (0x0f<<5); // 所有LED熄灭
  11.            
  12.             // 需要进一步判断是K1还是K2,或是K1、K2被同时按下
  13.             val = EINTPEND;
  14.             if (val & (1<<8))
  15.                 GPBDAT &= ~(1<<5); // K1被按下,LED1点亮
  16.             if (val & (1<<11))
  17.                 GPBDAT &= ~(1<<6); // K2被按下,LED2点亮
  18.          if (val & (1<<13))
  19.                 GPBDAT &= ~(1<<7); // K3被按下,LED3点亮
  20.             if (val & (1<<14))
  21.                 GPBDAT &= ~(1<<8); // K4被按下,LED4点亮
  22.         }
  23.  
  24.     //清中断
  25.     if( oft == 5 )
  26.     EINTPEND = (1<<8) | (1<<11)| (1<<13)| (1<<14); // EINT8_23合用IRQ5
  27.     SRCPND = 1<<oft;
  28.     INTPND = 1<<oft;
  29. }


资料:http://blogold.chinaunix.net/u3/101744/showart_2025311.html

阅读(1714) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~