!!!求各位大神点进来,帮我解释一下这个关于用中断控制LED灯亮灭出现的异常现象,万分感激!!!

2019-07-16 08:09发布

   请问各位大神,为什么在使用附件中的裸机程序在S3C2440A开发板上测试时,会出现虽然按键按下对应LED会点亮其余熄灭,但是按键抬起LED会全部恢复硬件初始状态(LED1-LED3自动全量)的现象,而不是保持对应LED常亮而其他熄灭的状态呢?(既然GPFDAT在中断服务程序中被赋值,后边又没有清除过,怎么会自己改变LED状态呢?)百思不得解,希望各位大神帮忙给出解释,万分感激!
TEST.rar 下载积分: 积分 -1 分
3.1 KB, 下载次数: 8, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
13条回答
liber_man
2019-07-17 14:41
houjue 发表于 2017-4-10 02:27
你都懒得贴上来,我为啥不能懒得看呢?!
  1. @******************************************************************************
  2. @ File:head.S
  3. @ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数
  4. @******************************************************************************      
  5. .extern     main
  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.    
  37.     msr cpsr_c, #0xd2       @ 进入中断模式
  38.     ldr sp, =3072           @ 设置中断模式栈指针

  39.     msr cpsr_c, #0xd3       @ 进入管理模式
  40.     ldr sp, =4096           @ 设置管理模式栈指针,
  41.                             @ 其实复位之后,CPU就处于管理模式,
  42.                             @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略

  43.     bl  init_led            @ 初始化LED的GPIO管脚
  44.     bl  init_irq            @ 调用中断初始化函数,在init.c中
  45.     msr cpsr_c, #0x5f       @ 设置I-bit=0,开IRQ中断
  46.    
  47.     ldr lr, =halt_loop      @ 设置返回地址
  48.     ldr pc, =main           @ 调用main函数
  49.        
  50. halt_loop:
  51.     b   halt_loop

  52. HandleIRQ:
  53.     sub lr, lr,#4                   @ 计算返回地址

  54.     stmfd   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器
  55.                                     @ 注意,此时的sp是中断模式的sp
  56.                                     @ 初始值是上面设置的3072
  57.    
  58.     ldr lr, =int_return             @ 设置调用ISR即EINT_Handle函数后的返回地址  
  59.     ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中
  60. int_return:
  61.     ldmfd   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr
  62.    
  63. /******************************
  64. /*
  65. * init.c: 进行一些初始化,初始化函数定义文件
  66. */

  67. #include "s3c24xx.h"

  68. /*
  69. * LED1,LED2,LED4对应GPF0、GPF1、GPF2
  70. */
  71. #define        GPF0_out        (0x1<<(0*2))
  72. #define        GPF1_out        (0x1<<(1*2))
  73. #define        GPF2_out        (0x1<<(2*2))

  74. #define        GPF0_msk        (3<<(0*2))
  75. #define        GPF1_msk        (3<<(1*2))
  76. #define        GPF2_msk        (3<<(2*2))

  77. /*
  78. * S1,S2,S3对应GPF4、GPF5、GPG6
  79. */
  80. #define GPF4_eint    (0x2<<(4*2))
  81. #define GPF5_eint     (0x2<<(5*2))
  82. #define GPF6_eint     (0x2<<(6*2))

  83. #define GPF4_msk    (3<<(4*2))
  84. #define GPF5_msk    (3<<(5*2))
  85. #define GPF6_msk    (3<<(6*2))

  86. /*
  87. * 关闭WATCHDOG,否则CPU会不断重启
  88. */
  89. void disable_watch_dog(void)
  90. {
  91.     WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可
  92. }

  93. void init_led(void)
  94. {
  95.     // LED1,LED2,LED3对应的3根引脚设为输出
  96.     GPFCON &= ~(GPF0_msk | GPF1_msk | GPF2_msk);
  97.     GPFCON |= GPF0_out | GPF1_out | GPF2_out;
  98.     GPFDAT = 0xf0;
  99.     GPFUP = 0x00;
  100. }

  101. /*
  102. * 初始化GPIO引脚为外部中断
  103. * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)
  104. */
  105. void init_irq( )
  106. {
  107.     // S1,S2,S3对应的3根引脚设为中断引脚 EINT4,EINT5,EINT6
  108.     GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
  109.     GPFCON |= GPF4_eint | GPF5_eint | GPF6_eint;

  110.     // S4对应的引脚设为中断引脚EINT11
  111.     //GPFCON &= ~GPF3_msk;
  112.     //GPFCON |= GPF3_eint;
  113.    
  114.     // 对于EINT11,需要在EINTMASK寄存器中使能它
  115.     //EINTMASK &= ~(1<<11);
  116.         
  117.     /*
  118.      * 设定优先级:
  119.      * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2
  120.      * 仲裁器1、6无需设置
  121.      * 最终:
  122.      * EINT0 > EINT2 > EINT11即K2 > K3 > K4
  123.      */
  124.     //PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;

  125.     // EINT4_7使能
  126.     EINTMASK &= ~((1<<4)|(1<<5)|(1<<6));
  127.     INTMSK   &= (~(1<<4));
  128. }

  129. /*******************************
  130. /interrupt.c中断处理文件

  131. #include "s3c24xx.h"

  132. void EINT_Handle()
  133. {
  134.     unsigned long oft = INTOFFSET;
  135.    
  136.     if( oft==4 )
  137.     {
  138.         SRCPND = 1<<oft;
  139.         INTPND = 1<<oft;
  140.         // S1被按下
  141.         if(EINTPEND&(1<<4))
  142.         {   
  143.             //GPFDAT |= (0x7<<0);   // 所有LED熄灭
  144.             //GPFDAT &= ~(1<<0);      // LED1点亮
  145.                         GPFDAT = 0xfe;
  146.             EINTPEND |= (1<<4);
  147.         }
  148.         
  149.         // S2被按下
  150.         if(EINTPEND&(1<<5))
  151.         {   
  152.             GPFDAT |= (0x7<<0);   // 所有LED熄灭
  153.             GPFDAT &= ~(1<<1);      // LED2点亮
  154.             EINTPEND |= (1<<5);
  155.         }

  156.         // S3被按下
  157.         if(EINTPEND&(1<<6))
  158.         {   
  159.             GPFDAT |= (0x7<<0);   // 所有LED熄灭
  160.             GPFDAT &= ~(1<<2);      // LED4点亮               
  161.             EINTPEND |= (1<<6);
  162.         }

  163.     }

  164. }
  165. /**************************************************************************************
  166. /**main.c文件
  167. int main()
  168. {   

  169.     while(1);
  170.     return 0;
  171. }
  172. /***************************************************************************************
  173. /***寄存器定义文件
  174. /* WOTCH DOG register */
  175. #define     WTCON           (*(volatile unsigned long *)0x53000000)

  176. /* SDRAM regisers */
  177. #define     MEM_CTL_BASE    0x48000000
  178. #define     SDRAM_BASE      0x30000000

  179. /* NAND Flash registers */
  180. #define NFCONF              (*(volatile unsigned int  *)0x4e000000)
  181. #define NFCMD               (*(volatile unsigned char *)0x4e000004)
  182. #define NFADDR              (*(volatile unsigned char *)0x4e000008)
  183. #define NFDATA              (*(volatile unsigned char *)0x4e00000c)
  184. #define NFSTAT              (*(volatile unsigned char *)0x4e000010)

  185. /*GPIO registers*/
  186. #define GPBCON              (*(volatile unsigned long *)0x56000010)
  187. #define GPBDAT              (*(volatile unsigned long *)0x56000014)

  188. #define GPFCON              (*(volatile unsigned long *)0x56000050)
  189. #define GPFDAT              (*(volatile unsigned long *)0x56000054)
  190. #define GPFUP               (*(volatile unsigned long *)0x56000058)

  191. #define GPGCON              (*(volatile unsigned long *)0x56000060)
  192. #define GPGDAT              (*(volatile unsigned long *)0x56000064)
  193. #define GPGUP               (*(volatile unsigned long *)0x56000068)

  194. #define GPHCON              (*(volatile unsigned long *)0x56000070)
  195. #define GPHDAT              (*(volatile unsigned long *)0x56000074)
  196. #define GPHUP               (*(volatile unsigned long *)0x56000078)



  197. /*UART registers*/
  198. #define ULCON0              (*(volatile unsigned long *)0x50000000)
  199. #define UCON0               (*(volatile unsigned long *)0x50000004)
  200. #define UFCON0              (*(volatile unsigned long *)0x50000008)
  201. #define UMCON0              (*(volatile unsigned long *)0x5000000c)
  202. #define UTRSTAT0            (*(volatile unsigned long *)0x50000010)
  203. #define UTXH0               (*(volatile unsigned char *)0x50000020)
  204. #define URXH0               (*(volatile unsigned char *)0x50000024)
  205. #define UBRDIV0             (*(volatile unsigned long *)0x50000028)


  206. /*interrupt registes*/
  207. #define SRCPND              (*(volatile unsigned long *)0x4A000000)
  208. #define INTMOD              (*(volatile unsigned long *)0x4A000004)
  209. #define INTMSK              (*(volatile unsigned long *)0x4A000008)
  210. #define PRIORITY            (*(volatile unsigned long *)0x4A00000c)
  211. #define INTPND              (*(volatile unsigned long *)0x4A000010)
  212. #define INTOFFSET           (*(volatile unsigned long *)0x4A000014)
  213. #define SUBSRCPND           (*(volatile unsigned long *)0x4A000018)
  214. #define INTSUBMSK           (*(volatile unsigned long *)0x4A00001c)

  215. /*external interrupt registers*/
  216. #define EINTMASK            (*(volatile unsigned long *)0x560000a4)
  217. #define EINTPEND            (*(volatile unsigned long *)0x560000a8)






复制代码

一周热门 更多>