S3C6410外部中断裸机学习笔记(VIC模式)

 

转自:http://user.qzone.qq.com/39458645/infocenter#!app=2&via=QZ.HashRefresh&pos=1331913255

一、          关于外部中断的一些基础知识

1、S3C6410共有127个外部中断,其外接I/O引脚及分组如下:

外部中断组0   EINT0  GPN0---GPN15 GPL8---GPL14  GPM0---GPM4

外部中断组1   EINT1  GPA0---GPA7   GPB0---GPB6

外部中断组2   EINT2  GPC0---GPC7

外部中断组3   EINT3  GPD0---GPD5

外部中断组4   EINT4  GPF0---GPF14

外部中断组5   EINT5  GPG0---GPG7

外部中断组6   EINT6  GPH0---GPH9

外部中断组7   EINT7  GPO0---GPO15

外部中断组8   EINT8  GPP0---GPP14

外部中断组9   EINT9  GPQ0---GPQ9

以上127个引脚每个引脚都可以产生一个外部中断

2、127个外部中断在VIC里的中断号

      NO.              中断源                         说明                                       GROUP

      0           INT_EINT0       外部中断组0引脚号0-3                    VIC0

      1           INT_EINT1       外部中断组0引脚号4-11                 VIC0

      32         INT_EINT2       外部中断组0引脚号12-19               VIC1

      33         INT_EINT3       外部中断组0引脚号20-27               VIC1

      53         INT_EINT4       外部中断组1-9                                  VIC1

以上属于外部中断组0的27个中断占用了VIC里的4个中断号,外部中断组1-9只占用了1个中断号

二、          外部中断响应流程

外部中断从外设到CPU的具体流程如下:

外设àGPIOàVICàARM1117

那么我们编写关于中断的程序流程也应该是这个过程:

配置外设à配置GPIOà配置VICà配置ARM协处理器等

三、          配置过程

1、配置GPIO

GPxCON:配置相应的I/O口为中断模式

EINTxCONx

外部中断屏蔽EINTxMASK:         屏蔽某个外部中断,0=发生中断  1=不发生中断 默认是全屏蔽的。


外部中断悬挂寄存器EINTxPEND:      中断标志位


过滤控制寄存器EINTxFLTCONx:      设置滤波方式,       延迟滤波或数字滤波

2、VIC配置

A、在协处理器中开启VIC,在协处理器里设置VE位。

B、关中断,清矢量地址寄存器并配置中断类型

VICxINTENCLEAR       写1 DISABLE

VICxINTSELECT           0=IRQ         1=FIQ

VICxADDRESS              矢量地址寄存器清零

C、配置中断函数入口地址

VICxVECTADDR[x]

D、使能中断

VICxINTENABLE   1=ENABLE写0无效,DISABLE只能通过VICxINTENCLEAR写1更改

  E、总中断使能                CPSR Bit 8位I置1 ENABLE

完整的代码如下,其于RVDS2.2环境,AXD调试

startup.s

-----------------------------------------------------------------------------------------------------------------------
 INCLUDE s3c6410.inc
;----------------------------------------------------------------
 IMPORT main   ;C Entry Point for Steppingstone Loader
;----------------------------------------------------------------
 
 EXPORT ENTRY
 AREA Init,CODE,READONLY
;----------------------------------------------------------------

ENTRY
  b ResetHandler
  b .
  b .
  b .
  b .
  b .
  b .
   
  
ResetHandler
;----------------------------------------
; Disable WatchDog Timer
;----------------------------------------  
  ldr r0,=WTCON
  ldr r1,=0x00
  str r1,[r0]
  
;----------------------------------------
; Enable VIC
;---------------------------------------- 
  mrc p15,0,r0,c1,c0,0
  orr r0,r0,#(1<<24) ;Enable VE bit
  mcr p15,0,r0,c1,c0,0 
;SetBit C1 Register VE位(BIT24)则中断向量地址由VIC决定
;ClrBit C1 Register VE位(BIT24)则中断向量地址是固定地址

;  总中断ENABLE

  mrs r0,cpsr
  bic r0,r0,#0x80
  msr cpsr_c,r0

