转帖: 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. (转)js闭包初入门

    先看一段JS代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 function a(){             var num = 0;             function  ...

  2. nrf51822裸机教程-SPI(主)

    关于SPI总线的介绍这里就不细说了,网上有很多介绍SPI总线时序的. SPI总线的本质就是一个环形总线结构,在时钟驱动下两个双向移位寄存器进行数据交换. 所以SPI总线的特色就是:传输一字节数据的同时 ...

  3. WGZX:javaScript 学习心得--1

    标签: javascriptiframedreamweaver浏览器htmltable 2008-09-11 10:50 1071人阅读 评论(0) 收藏 举报  分类: UI(21)  1,docu ...

  4. SQL查询的几种方式

    /* 左连接 left join 或者 left outer join */ /* 左连接 Table_A表数据全部显示,Table_B根据条件匹配Table_A 匹配上显示,否则显示NULL */ ...

  5. Wordpress固定链接设置

    wordpress设置固定链接时,应该尽量注意一下几点: 1.不要让日期出现在固定链接里面. 2.不要让分类的链接出现在固定链接里面. 3.链接不要太深. 4.链接中不要出现中文. 5.文章最后可以加 ...

  6. I Count Two Three---hdu5878(打表+二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5878 题意:找到第一个>=n的数x, 满足 x = 2a3b5c7d:n<=1e9; 打表 ...

  7. mac下配置laravel环境

    1.由于 Laravel 需要使用 PHP 的 Mcrypt 扩展,所以我们使用下面的命令来安装. brew search mcrypt brew install php54-mcrypt 2.安装 ...

  8. cname和CDN

    http://blog.csdn.net/crazw/article/details/8986504 先说一下DNS的几个基本概念: 一. 根域 就是所谓的“.”,其实我们的网址www.baidu.c ...

  9. Mysqldump 参数详解(全)

    Mysqldump 参数详解(全) http://www.open-open.com/lib/view/open1358172843762.html mysqldump -S /tmp/mysql33 ...

  10. CentOS6.7搭建蜜罐dionaea

    yum -y install epel-release wget tar git autoconf* libtool-* mkdir /opt/dionaea 1.安装liblcfg软件.git cl ...