转帖: http://www.oschina.net/question/565065_115196?sort=time

实验目的: mini2440开发板上有6个按键,将其中的前4个按键设为外部中断方式,当按下K1时,LED1亮;当按下K2时,LED2亮;当按下K3时,LED3亮;当按下K4时,LED4亮。

首先我们先了解一下 mini2440 按键和LED接口:

   

GPBCON 地址: 0x56000010 (LED 灯可以参考流水灯的随笔)

GPGCON 地址: 0x56000060

图画错了,应该是 输入模式 input ,而不是 EINT

要将 GPG 0 3 5 6 7 11 设为 输入功能的话, 那么 但是由于主要考虑的是 K1 k2 K3 K4 所以只要这几个 为输入模式 就行了

19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
            0 0 0 0     0 0         0 0
            input   input       input           input  
            K4   K3       K2           K1  
            GPG6   GPG5       GPG3           GPG0  

按键接口电路如图2所示,当按键没有按下时,GPGx引脚为高电平;当按键按下时,引脚电平变为低电平。

外部中断文件布局:

该工程有三个模块组成。

按键模块主要包含 button.c 和  button.h

LED模块包含led.c和led.h。

中断处理模块主要包含     interrupt.c、interrupt.h、isrservice.c和isrservice.h文件。其中,interrupt.h和interrupt.c文件主要包含中断初始化函数,isrservice.c和isrservice.h文件主要包含中断处理函数。

_______________________________________________________________________________________________________________________________________________________________________

main.c 文件

 #include"led.h"
#include"button.h"
#include"isrservice.h"
#include"interrupt.h" int main()
{
Led_Init(); //初始化LED
KeyInt_Init(); //初始化按键
Irq_Init(); //初始化外部中断
while() //循环,等待中断发生
{
;
}
}

————————————————————————————————————————————————————————————————————————————————————————————————————————————————

led.h 文件

 #ifndef __LED_H__
#define __LED_H__ // #include<s3c2440.h> 我们也把它注释掉看看
// 添加以下代码 #define GPBDAT (*(volatile unsigned long *) 0x56000014)
// 添加上面一行就可以运行,而不需要 GPBDAT GPBUP 说明,这里的 void Led_Init()与它无关 #define Led1_On() {GPBDAT&=(~(1<<5));} // 第5位 为 0,按位与,所以 GPBDAT 第五位始终为 0,LED1 也就是 GPB5 灯亮
#define Led1_Off() {GPBDAT|=(1<<5);} // 第5位为 1 ,按位或 ,始终为 1 ,灯灭
#define Led2_On() {GPBDAT&=(~(1<<6));}
#define Led2_Off() {GPBDAT|=(1<<6);}
#define Led3_On() {GPBDAT&=(~(1<<7));}
#define Led3_Off() {GPBDAT|=(1<<7);}
#define Led4_On() {GPBDAT&=(~(1<<8));}
#define Led4_Off() {GPBDAT|=(1<<8);}
/****************************************************
* 函数名称:void Led_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:设置GPN5-8为输出功能,初始化4个LED灯灭
*****************************************************/
void Led_Init(void); #endif