;DEBUG  
  mrs r0,cpsr

  b main

  END  -----------------------------------------------------------------------------------------------------------------------
main.c

void main(void)
{

 Led_Init(); 
 
 INTC_Init();
 
 Key_IO_Init();
  
 Key_Int_Config();

 while(1);
}

 -----------------------------------------------------------------------------------------------------------------------
led.c

#include "s3c6410_addr.h"

void Led_Init(void)
{
 // GPK4 5 6 7 接LED,I/O设置为输出
 rGPKCON0 = (rGPKCON0 & (~(0xFFFF << 16))) | (0x1111 << 16);
 
 // GPK4 5 6 7 设置为上拉
 rGPKPUD = (rGPKPUD & (~(0xFF << 8))) | (0xAA << 8);
 
 // 初始化时LED OFF
 rGPKDAT |= 0x00F0;
}

key.c

#include "s3c6410_addr.h"
#include "interrupt.h"

void Key_ISR(void) __irq;

void Key_IO_Init(void)
{
 // GPN0 1 2 3 接按键K1 K2 K3 K4 配置按键为中断E_INT
 rGPNCON = rGPNCON & 0xFFFFFFAA; 
 rGPNDAT = rGPNDAT | 0x000F;
 
}


// KEY Interrupt configuration
void Key_Int_Config(void)
{
 // Configurate the Key I/O for Interrupt Mode 0x10
 rGPNCON = rGPNCON & 0xFFFFFF00 | 0x00AA; 
 // Configurate the EINT0 EINT1 EINT2 EINT3 Trigger of Flowing Type 01x
 rEINT0CON0 = (rEINT0CON0 & 0xFFFFFF22);
 
 // Disable Interrupt MASK EINT0 ENIT1 EINT2 EINT3
 rEINT0MASK &= 0xFFFFFFF0;
 
 //Clear EINT Flag
 rEINT0PEND |= 0x0000000F;
 
 // Select External Interrupt Mode IRQ
 rVIC0INTSELECT = 0x0;
 rVIC1INTSELECT = 0x0;
 
 // Set the Entry Address of External Interrupt Group 0 ISR
 VIC0VECTADDR[0] = (unsigned int)Key_ISR;
 
 // Enable the External Interrupt Group 0
 rVIC0INTENABLE |= 0x01; 
  
}

void Key_ISR(void) __irq
{
 int temp;
 // KEY 1
 if(rEINT0PEND & 0x01)
 {
  temp = ~(rGPKDAT & (0x01 << 4));
  rGPKDAT = rGPKDAT & ~(0x01 << 4) | temp;
   
  // Clear Interrupt Pend
  rEINT0PEND |= 0x01; 
 }
 // KEY2
 if(rEINT0PEND & 0x02)
 {
  temp = ~(rGPKDAT & (0x01 << 5));
  rGPKDAT = rGPKDAT & ~(0x01 << 5) | temp;
// Clear Interrupt Pend
  rEINT0PEND |= 0x02;  
 }
 // KEY3
 if(rEINT0PEND & 0x04)
 {
  temp = ~(rGPKDAT & (0x01 << 6));
  rGPKDAT = rGPKDAT & ~(0x01 << 6) | temp;
  
  // Clear Interrupt Pend
  rEINT0PEND |= 0x04;  
 }
 // KEY4
 if(rEINT0PEND & 0x08)
 {
  temp = ~(rGPKDAT & (0x01 << 7));
  rGPKDAT = rGPKDAT & ~(0x01 << 7) | temp;
  
  // Clear Interrupt Pend
  rEINT0PEND |= 0x08;  
 }
 rVIC0ADDR = 0x00000000;  
}

-----------------------------------------------------------------------------------------------------------------------

interrupt.c

#include "s3c6410_addr.h"
#include "interrupt.h"


void INTC_Init(void)
{
 // Disable All Interrupt
 rVIC0INTENCLEAR = 0xFFFFFFFF;
 rVIC1INTENCLEAR = 0xFFFFFFFF; 
 // Clear VECT Address
 rVIC0ADDR = 0x0;
 rVIC1ADDR = 0x0; 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值