TQ210_Bare Metal Programming (II)——Button Control LED Light

Publisher:自在逍遥Latest update time:2020-12-25 Source: eefocusKeywords:TQ210 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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 */



Keywords:TQ210 Reference address:TQ210_Bare Metal Programming (II)——Button Control LED Light

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

TQ210 - s5pv210u-boot.lds analysis
/*  * (C) Copyright 2002  * Gary Jennejohn, DENX Software Engineering, gj@denx.de  *  * See file CREDITS for list of people who contributed to this  * project.  *  * This program is free software; you can redistribute it and/or  * modify it under the terms of the GNU General Public License as  * published by the Fre
[Microcontroller]
TQ210 Learning Path (1) - Migrating Software
Before compiling, install the cross-compilation tool. Just write the path of the compilation tool into the environment variable PATH. Software migration: 1. Download the source code from the official website and put it in the development environment. 2. Unzip. For example, tar zxvf xxx.tar.gz 3. Generate Makefile. I
[Microcontroller]
TQ210 —— NandFlash
The TQ210 development board has a 1Gbyte NAND FLASH onboard - K9K8G08U0B. By consulting the K9K8G08U0B chip manual, you can get the following information: (Theoretical knowledge will not be introduced again) K9K8G08U0B : (1G + 32M) x 8bit total size Data Register: (2K + 64) x 8bit data register Page Program: (2K + 64)
[Microcontroller]
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号