2440的外部中断操作过程

发布者:温暖拥抱最新更新时间:2024-07-25 来源: cnblogs关键字:外部中断  操作过程 手机看文章 扫描二维码
随时随地手机看文章

要想正确地执行2440的外部中断,一般需要完成两个部分内容:中断初始化和中断处理函数。


    在具体执行中断之前,要初始化好要用的中断。2440的外部中断引脚EINT与通用IO引脚F和G复用,要想使用中断功能,就要把相应的引脚配置成中断模式,如我们想把端口F0设置成外部中断,而其他引脚功能不变,则GPFCON=(GPFCON & ~0x3) | 0x2。配置完引脚后,还需要配置具体的中断功能。我们要打开某一中断的屏蔽,这样才能响应该中断,相对应的寄存器为INTMSK;还要设置外部中断的触发方式,如低电平、高电平、上升沿、下降沿等,相对应的寄存器为EXTINTn。另外由于EINT4到EINT7共用一个中断向量,EINT8到EINT23也共用一个中断向量,而INTMSK只负责总的中断向量的屏蔽,要具体打开某一具体的中断屏蔽,还需要设置EINTMASK。上面介绍的是最基本的初始化,当然还有一些其他的配置,如当需要用到快速中断时,要使用INTMOD,当需要配置中断优先级时,要使用PRIORITY等。


    中断处理函数负责执行具体的中断指令,除此以外还需要把SRCPND和INTPND中的相应的位清零(通过置1来清零),因为当中断发生时,2440会自动把这两个寄存器中相对应的位置1,以表示某一中断发生,如果不在中断处理函数内把它们清零,系统会一直执行该中断函数。另外还是由于前面介绍过的,有一些中断是共用一个中断向量的,而一个中断向量只能有一个中断执行函数,因此具体是哪个外部中断,还需要EINTPEND来判断,并同样还要通过置1的方式把相应的位清零。一般来说,使用__irq这个关键词来定义中断处理函数,这样系统会为我们自动保存一些必要的变量,并能够在中断处理函数执行完后正确地返回。还需要注意的是,中断处理函数不能有返回值,也不能传递任何参数。


    为了把这个中断处理函数与在2440启动文件中定义的中断向量表相对应上,需要先定义中断入口地址变量,该中断入口地址必须与中断向量表中的地址一致,然后把该中断处理函数的首地址传递给该变量,即中断入口地址。


    下面就是一个外部中断的实例。开发板上一共有四个按键,分别连到了EINT0,EINT1,EINT2和EINT4,我们让这四个按键分别控制连接在B5~B8引脚上的四个LED:按一下键则LED亮,再按一下则灭:


 


#define _ISR_STARTADDRESS 0x33ffff00


 


#define U32 unsigned int


 


#define pISR_EINT0            (*(unsigned *)(_ISR_STARTADDRESS+0x20))


#define pISR_EINT1            (*(unsigned *)(_ISR_STARTADDRESS+0x24))


#define pISR_EINT2            (*(unsigned *)(_ISR_STARTADDRESS+0x28))


#define pISR_EINT4_7  (*(unsigned *)(_ISR_STARTADDRESS+0x30))


 


#define rSRCPND     (*(volatile unsigned *)0x4a000000)      //Interrupt request status


#define rINTMSK     (*(volatile unsigned *)0x4a000008)       //Interrupt mask control


#define rINTPND     (*(volatile unsigned *)0x4a000010)       //Interrupt request status


 


#define rGPBCON    (*(volatile unsigned *)0x56000010) //Port B control


#define rGPBDAT    (*(volatile unsigned *)0x56000014) //Port B data


#define rGPBUP     (*(volatile unsigned *)0x56000018)  //Pull-up control B


 


#define rGPFCON    (*(volatile unsigned *)0x56000050) //Port F control


 


#define rEXTINT0   (*(volatile unsigned *)0x56000088)  //External interrupt control register 0


#define rEINTMASK  (*(volatile unsigned *)0x560000a4) //External interrupt mask


#define rEINTPEND  (*(volatile unsigned *)0x560000a8) //External interrupt pending


 


static void __irq Key1_ISR(void)   //EINT1