led.c 文件

 /****************************************************
* 我的mini2440开发板上4个LED灯对应的GPIO口
* LED1---GPB5 LED2---GPB6
* LED3---GPB7 LED4---GPB8 注意 LED 口 是低电平,亮
*****************************************************/ // #include<s3c2440.h> // 我们也把它注释掉,主要为了练习,添加下面代码,来熟悉C语言
#define GPBCON (*(volatile unsigned long *) 0x56000010)
#define GPBDAT (*(volatile unsigned long *) 0x56000014)
#define GPBUP (*(volatile unsigned long *) 0x56000018) /****************************************************
* 函数名称:void Led_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:设置GPB5-8为输出功能,初始化4个LED灯灭
*****************************************************/ // 自己添加一下 代码 void Led_Init(void)
{ // GPBCON&=~((3<<10)|(3<<12)|(3<<14)|(3<<16));
// GPBCON|=((1<<10)|(1<<12)|(1<<14)|(1<<16));//设置GPB5-8口为输出功能
// GPBUP&=~((1<<5)|(1<<6)|(1<<7)|(1<<8));//上拉电阻使能
// GPBDAT|=(1<<5)|(1<<6)|(1<<7)|(1<<8);//令GPBDAT5-8均为高电平,即令4个led灯全灭 GPBCON=0x0015400; // 设置 GPB5-8 口为输出功能 ,也就是 GPB8--GPB5 为 17-10位为(01 01 01 01)(http://www.cnblogs.com/shengruxiahua/p/4888028.html)
GPBUP&=~((<<)|(<<)|(<<)|(<<));//上拉电阻使能 使得 5-8位 全为0 ,上拉使能
GPBDAT|=( (<<)|(<<)|(<<)|(<<) ); // 5678位,为 1,使用 按位或 运算符,显然可以令GPBDAT5-8均为高电平,即令4个led灯全灭 }

________________________________________________________________________________________________________________________________________________________________________________________________________

button.h 文件

#ifndef __BUTTON_H__
#define __BUTTON_H__ /****************************************************
* 函数名称:void KeyInt_Init()
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:设置GPG0、3、5、6、7、11为外部中断输入功能
*****************************************************/
void KeyInt_Init(void); #endif

button.c 文件

 /************************************************
* mini2440板子上六个按键对应的GPIO和中断
按键 GPIO 中 断
* K1 GPG0 EINT8
* K2 GPG3 EINT11
* K3 GPG5 EINT13
* K4 GPG6 EINT14
* K5 GPG7 EINT15
* K6 GPG11 EINT19
************************************************/
/*
#include<s3c2440.h>
#include"button.h" // 不能理解,为什么要添加 这一个文件 ????????????????????? #define KEY1_C (3<<0) // LED1
#define KEY2_C (3<<6) // LED2
#define KEY3_C (3<<10) // LED3
#define KEY4_C (3<<12) // LED4 #define KEY1 (2<<0)
#define KEY2 (2<<6)
#define KEY3 (2<<10)
#define KEY4 (2<<12) ****************************************************
* 函数名称:void KeyInt_Init()
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:设置GPG0、3、5、6、7、11为外部中断输入功能
*****************************************************/
/*
void KeyInt_Init(void)
{
GPGCON&=~(KEY1_C|KEY2_C|KEY3_C|KEY4_C);
GPGCON|=KEY1|KEY2|KEY3|KEY4; //将GPG0、3、5、6、7、11设为输入功能
GPGUP&=~((1<<0)|(1<<3)|(1<<5)|(1<<6));
GPGDAT|=(1<<0)|(1<<3)|(1<<5)|(1<<6); //因为按下按键后,相应的GPIO口为0,所以初始化为高电平 }
*/ // 我们来自己编写一个 中断
#include<s3c2440.h>
#include"button.h" #define KEY1_C (3<<0) // LED1 也就是把 10 位设为 11
#define KEY2_C (3<<6) // LED2 76 11
#define KEY3_C (3<<10) // LED3 11 10 11
#define KEY4_C (3<<12) // LED4 13 12 11 #define skey ( ~(KEY1_C|KEY2_C|KEY3_C|KEY4_C) ) // 也就是取反 ,也就是13 12 11 10 7 6 10 全为 00 00 00 00
#define Dkey ( (1<<0)|(1<<3)|(1<<5)|(1<<6) ) // 为了后面的 GPG0 3 5 6 位 为 1 1 1 1 void KeyInt_Init(void)
{
GPGCON&=skey; // 那么13 12 11 10 7 6 10 全为 00 00 00 00 ,其他位不变,那么GPG0、3、5、6 初始化为 输入模式
GPGUP&=~((<<)|(<<)|(<<)|(<<)); // 1 3 5 6 位 设为 0 ,上拉电阻
GPGDAT|=(<<)|(<<)|(<<)|(<<); // 开关本来是断开的,按下后接通,说明GPG0 3 5 6 被拉低成低电平,说明GPG0 3 5 6 本身就是 高电平, }

________________________________________________________________________________________________________________________________________________________________________________________________________

interrupt.h 文件

 #ifndef    __INTERRUPT_H__
#define __INTERRUPT_H__ /****************************************************
* 函数名称:void Irq_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:将Led1-4按键对应的中断屏蔽位置设为无效
*****************************************************/
void Irq_Init(void); #endif

interrupt.c 文件

 /************************************************
* mini2440板子上六个按键对应的GPIO和中断
* 按键 GPIO 中 断
* K1 GPG0 EINT8
* K2 GPG3 EINT11
* K3 GPG5 EINT13
* K4 GPG6 EINT14
* K5 GPG7 EINT15
* K6 GPG11 EINT19
************************************************/ #include<s3c2440.h>
#include"interrupt.h" // 为什么要添加 这一项呢,感觉没用啊,C语言学的很烂 /****************************************************
* 函数名称:void Irq_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:将Led1-4按键对应的中断屏蔽位置设为无效
*****************************************************/
void Irq_Init(void)
{
//对于EINT8,EINT11,EINT13,EINT14,需要在EINTMASK寄存器使能它们   0 为允许中断, 1为禁止,所以呢
EINTMASK&=(~(<<))&(~(<<))&(~(<<))&(~(<<)); // 见 P305页, 外部中断允许寄存器
//这4个外部中断的优先级是相同的,EINT8_23都接仲裁器的REQ1引脚
//所以不用像韦东山程序里那样再设置优先级了 //EINT8,EINT11,EINT13,EINT14使能
INTMSK&=(~(<<)); // P388 页
}

_____________________________________________________________________________________________________________________________________________________________________________________________________

irservice.h 文件

 #ifndef    __ISRSERVICE_H__
#define __ISRSERVICE_H__ /****************************************************
* 函数名称:void __irq IRQ_Handler(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:中断服务函数,必须加__irq
*****************************************************/
void __irq IRQ_Handler(void); #endif

isrservice.c 文件

 #include<s3c2440.h>
#include"isrservice.h"
#include"led.h" void delay(void);
/****************************************************
* 函数名称:void __irq IRQ_Handler(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:中断服务函数,必须加__irq
*****************************************************/
void __irq IRQ_Handler(void)
{
unsigned long oft=INTOFFSET; unsigned long val; val=EINTPEND; //EINT寄存器,它的位x为1时,表示EINT已经发生(x为4——23)。

// 比如 EINTPEND 的 第八位 指向 EINT
if(val&(<<)) //K1被按下,LED1被点亮
{
Led1_On();delay();Led1_Off();
} if(val&(<<)) //K2被按下,LED2被点亮
{
Led2_On();delay();Led2_Off();
} if(val&(<<)) //K3被按下,LED3被点亮
{
Led3_On();delay();Led3_Off();
}
if(val&(<<)) //K4被按下,LED4被点亮
{
Led4_On();delay();Led4_Off();
} // 清除中断

if(oft==) // 也就是 INTPND寄存器中哪一位被置1了,即INTPEND寄存器中位[X]为1时,INTOFFSET寄存器的值为 X(0-31),显然这里便是 第5位,EINT8_23 为 5
EINTPEND=(<<)|(<<)|(<<)|(<<); //清除EINTPEND寄存器,往某位写入1即可清除此位 。。 不清楚为什么是 写1 , 不是应该写0 吗???(手册实说 It is cleared by writing "1")
SRCPND=<<oft; //清除SRCPND寄存器,往某位写入1即可清楚此位 ,// 是不是 也就是 中断被拒绝???
INTPND=<<oft; //清除INTPND寄存器,往某位写入1即可清楚此位
//注意:清除顺序很重要:先是EINTPEND,然后是SRCPND,最后是INTPND
}
/****************************************************
* 函数名称:static void delay(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功 能:延时函数,前边加static是为了限制该函数只在
* 本文件中使用
*****************************************************/
static void delay(void)
{
int i,j;
for(i=;i<;i++)
for(j=;j<;j++);
}

总共 10个文件(包括初始化的 s3c2440.s 文件)

当然 我们调试的时候 ,把 .sct 文件改了一下,才能在 norflash 里面运行

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; ************************************************************* LR_ROM1 0x00000000 0x0200000 { ; load region size_region
ER_ROM1 0x00000000 0x0200000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 0x30000000 0x04000000 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM1 0x40000000 0x00001000 {
.ANY (+RW +ZI)
}
}

可以测试了,但是 只有 三个按键可以控制灯 亮灭,所以自己需要思考修改,现在看自己的了。

17:13:56

很不幸,下午在debug 的时候,老是调试在运行模式,进入不了debug中,开始还好好的,编译是没有问题的,也生成了,就是 调试不了。。

开发板环境配置可能哪里出现了问题

外部按键 控制 LED 中断 (参考 http://www.oschina.net/question/565065_115196?sort=time )的更多相关文章

  1. 51单片机-独立按键控制led矩阵的左移和右移

    51单片机学习 独立按键 控制led灯光矩阵的左移和右移 开发板采用的是普中的A2学习开发板,具体的代码如下: typedef unsigned int u16; void delay(u16 tim ...

  2. CC2530学习路线-基础实验-GPIO 按键控制LED灯亮灭(2)

    目录 1.前期预备知识 1.1 新大陆Zigbee模块按键电路图 1.2 CC2530相关寄存器 1.3 CC2530中断走向图 1.4 使用C语言为51单片机编写中断程序 1.5 *函数指针 2. ...

  3. 基于Arduino的按键控制LED实验

    I/O 口的意思即为INPUT 接口和OUTPUT 接口,到目前为止我们设计的小灯实验都还只是应用到Arduino 的I/O 口的输出功能,这个实验我们来尝试一下使用Arduino的I/O 口的输入功 ...

  4. 【嵌入式】——arm裸机开发 step by step 之 按键控制 LED 和 蜂鸣器

    一.arm-9 TQ2440 key.h #ifndef __KEY_H__ #define __KEY_H__ #define GPFCON (*(volatile unsigned long *) ...

  5. 按键控制LED灯-ESP32中断处理

    #include <driver/gpio.h> #include <esp_task_wdt.h> #include <freertos/FreeRTOS.h> ...

  6. 集齐所有机制的按键控制LED驱动

    内核版本:linux2.6.22.6 硬件平台:JZ2440 驱动源码 final_key.c : #include <linux/module.h> #include <linux ...

  7. 按键控制led驱动

    内核版本:linux2.6.22.6 硬件平台:JZ2440 驱动源码 key_drv.c : #include<linux/module.h> #include<linux/ker ...

  8. 独立按键控制led灯

    #include "regx51.h"typedef unsigned int u16; void delay_us(u16 time){ while(time--){} }voi ...

  9. zigbee学习之路(四):按键控制(中断方式)

    一.前言 通过上次的学习,我们学习了如何用按键控制led,但是在实际应用中,这种查询方式占用了cpu的时间,如果通过中断控制就可以解决这个问题,我们今天就来学习按键控制的中断方式. 二.原理分析 传统 ...

随机推荐

  1. Java迭代 : Iterator和Iterable接口

    从英文意思去理解 Iterable :故名思议,实现了这个接口的集合对象支持迭代,是可迭代的.able结尾的表示 能...样,可以做.... Iterator:   在英语中or 结尾是都是表示 .. ...

  2. 学习之js绑定事件

    由于ie中绑定事件的bug,所以产生了用原生的实践操作来模拟事件绑定的方法,跟着李炎恢学的一招. function addEvent(obj, type, fn){ if(obj.addEventLi ...

  3. Cocos2d-JS切换场景与切换特效

    var HelloWorldLayer = cc.Layer.extend({ sprite:null, ctor:function () { //////////////////////////// ...

  4. Subway---poj2502(最短路)

    题目链接:http://poj.org/problem?id=2502 人走路的速度是10km/h,地铁的速度是40km/h题目给出一个起点,一个终点,以及几条地铁线路运行的站点.题目给的点的做坐标单 ...

  5. .net中如何使用cookie

    比如建立一个名为aspcn,值为灌水小鱼的cookie HttpCookie cookie = new HttpCookie["aspcn"];cookie.Value = &qu ...

  6. Web:AJAX的详解

    Web中的AJAX技术: 1.介绍:全称:Asnchronous JavaScript and XML,即异步的JavaScript和XML功能:它不是某种编程语言,是一种无需加载整个网页的情况下能够 ...

  7. zabbix配置发送报警邮件

    配置邮件分为两种情况: 第一种:使用远端邮件服务器发送报警邮件 Linux系统版本:CentOS6.5-64 下载mailx: http://nchc.dl.sourceforge.net/proje ...

  8. loop_nslookup

    function loop_nslookup() { $baseFolder = "D:\ps_toolkit" $ip_list = "$baseFolder\ip_l ...

  9. Windows 上使用 cygwin 连接到 docker toolbox

    Windows 上使用 cygwin 连接到 docker toolbox Docker 确实给软件开发带来一些好处,在简化部署.统一开发.测试和生产环境上,有它独到的理念.Linux 上可直接安装 ...

  10. 项目重新部署后报The attribute required is undefined for the annotation type XmlElementRef

    在另外一台机器上部署项目,项目导进Eclipse中发现有异常 public class BooleanFeatureType extends FeatureBaseType{ @XmlElementR ...