The S5PV210 has four vector interrupt controllers (VICs), each containing 32 interrupt sources.
When an interrupt source generates an interrupt, the CPU will automatically assign the value of the VICxVECTADDRy (x=0,1,2,3,y=0-31) register to VICxADDRESS (x=0,1,2,3), so we can assign the address of our interrupt handling function to the VICxVECTADDRy register.
For example, we have a function
void key_handle()
{
……
}
We assign the value of the key_handle function to VIC0VECTADDR0 (external interrupt 0)
VIC0VECTADDR0 =key_handle;
When external interrupt 0 triggers an interrupt, the CPU will automatically assign the value of VIC0VECTADDR0 to VIC0ADDRESS and jump to this address to execute, that is, execute the function key_handle.
code show as below:
.global _start /* Declare a global label */
.global key_isr
_start:
/* Set up the stack to call the C function */
ldr sp, =0x40000000
/* Enable general interrupt */
mrs r0, cpsr
bic r0, r0, #0x00000080 /* Clear bit 7, IRQ interrupt disable bit, write 0 to enable IRQ */
msr cpsr, r0
bl main /* Jump to C function to execute */
halt:
b stop
key_isr:
/* Calculate the return address: The value of PC is equal to the current execution address + 8. When the CPU is about to execute an instruction (not yet executed), it is interrupted.
** This is the address of the instruction to be executed = PC-4 */
sub lr, lr, #4
stmfd sp!, {r0-r12, lr} /* protect the context */
bl key_handle
/* Restore the scene */
ldmfd sp!, {r0-r12, pc}^ /* ^ means restore spsr to cpsr */
key.c
#define GPC0CON *((volatile unsigned int *)0xE0200060)
#define GPC0DAT *((volatile unsigned int *)0xE0200064)
#define GPH0CON *((volatile unsigned int *)0xE0200C00)
#define GPH0DAT *((volatile unsigned int *)0xE0200C04)
#define EXT_INT_0_CON *((volatile unsigned int *)0xE0200E00)
#define EXT_INT_0_MASK *((volatile unsigned int *)0xE0200F00)
#define VIC0INTSELECT *((volatile unsigned int *)0xF200000C)
#define VIC0INTENABLE *((volatile unsigned int *)0xF2000010)
#define VIC0VECTADDR0 *((volatile unsigned int *)0xF2000100)
#define VIC0VECTADDR1 *((volatile unsigned int *)0xF2000104)
#define VIC0ADDRESS *((volatile unsigned int *)0xF2000F00)
#define EXT_INT_0_PEND *((volatile unsigned int *)0xE0200F40)
extern void key_isr(void);
void key_handle()
{
volatile unsigned char key_code = EXT_INT_0_PEND & 0x3;
VIC0ADDRESS = 0; /* Clear interrupt vector register */
EXT_INT_0_PEND |= 3; /* Clear interrupt pending register*/
if (key_code == 1) /* key1 */
GPC0DAT ^= 1 << 3; /* toggle LED1 */
else if (key_code == 2) /* key2 */
GPC0DAT ^= 1 << 4; /* toggle LED2 */
}
int main()
{
GPC0CON &= ~(0xFF << 12);
GPC0CON |= 0x11 << 12; /* Configure GPC0_3 and GPC0_4 as output: LED1 and LED2 */
GPH0CON |= 0xFF << 0; /* Configure GPH0_0 and GPH0_1 as external interrupts: key1 and key2 */
EXT_INT_0_CON &= ~(0xFF << 0);
EXT_INT_0_CON |= 2 | (2 << 4); /* Configure EXT_INT[0] and EXT_INT[1] as falling edge trigger*/
EXT_INT_0_MASK &= ~3; /* Unmask external interrupts EXT_INT[0] and EXT_INT[1] */
VIC0INTSELECT &= ~3; /* Select external interrupt EXT_INT[0] and external interrupt EXT_INT[1] as IRQ type interrupt*/
VIC0INTENABLE |= 3; /* Enable external interrupts EXT_INT[0] and EXT_INT[1] */
VIC0VECTADDR0 = (int)key_isr; /* When EXT_INT[0] triggers an interrupt, that is, when the user presses key1,
The CPU will automatically assign the value of VIC0VECTADDR0 to VIC0ADDRESS and jump to this address to execute */
VIC0VECTADDR1 = (int)key_isr;
while (1);
return 0;
}
Makefile
key.bin: start.o key.o
arm-linux-ld -Ttext 0x20000000 -o key.elf $^
arm-linux-objcopy -O binary key.elf $@
arm-linux-objdump -D key.elf > key.dis
key.o : key.c
arm-linux-gcc -c $< -o $@
start.o : start.S
arm-linux-gcc -c $< -o $@
clean:
rm *.o *.elf *.bin *.dis
Download the program to memory and run it
Press key1, LED1 lights up, press key1 again, LED1 turns off
Press key2, LED2 lights up, press key2 again, LED2 turns off
Previous article:Embedded Learning Notes 2: Introduction to the 210 Power-on Startup Process
Next article:TQ210 bare metal programming (2) - LED running light
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- What will happen if the servo motor inertia is insufficient?
- How to select parameters for servo motor inertia size
- The difference between the servo motor moment of inertia and the load moment of inertia
- How to calculate the inertia of servo motor and reducer
- What is the difference between a servo press and a normal press?
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- EEWORLD University ---- Basic knowledge of TID
- Commonly used algorithms for drones - Kalman filter (10)
- If the test posture is not up to standard and the result is deviated, you will have to work overtime!
- Design of filter circuit
- How to use a touch switch to make a circuit that turns on when pressed once and turns off when pressed again
- Meng Wanzhou is about to return to China
- Equivalent circuits of components such as resistors, capacitors, inductors, and thyristors
- SI4463 wireless wake-up principle
- [Prize Download] Infineon "Selection Guide for Power Devices for Fashionable Small Home Appliances"
- [Rawpixel RVB2601 development board trial experience] 2. Temperature and humidity sensor DHT11 test, serial port print results