{


       int led;


       rSRCPND = rSRCPND | (0x1<<1);


       rINTPND = rINTPND | (0x1<<1);


       led = rGPBDAT & (0x1<<5);


       if (led ==0)


              rGPBDAT = rGPBDAT | (0x1<<5);


       else


              rGPBDAT = rGPBDAT & ~(0x1<<5);


}


 


static void __irq Key2_ISR(void)   //EINT4


{


       int led;


       rSRCPND = rSRCPND | (0x1<<4);


       rINTPND = rINTPND | (0x1<<4);


       if(rEINTPEND&(1<<4))


       {


              rEINTPEND = rEINTPEND | (0x1<<4);


              led = rGPBDAT & (0x1<<6);


              if (led ==0)


                     rGPBDAT = rGPBDAT | (0x1<<6);


              else


                     rGPBDAT = rGPBDAT & ~(0x1<<6);


       }


}


 


static void __irq Key3_ISR(void)   //EINT2


{


       int led;


       rSRCPND = rSRCPND | (0x1<<2);


       rINTPND = rINTPND | (0x1<<2);


       led = rGPBDAT & (0x1<<7);


       if (led ==0)


              rGPBDAT = rGPBDAT | (0x1<<7);


       else


              rGPBDAT = rGPBDAT & ~(0x1<<7);


}


 


void __irq Key4_ISR(void)   //EINT0


{


       int led;


       rSRCPND = rSRCPND | 0x1;


       rINTPND = rINTPND | 0x1;


       led = rGPBDAT & (0x1<<8);


       if (led ==0)


              rGPBDAT = rGPBDAT | (0x1<<8);


       else


              rGPBDAT = rGPBDAT & ~(0x1<<8);


}


 


void Main(void)


{


       int light;


      


       rGPBCON = 0x015550;


       rGPBUP = 0x7ff;


       rGPFCON = 0xaaaa;


   


       rSRCPND = 0x17;


       rINTMSK = ~0x17;


       rINTPND =0x17;


       rEINTPEND = (1<<4);


       rEINTMASK = ~(1<<4);


       rEXTINT0 = 0x20222;


   


       light = 0x0;


       rGPBDAT = ~light;


       


       pISR_EINT0 = (U32)Key4_ISR;


       pISR_EINT1 = (U32)Key1_ISR;


       pISR_EINT2 = (U32)Key3_ISR;


       pISR_EINT4_7 = (U32)Key2_ISR;


      


       while(1)


              ;     


}


关键字:外部中断  操作过程 引用地址:2440的外部中断操作过程

上一篇:linux gpio模拟i2c
下一篇:s3c2440中PWM应用

推荐阅读最新更新时间:2024-11-17 10:06

