[ARM bare board] Key external interrupt process and example

Publisher:TranquilSmileLatest update time:2020-03-06 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Initialization

Set up the interrupt source (so that it can send an interrupt signal)

Set up the interrupt controller (so that it can send an interrupt signal to the CPU)

Set the CPU master switch (CPSR has an I bit, set the master switch, enable interrupts)

Distinguish the interrupt source when processing

Clear the interrupt after processing

insert image description here

1.1 Interrupt Sources

Set the button as an interrupt source pin

Configure pins for external interrupt mode

Configure the interrupt to be triggered by the falling edge

Configure external interrupt MASK enable

//Initialize external interrupt, set the button as interrupt source

void key_eint_init(void)

{

/* Pins: GPF0,2 GPG3,11 */

/* Interrupt: EINT0, 2 EINT11, 19*/

GPFCON &= ~((3<<0) | (3<<4)); //Clear

GPFCON |= ((2<<4) | (2<<0)); //Set [10] to configure as external interrupt


GPGCON &= ~((3<<6) | (3<<22));

GPGCON |= ((2<<6) | (2<<22)); //Set [10] to configure as external interrupt


/* Set the interrupt trigger mode: double edge trigger*/

EXTINT0 |= (3<<0) | (3<<8); //Configure EINT0, 2

EXTINT1 |= (3<<12); //Configure EINT11

EXTINT2 |= (3<<12); //Configure EINT19


/* Set external MASK clear enable */

EINTMASK &= ((1<<11) | (1<<19));

}

insert image description here

1.2 Interrupt Controller

Set INTMASK (INTERRUPT MASK (INTMSK) REGISTER) interrupt mask register

0 = Interrupt service is available.

1 = Interrupt service is masked.

// Initialize the interrupt controller

void interrupt_init(void)

{

INTMASK &= ~((1<<0) | (1<<2) | (1<<5)); // Enable interrupt

}

insert image description here

1.3 CPU Enable Interrupt

Set the I bit of the CPSR

When set to 0, it is enabled, and when set to 1, it is disabled

mrs r0,cpsr //Read CPSR

bic r0,r0,#(1<<7) //bit 7 cleared (IRQ)

msr cpsr,r0

insert image description here
insert image description here

1.4 start.S sets the interrupt vector table

Call the interrupt service function at 0x18

/*======================================Exception Vector Table================================================*/

_start:

b reset //vector 0x00: reset (address 0 corresponds to reset)

  ldr pc, und_addr //vector 0x04: und (undefined instruction exception occurs, enter the "undefined exception handling function") absolute jump, jump to sdram

  ldr pc, swi_addr //vector 0x08: swi

  b halt //vector 0x0c: prefetch aboot

  b halt //vector 0x10: data aboot

  b halt //vector 0x14: reserved

  bl irq_addr //vector 0x18: IRQ

  b halt //vector 0x1c: FIQ

    

irq_addr:

.word do_irq

insert image description here

1.5 start.S sets up interrupt processing

Before executing the interrupt handler, the hardware will handle the following:

 1.lr_irq holds the address of the next instruction to be executed in interrupt mode

 2.SPSR_irq saves the interrupt mode CPSR

 3.CPSR's [M4:M0] = [10010], enter irq mode

 4. Jump to the 0x08 mode to execute the program, that is, jump to the bl do_irq instruction


1.5.1 Setting up the stack

sp_irq sets up the stack because the following functions need the stack

    ldr sp, =0x33D00000


1.5.2 Save the scene

In the irq processing function, it is always possible to use r0~r12, so save it first

As can be seen from the figure below, lr-4 is the return address after the exception is handled, and it also needs to be saved

    sub lr,lr,#4

    stmdb sp!, {r0-r12,lr} 

insert image description here

1.5.3 Handling Interrupts

Jump to the interrupt handling function

    bl handle_irq_c


1.5.4 Restoring the scene

Assign the value of lr to pc, ^ will restore the value of spsr to cpsr

    ldmia sp,{r0-r12,pc}^ 


2. Interrupt service function

void handle_irq_c(void)

{

/* 1. Identify interrupt source*/

int bit = INTOFFSET;


/* 2. Call the corresponding processing function*/

key_eint_irq(bit); //Process interrupt and clear external interrupt flag


/* 3. Clear interrupts: clear from the source*/

SRCPND = (1< INTPND = (1<}


2.1 Identifying interrupt sources

INTERRUPT OFFSET (INTOFFSET) REGISTER

The current interrupt source can be known by judging INTOFFEST

insert image description here

2.2 Calling the processing function

This triggers an external interrupt, so the external interrupt needs to be cleared

EINTPEND (External Interrupt Pending Register)

To clear the interrupt, just write 1 to it. Because whatever interrupt occurs, the corresponding bit will become 1. Therefore, whatever interrupt occurs, just write the value of EINTPEND of the interrupt to EINTPEND

/* 2. Call the corresponding processing function and clear the corresponding interrupt*/

key_eint_irq(bit); 

insert image description here

2.3 Clear Interrupt

Clear from the source: clear SRCPND first, then clear INTPND


It only clears the SRCPND and INTPND registers corresponding to the bits set to 1 in the data, so to clear any interrupt, just write 1 to the corresponding bit.

insert image description here

SRCPND(SOURCE PENDING (SRCPND) REGISTER)

insert image description here

INTPND(INTERRUPT PENDING (INTPND) REGISTER)

insert image description here

Reference address:[ARM bare board] Key external interrupt process and example

Previous article:[ARM bare board] Timer interrupt example and analysis
Next article:【ARM bare board】Software interrupt analysis and examples

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

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