请问各位大神,为什么在使用附件中的裸机程序在S3C2440A开发板上测试时,会出现虽然按键按下对应LED会点亮其余熄灭,但是按键抬起LED会全部恢复硬件初始状态(LED1-LED3自动全量)的现象,而不是保持对应LED常亮而其他熄灭的状态呢?(既然GPFDAT在中断服务程序中被赋值,后边又没有清除过,怎么会自己改变LED状态呢?)百思不得解,希望各位大神帮忙给出解释,万分感激!
-
-
TEST.rar
下载积分: 积分 -1 分
3.1 KB, 下载次数: 8, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
- @******************************************************************************
- @ File:head.S
- @ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数
- @******************************************************************************
- .extern main
- .text
- .global _start
- _start:
- @******************************************************************************
- @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用
- @******************************************************************************
- b Reset
- @ 0x04: 未定义指令中止模式的向量地址
- HandleUndef:
- b HandleUndef
-
- @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
- HandleSWI:
- b HandleSWI
- @ 0x0c: 指令预取终止导致的异常的向量地址
- HandlePrefetchAbort:
- b HandlePrefetchAbort
- @ 0x10: 数据访问终止导致的异常的向量地址
- HandleDataAbort:
- b HandleDataAbort
- @ 0x14: 保留
- HandleNotUsed:
- b HandleNotUsed
- @ 0x18: 中断模式的向量地址
- b HandleIRQ
- @ 0x1c: 快中断模式的向量地址
- HandleFIQ:
- b HandleFIQ
- Reset:
- ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
- bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
-
- msr cpsr_c, #0xd2 @ 进入中断模式
- ldr sp, =3072 @ 设置中断模式栈指针
- msr cpsr_c, #0xd3 @ 进入管理模式
- ldr sp, =4096 @ 设置管理模式栈指针,
- @ 其实复位之后,CPU就处于管理模式,
- @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略
- bl init_led @ 初始化LED的GPIO管脚
- bl init_irq @ 调用中断初始化函数,在init.c中
- msr cpsr_c, #0x5f @ 设置I-bit=0,开IRQ中断
-
- ldr lr, =halt_loop @ 设置返回地址
- ldr pc, =main @ 调用main函数
-
- halt_loop:
- b halt_loop
- HandleIRQ:
- sub lr, lr,#4 @ 计算返回地址
- stmfd sp!, { r0-r12,lr } @ 保存使用到的寄存器
- @ 注意,此时的sp是中断模式的sp
- @ 初始值是上面设置的3072
-
- ldr lr, =int_return @ 设置调用ISR即EINT_Handle函数后的返回地址
- ldr pc, =EINT_Handle @ 调用中断服务函数,在interrupt.c中
- int_return:
- ldmfd sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr
-
- /******************************
- /*
- * init.c: 进行一些初始化,初始化函数定义文件
- */
- #include "s3c24xx.h"
- /*
- * LED1,LED2,LED4对应GPF0、GPF1、GPF2
- */
- #define GPF0_out (0x1<<(0*2))
- #define GPF1_out (0x1<<(1*2))
- #define GPF2_out (0x1<<(2*2))
- #define GPF0_msk (3<<(0*2))
- #define GPF1_msk (3<<(1*2))
- #define GPF2_msk (3<<(2*2))
- /*
- * S1,S2,S3对应GPF4、GPF5、GPG6
- */
- #define GPF4_eint (0x2<<(4*2))
- #define GPF5_eint (0x2<<(5*2))
- #define GPF6_eint (0x2<<(6*2))
- #define GPF4_msk (3<<(4*2))
- #define GPF5_msk (3<<(5*2))
- #define GPF6_msk (3<<(6*2))
- /*
- * 关闭WATCHDOG,否则CPU会不断重启
- */
- void disable_watch_dog(void)
- {
- WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可
- }
- void init_led(void)
- {
- // LED1,LED2,LED3对应的3根引脚设为输出
- GPFCON &= ~(GPF0_msk | GPF1_msk | GPF2_msk);
- GPFCON |= GPF0_out | GPF1_out | GPF2_out;
- GPFDAT = 0xf0;
- GPFUP = 0x00;
- }
- /*
- * 初始化GPIO引脚为外部中断
- * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)
- */
- void init_irq( )
- {
- // S1,S2,S3对应的3根引脚设为中断引脚 EINT4,EINT5,EINT6
- GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
- GPFCON |= GPF4_eint | GPF5_eint | GPF6_eint;
- // S4对应的引脚设为中断引脚EINT11
- //GPFCON &= ~GPF3_msk;
- //GPFCON |= GPF3_eint;
-
- // 对于EINT11,需要在EINTMASK寄存器中使能它
- //EINTMASK &= ~(1<<11);
-
- /*
- * 设定优先级:
- * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2
- * 仲裁器1、6无需设置
- * 最终:
- * EINT0 > EINT2 > EINT11即K2 > K3 > K4
- */
- //PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;
- // EINT4_7使能
- EINTMASK &= ~((1<<4)|(1<<5)|(1<<6));
- INTMSK &= (~(1<<4));
- }
- /*******************************
- /interrupt.c中断处理文件
- #include "s3c24xx.h"
- void EINT_Handle()
- {
- unsigned long oft = INTOFFSET;
-
- if( oft==4 )
- {
- SRCPND = 1<<oft;
- INTPND = 1<<oft;
- // S1被按下
- if(EINTPEND&(1<<4))
- {
- //GPFDAT |= (0x7<<0); // 所有LED熄灭
- //GPFDAT &= ~(1<<0); // LED1点亮
- GPFDAT = 0xfe;
- EINTPEND |= (1<<4);
- }
-
- // S2被按下
- if(EINTPEND&(1<<5))
- {
- GPFDAT |= (0x7<<0); // 所有LED熄灭
- GPFDAT &= ~(1<<1); // LED2点亮
- EINTPEND |= (1<<5);
- }
- // S3被按下
- if(EINTPEND&(1<<6))
- {
- GPFDAT |= (0x7<<0); // 所有LED熄灭
- GPFDAT &= ~(1<<2); // LED4点亮
- EINTPEND |= (1<<6);
- }
- }
- }
- /**************************************************************************************
- /**main.c文件
- int main()
- {
- while(1);
- return 0;
- }
- /***************************************************************************************
- /***寄存器定义文件
- /* WOTCH DOG register */
- #define WTCON (*(volatile unsigned long *)0x53000000)
- /* SDRAM regisers */
- #define MEM_CTL_BASE 0x48000000
- #define SDRAM_BASE 0x30000000
- /* NAND Flash registers */
- #define NFCONF (*(volatile unsigned int *)0x4e000000)
- #define NFCMD (*(volatile unsigned char *)0x4e000004)
- #define NFADDR (*(volatile unsigned char *)0x4e000008)
- #define NFDATA (*(volatile unsigned char *)0x4e00000c)
- #define NFSTAT (*(volatile unsigned char *)0x4e000010)
- /*GPIO registers*/
- #define GPBCON (*(volatile unsigned long *)0x56000010)
- #define GPBDAT (*(volatile unsigned long *)0x56000014)
- #define GPFCON (*(volatile unsigned long *)0x56000050)
- #define GPFDAT (*(volatile unsigned long *)0x56000054)
- #define GPFUP (*(volatile unsigned long *)0x56000058)
- #define GPGCON (*(volatile unsigned long *)0x56000060)
- #define GPGDAT (*(volatile unsigned long *)0x56000064)
- #define GPGUP (*(volatile unsigned long *)0x56000068)
- #define GPHCON (*(volatile unsigned long *)0x56000070)
- #define GPHDAT (*(volatile unsigned long *)0x56000074)
- #define GPHUP (*(volatile unsigned long *)0x56000078)
- /*UART registers*/
- #define ULCON0 (*(volatile unsigned long *)0x50000000)
- #define UCON0 (*(volatile unsigned long *)0x50000004)
- #define UFCON0 (*(volatile unsigned long *)0x50000008)
- #define UMCON0 (*(volatile unsigned long *)0x5000000c)
- #define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
- #define UTXH0 (*(volatile unsigned char *)0x50000020)
- #define URXH0 (*(volatile unsigned char *)0x50000024)
- #define UBRDIV0 (*(volatile unsigned long *)0x50000028)
- /*interrupt registes*/
- #define SRCPND (*(volatile unsigned long *)0x4A000000)
- #define INTMOD (*(volatile unsigned long *)0x4A000004)
- #define INTMSK (*(volatile unsigned long *)0x4A000008)
- #define PRIORITY (*(volatile unsigned long *)0x4A00000c)
- #define INTPND (*(volatile unsigned long *)0x4A000010)
- #define INTOFFSET (*(volatile unsigned long *)0x4A000014)
- #define SUBSRCPND (*(volatile unsigned long *)0x4A000018)
- #define INTSUBMSK (*(volatile unsigned long *)0x4A00001c)
- /*external interrupt registers*/
- #define EINTMASK (*(volatile unsigned long *)0x560000a4)
- #define EINTPEND (*(volatile unsigned long *)0x560000a8)
复制代码一周热门 更多>