STM32 基础系列教程 3 – 外部中断
前言 学习stm32 GPIO 的外部中断使用,用中断模式实现简单的按键输入功能,用按实现基础实验二中的LED亮灭切换功能! 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。将PA0引脚设置成外部中断输入引脚(中断模式设为下降沿中断),程序得到PA0引脚的(按键操作)输入状态,并根据其输入电平的高低来控制PC13输出,来控制LED,实现按一次LED亮,再按一下,LED灭的功能。 本示例所用的最小系统板原理图: 新建STM32 CUBEMX 工程, 双击桌面STM32Cube
[单片机]
STM32 基础系列教程 3 – <font color='red'>外部中断</font>
avr的外部中断
关于AVR中断: 系统在正常运行主程序时,如果突然有一个重要的任务要马上处理,那么系统就要保存现在的工作,然后再去处理这个任务,执行这个重要任务完毕以后再返回原来的主程序继续运行,这就是中断。 主程序一旦进入中断服务程序,那么AVR芯片将自动的关闭全局中断,在这个期间不再执行其它的中断请求,直到中断程序结束以后芯片才自动的重新开放全局中断。(注意,在这个期间某些中断请求可能会被丢弃,某些请求会留下中断请求标致,一旦当前的中断执行完毕,这个有中断标致的请求就有可能马上得到响应,如INT0的下降沿触发就会留下中断请求标致,而低电平触发就不会流下中断请求标致)。如果你想在执行中断服务程序时响应另外一个更重要的中断,那么就要在中断服务程
[单片机]
基于s3c2440的12864液晶驱动
12864是128*64点阵液晶模块的点阵数简称,业界约定俗成的简称。 一、液晶显示模块概述 12864A-1 汉字图形点阵液晶显示模块,可显示汉字及图形,内置 8192 个中文汉字(16X16 点阵,16*8=128,16*4=64,一行只能写 8 个汉字,4 行;、128 个字符(8X16 点阵)及 64X256 点阵显示 RAM(GDRAM))。 主要技术参数和显示特性: 电源:VDD 3.3V~+5V(内置升压电路,无需负压); 显示内容:128 列× 64 行(128 表示点数) 显示颜色:黄绿 显示角度:6:00 钟直视 LCD 类型:STN 与 MCU 接口:8 位或 4 位并行/3 位串行 配置 LED 背光
[单片机]
玩转mini2440开发板之【在64位WIN7/WIN10系统中安装USB驱动】
玩mini2440开发板已经很多年了,虽然玩的不怎么精通,但是一直都有在弄。而电脑的操作系统也从最终的32位WinXP提升到了32位的Win7,而今更是到了64位的Win10。然后,却带来了一个很严重的问题,友善之臂官方原配的FriendlyARM USB Download Driver Setup_20090421驱动文件根本不能用于64位的Win10系统中。所以,这段时间我一直在倒腾怎么在64位的Win10系统中安装mini2440开发板的USB驱动,不然开发板就只能变成一块砖头了。 好在今天终于在网上找到高人的妙招了,总结如下: 1、下载工具包:https://download.csdn.net/download/l
[单片机]
玩转mini<font color='red'>2440</font>开发板之【在64位WIN7/WIN10系统中安装USB驱动】
DM9000的驱动在TQ2440+linux2.6.32下的移植
这里我们主要阐述DM9000的驱动在TQ2440+linux2.6.32下的移植,分俩部分,一是驱动移植,一是测试程序 硬件平台:TQ2440,DM9000EP 内核 : linux2.6.32 编译工具: codesource出品 arm-linux-none-gnueabi-4.3.3 文件系统: busybox1.1.11+yaffs 在此推荐一个文档: http://singleboy.blog.163.com/blog/static/5490019420115141426387/ mini2440的,在移植过程中参考了此文,鸣谢 一、DM9000驱动移植 主要修改俩个文件,一是mach-smdk2440.c,一
[单片机]
DM9000的驱动在TQ<font color='red'>2440</font>+linux2.6.32下的移植
S3C2440裸机------触摸屏_校准原理
所谓校准就是找到一个公式把电压值转换为坐标值,我们的触摸屏覆盖在LCD上面,当我们得到出点的电压值之后可以通过比例公式得到LCD的坐标。 但是实际我们不会选择边界点,因为边界点不方便点,所以我们都是从中间选择某个点进行计算。 由于液晶屏的水平方向和垂直方向存在一些偏差,因此我们都是水平方向选择2个点,垂直方向选择两个点。
[单片机]
S3C<font color='red'>2440</font>裸机------触摸屏_校准原理
用51单片同时测温度(DS18B20)和频率(外部中断测)
void main()//主函数 { delay1ms(1000); lcd_init();//液晶显示初始化 init_play(); while(1) { EA=0; //因DS18B20对时序要求高且受中断影响,故先关闭总中断 read_temp();//读取温度 ds1820disp();//显示 CT_init();//定时计数器初始化 EA=1;//开总中断 EX0=1;//允许外部中断 IT0=1;//设置外部中断方式为下降沿触发 P3=0xff; t0=(u
[单片机]
S3C2440看门狗定时器
看门狗定时器的主要作用是在程序因为干扰而跑飞后,能够使系统复位,不至于使系统永远的死下去。它的原理与一般的定时器没有多大区别,就是先要设置好一段时间,当超过这段时间后,就从当前运行的程序中跳出进入中断处理程序中。但两者的主要差别是,一般的定时器中断是我们希望它发生的,因此我们不会在定时器中断发生前的那个时间段内干预它;而看门狗定时器中断是我们不希望它发生的,因此我们要想方设法地避免其发生。主要的方法就是在中断发生前,重新对看门狗定时器的寄存器进行赋值,使它的定时器重新开始计时。 view plain copy #include 2440addr.h #include Option.h #d
[单片机]
S3C<font color='red'>2440</font>看门狗定时器
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved