First, we can find the circuit diagram of the button in the supporting materials of the development board, E: TQ210_CD development board supporting circuit diagram Bottom pdf format TQ210_BOARD_V4_20121023.
You can see that the address lines corresponding to keys key1~key6 are XEINT0~XEINT5. We will only use the first few keys for now.
Then we find the corresponding pin number of the address line in the board.
It can be seen that the pin numbers corresponding to the key address lines XEINT0~XEINT5 are GPH0_1~GPH0_5.
Now you can find the control register of GPH0 in the S5PV210_UM_REV1.1 document, which controls the 6 buttons accordingly.
Set the key control registers to external interrupt processing. Then set the corresponding parameters for external interrupt processing.
External interrupts require setting two interrupt registers, EXT_INT_CON and EXT_INT_MASK.
Since the level is low when the button is pressed, all are set to Falling edge triggered.
After setting EXT_INT_CON, you also need to set EXT_INT_MASK (external interrupt control register).
Set the external interrupt processing corresponding to the key to be used to enable interruption.
Then set the interrupt selection register VIC0INTSELECT and select the interrupt mode (usually IRQ mode).
Then set the VICINTENABLE register, the interrupt enable register.
When an interrupt occurs, a register VICVECTADDR is needed to store the interrupt processing. After the interrupt occurs, it jumps to the function in the register and starts executing.
For example:
VIC0VECTADDR0 = (unsigned int)key_isr;
After the interrupt occurs, it jumps to key_isr for execution.
However, when it comes to jump execution, you need to consider the operation of protecting the scene.
For example: in key_isr
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.
** The address of the instruction just to be executed is exactly = PC-4 (you can check the working principle of the three-stage pipeline) */
sub lr, lr, #4
stmfd sp!, {r0-r12, lr} /* Protect the scene. Since we don’t know which general register to use, we push all 0~12 onto the stack*/
bl key_handle
/* Restore the scene*/
ldmfd sp!, {r0-r12, pc}^ /* ^ means restore spsr to cpsr */
Since interrupt processing is used, the parameters of cpsr (current program status register) must be set.
To use the IRQ interrupt, set the i bit to 0.
/* Open the general interrupt */
mrs r0, cpsr /* transfer the content of cpsr to r0*/
bic r0, r0, #0x00000080 /* clear the 7th bit, IRQ interrupt disable bit, write 0 to enable IRQ */
msr cpsr, r0 /* transfer the content of r0 to cpsr*/
BIC - Bit Clear Instruction
Instruction format:
BIC{cond}{S} Rd,Rn,operand2
The BIC instruction performs a bitwise logical AND operation on the value of Rn and the complement of operand2, and stores the result in the destination register Rd. Instruction example: BIC R0, R0, #0x0F; clear the lowest 4 bits of R0 and keep the other bits unchanged.
When the scene is protected above, the program jumps to key_handle for execution.
void key_handle()
{
volatile unsigned char key_code = EXT_INT_0_PEND & 0x3;
VIC0ADDRESS = 0;
EXT_INT_0_PEND |= 3;
if (key_code == 1)
/* GPC0DAT ^= 1 << 3;*/
GPC0DAT |= 0x00000008;
else if (key_code == 2)
/* GPC0DAT ^= 1 << 4;*/
GPC0DAT |= 0x00000010;
}
In the program, the EXT_INT_0_PEND register is the data change after the interrupt occurs. 1 means an interrupt occurs.
The overall source code is as follows:
/*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;
EXT_INT_0_PEND |= 3;
if (key_code == 1)
/* GPC0DAT ^= 1 << 3;*/
GPC0DAT |= 0x00000008;
else if (key_code == 2)
/* GPC0DAT ^= 1 << 4;*/
GPC0DAT |= 0x00000010;
}
int main()
{
GPC0CON &= ~(0xFF << 12);
GPC0CON |= 0x11 << 12;
GPH0CON |= 0xFF << 0;
EXT_INT_0_CON &= ~(0xFF << 0);
EXT_INT_0_CON |= 2 | (2 << 4);
EXT_INT_0_MASK &= ~3;
VIC0INTSELECT &= ~3;
VIC0INTENABLE |=3;
VIC0VECTADDR0 = (unsigned int)key_isr;
VIC0VECTADDR1 = (unsigned int)key_isr;
while (1);
return 0;
}
/*start.S*/
.global _start /* declare a global label */
.global key_isr
_start:
/* set up the stack to call the C function */
ldr sp, =0x40000000
/* Open the general interrupt */
mrs r0, cpsr
bic r0, r0, #0x00000080 /* Clear the 7th bit, IRQ interrupt disable bit, write 0 to enable IRQ */
msr cpsr, r0
bl main /* Jump to C function to execute */
stop:
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.
** The address of the instruction just to be executed is exactly = PC-4 */
sub lr, lr, #4
stmfd sp!, {r0-r12, lr} /* Protect the scene*/
bl key_handle
/* Restore the scene*/
ldmfd sp!, {r0-r12, pc}^ /* ^ means restore spsr to cpsr */
Previous article:TQ210_Bare Metal Programming (III)——Serial Communication
Next article:About S3C2440 u-boot supports nand hw ecc
Recommended ReadingLatest update time:2024-11-15 17:22
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
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- [Precise delay function] Precise delay function in IAR (MSP430)
- After reading this article from the Research Institute, I feel that 6-lane Wi-Fi still has a long way to go.
- Warning for trouble~~~~ la la la~ hurry to the front of the post to find out
- mcgs Kunlun Tongtai Modbus RTU, Modbus TCP communication method Modicon Modbus communication configuration steps
- Proficient in hardware and familiar with software
- [Nucleo G071 Review] SYSTICK & Comparison of Two Commonly Used Low Power Modes
- TMS320C66x dual loop and multiple loop optimization summary
- [Top Micro Smart Display Screen Review] 3. Run SciTE Lua script editor to test the screen alarm function
- Material problem of wifi gun
- The processing of instantaneous signals, the signal is -50mV-0V, the time length is 16us, such instantaneous signals need to be extracted and processed...