Mini2440 裸机实验之LED程序、按键、中断
2013-05-28 16:18
393 查看
测试平台:Mini2440 Win7 64 ADS开发环境测试
此程序主要考虑按键、LED点亮、中断模式(IRQ)之间的联系
以下为main.c代码部分,其他请参考三星提供的2440用例代码
LED点亮步骤(以MIni2440为参考,其他请看手册说明)
1.初始化LED配置的引脚,如mini2440 led1-》GPB5 每一个器件都有一个或者多个管脚进行驱动控制,就是设置GPBCON引脚5(两位为一个控制单位,应该是【11:10】)
2.直接点亮,还是管脚,这里有谁驱动它发光亮起来呢??就是GPBDAT,led1引脚5,此时为1位控制,即是【5】=0(低电平有效的情况下),就能驱动发亮
对于按键来说其实是一样的,只不过连接的针脚不一样,这时候参考手册就可以知道key-》GPG,然后这些针脚对应了相应的中断,当我们不使用中断控制的情况下,这时候需要读取GPGDAT的值,然后与相应的key对应的键位值进行&即可判断哪个按键被按下了,方法同上因为都是GPIO
中断控制(IRQ,非快速中断模式FIQ)
对于如何设置堆栈sp,pc....如何调转到快速中断,怎么恢复CPSR等等,暂且不谈,先看中断顺序
1. 首先要初始化中断,清除当前要中断的位,设置当前中断的位,使能当前中断,
如: 按键key1-》EINT8-》GPG0,仍然是GPIO,还是前面的方法,因为这个中断属于二级仲裁器1中的REQ1/EINT8_23,
所以还要设置EINTPEND用以判断到底是哪一个中断,先清除如key1: rEINTPEND |= (1<<8)。还得保证不被屏蔽mask位就要设为0,才是应为EINTMASK对应的位,查手册即可;
这里使用默认低电平触发方式,如果要设置电平方式,设置EXTINT1即可,额外设置的寄存器EXTINT0不能使用,请参看手册;
设置中断先后顺序,这里两个中断同级,并没有设置,如需请设置PRIORITY
2. 设置中断处理函数,先将中断处理函数映射到相应的中断地址去,本例就是key_handler
3. 接下来就可以使能相应中断了,如key1 INMASK &= (~(1<<5) )即可,本例调用三星的库函数EnableIrq(BIT_EINT8_23);使能中断
4. 处理中断,在主函数里面是一个无止境的循环,当有中断发生,即转到中断处理函数
注:1)处理函数之前就是使用了一个循环导致不能退出,也不能相应下一个中断
2)蜂鸣中断处理函数,屏蔽蜂鸣不能使用rGPBDAT &=(0x0<<0);此时LED会全部亮起来,因为此时我只想测试蜂鸣,最好采用rGPBDAT &= ~(0x1<<0);
尤其LED部分,我调试了走马灯,各灯分别亮起,0-15循环亮起的LED实例,注销部分注释即可测试,以及未修改成功的显示0-15测试用例
此程序主要考虑按键、LED点亮、中断模式(IRQ)之间的联系
以下为main.c代码部分,其他请参考三星提供的2440用例代码
#define GLOBAL_CLK 1 #include<stdlib.h> #include<string.h> #include"def.h" #include"option.h" #include"2440addr.h" #include"2440lib.h" #include"2440slib.h" #include "mmu.h" #include "profile.h" #include "memtest.h" //led灯测试程序 void led_init(void); void led_close(void); void led_run(void); void disp_num(int data); void led_disp_num(int data); //按键中断程序 void key_init(void); static void __irq key_handler(void); void beep_init(void); void beep_run(void); #define LED1_ON ~(1<<5) #define LED2_ON ~(1<<6) #define LED3_ON ~(1<<7) #define LED4_ON ~(1<<8) #define LED1_OFF (1<<5) #define LED2_OFF (1<<6) #define LED3_OFF (1<<7) #define LED4_OFF (1<<8) /******延时函数******/ void delay(int n_times) { int i; for( ;n_times>0;n_times--) for(i=0;i<400;i++) ; } /*****运行主函数*****/ void Main(void) { int i=0; led_init(); //实现led灯递增亮起 //led_run(); /* //实现led灯以二进制方式显示0-15 while(i<16) { //disp_num(i++); led_disp_num(i++); delay(5000); if(i==16) { i = 0; } } */ //按键测试中断 beep_init(); MMU_Init(); key_init(); while(1) { ; //beep_run(); } } /*******对LED引脚进行初始化*******/ void led_init(void) { //每一个引脚设为输出端口,初始化为01 rGPBCON &= ~( (1<<2*5+1)|(1<<2*6+1)|(1<<2*7+1)|(1<<2*8+1) ); //rGPBCON..... } /*******关闭所有的led灯*******/ void led_close(void) { rGPBDAT |= (LED1_OFF)|(LED2_OFF)|(LED3_OFF)|(LED4_OFF); //rGPBDAT &= 0xFFFFFF0F; } /********mini2440开发板有4个引脚连接了LED发光二极管,该函数实现了流水灯*******/ void led_run(void) { int i=0; //int arr_led_on[4]={LED1_ON,LED2_ON,LED2_ON,LED2_ON}; //led_close(); led_close(); rGPBDAT &= ~(1<<5); delay(10000); /* while(1) { //第一种递增跑马灯 1000-》0100-》0010-》0001-》1000... led_close(); rGPBDAT &= ~(1<<i+5); delay(50000); if( ++i == 4 ) { i = 0; } //第二种递增亮起 1000-》1100-》1110-》1111-》0000... rGPBDAT &= ~(i<<5); delay(5000); if( ++i == 16) { led_close(); i = 0; } */ //} } /********显示0000~1111数字********/ void disp_num(int data) { if(data&0x08) rGPBDAT &= LED4_ON; else rGPBDAT |= LED4_OFF; if(data&0x04) rGPBDAT &= LED3_ON; else rGPBDAT |= LED3_OFF; if(data&0x02) rGPBDAT &= LED2_ON; else rGPBDAT |= LED2_OFF; if(data&0x01) rGPBDAT &= LED1_ON; else rGPBDAT |= LED1_OFF; } /********显示0000~1111数字********/ void led_disp_num(int data) { int i = 3; for(; i>=0; i++) { //if( data & ((int)pow(2,i)) ) //肯定非0都为真 if( data & 0x0f) { delay(1000); rGPBDAT &= ~(1<<8-i); } else { rGPBDAT &= (1<<8-i); } } } /*******按键key1的初始化函数********/ void key_init(void) { //rGPGCON &= ~(0<<2*0+1); rGPGCON &= (~(0x3<<0))&(~(0x3<<2*3)); rGPGCON |= (0x2<<0)|(0x2<<2*3); //10特殊功能 //rEXTINT1 &= ~(0xf<<0);//0000 EINIT8 开启低电平 过滤关闭 rEINTPEND |= (1<<8)|(1<<11); //清除之前的中断 rEINTMASK &= (~(1<<8))&(~(1<<11));//中断不被屏蔽 pISR_EINT8_23 = (U32) key_handler; EnableIrq(BIT_EINT8_23); } /*******key1的中断服务程序*******/ static void __irq key_handler(void) { if( rINTPND == BIT_EINT8_23) { ClearPending(BIT_EINT8_23); if( rEINTPEND&(1<<8) ) { led_close(); rEINTPEND |= 1<<8; beep_run(); } if( rEINTPEND&(1<<11) ) { rEINTPEND |= 1<<11; led_run(); } //ClearPending(BIT_EINT8_23); } } /***********初始化蜂鸣器***********/ void beep_init(void) { rGPBCON &= ~(0x3<<0); rGPBCON |= 0x1<<0;//初始化为输出端 } /*********运行蜂鸣器*********/ void beep_run(void) { rGPBDAT |= 0x1<<0; delay(1000); rGPBDAT &= ~(0x1<<0); delay(1000); }
LED点亮步骤(以MIni2440为参考,其他请看手册说明)
1.初始化LED配置的引脚,如mini2440 led1-》GPB5 每一个器件都有一个或者多个管脚进行驱动控制,就是设置GPBCON引脚5(两位为一个控制单位,应该是【11:10】)
2.直接点亮,还是管脚,这里有谁驱动它发光亮起来呢??就是GPBDAT,led1引脚5,此时为1位控制,即是【5】=0(低电平有效的情况下),就能驱动发亮
对于按键来说其实是一样的,只不过连接的针脚不一样,这时候参考手册就可以知道key-》GPG,然后这些针脚对应了相应的中断,当我们不使用中断控制的情况下,这时候需要读取GPGDAT的值,然后与相应的key对应的键位值进行&即可判断哪个按键被按下了,方法同上因为都是GPIO
中断控制(IRQ,非快速中断模式FIQ)
对于如何设置堆栈sp,pc....如何调转到快速中断,怎么恢复CPSR等等,暂且不谈,先看中断顺序
1. 首先要初始化中断,清除当前要中断的位,设置当前中断的位,使能当前中断,
如: 按键key1-》EINT8-》GPG0,仍然是GPIO,还是前面的方法,因为这个中断属于二级仲裁器1中的REQ1/EINT8_23,
所以还要设置EINTPEND用以判断到底是哪一个中断,先清除如key1: rEINTPEND |= (1<<8)。还得保证不被屏蔽mask位就要设为0,才是应为EINTMASK对应的位,查手册即可;
这里使用默认低电平触发方式,如果要设置电平方式,设置EXTINT1即可,额外设置的寄存器EXTINT0不能使用,请参看手册;
设置中断先后顺序,这里两个中断同级,并没有设置,如需请设置PRIORITY
2. 设置中断处理函数,先将中断处理函数映射到相应的中断地址去,本例就是key_handler
3. 接下来就可以使能相应中断了,如key1 INMASK &= (~(1<<5) )即可,本例调用三星的库函数EnableIrq(BIT_EINT8_23);使能中断
4. 处理中断,在主函数里面是一个无止境的循环,当有中断发生,即转到中断处理函数
注:1)处理函数之前就是使用了一个循环导致不能退出,也不能相应下一个中断
2)蜂鸣中断处理函数,屏蔽蜂鸣不能使用rGPBDAT &=(0x0<<0);此时LED会全部亮起来,因为此时我只想测试蜂鸣,最好采用rGPBDAT &= ~(0x1<<0);
尤其LED部分,我调试了走马灯,各灯分别亮起,0-15循环亮起的LED实例,注销部分注释即可测试,以及未修改成功的显示0-15测试用例
相关文章推荐
- 关于mini2440的一个裸机程序——LED与按键中断
- 关于mini2440的一个裸机程序——LED与按键中断
- 基于mini2440的按键中断控制LED(裸机代码)
- 二、mini2440裸机程序之按键检测实验
- mini2440 按键中断LED 实验
- 六、mini2440裸机程序之中断控制器(2)外部按键中断
- 4412裸机程序之按键控制LED
- 裸机程序按键中断问题,求解
- mini2440裸机程序--LED灯(C语言)
- 五、mini2440裸机程序之nand flash控制器实验
- ARM开发板mini2440的按键控制LED小程序
- 七、mini2440裸机程序之定时器中断(2)时钟相关寄存器配置
- 从ARM裸机看驱动之按键中断方式控制LED(二)
- mini2440(2) LED灯裸机硬件控制程序
- Mkefile文件编写及点亮两个led的mini2440裸机程序
- 按键中断---那些年我们一起玩mini2440(arm9)裸机
- mini2440裸机程序--完善点亮LED(c…
- Tiny6410按键轮询方式控制LED的SD卡启动裸机程序
- 七、mini2440裸机程序之定时器中断(3)定时器简介
- Mini 2440 LED、按键和蜂鸣器裸机测试程序(C语言)