历史上的今天
今天是:2024年12月25日(星期三)
2020年12月25日 | TQ210_裸机编程(二)——按键控制LED灯
2020-12-25 来源:eefocus
首先我们可以在开发板配套材料中找到按键的电路图,E:TQ210_CD开发板配套电路图Bottompdf格式TQ210_BOARD_V4_20121023。

可以看到按键key1~key6对应的地址线为XEINT0~XEINT5,我们暂时就只用前面几个按键。
然后我们再找地址线在板子中相应的引脚号。

可以看到 按键地址线XEINT0~XEINT5对应的管脚号为GPH0_1~GPH0_5。
现在在S5PV210_UM_REV1.1文档中就能找到GPH0的控制寄存器,对应的控制6个按键。

将按键控制寄存器都设置为外部中断处理。然后去设定外部中断的处理相应参数。
外部中断要设置2个中断寄存器,EXT_INT_CON,EXT_INT_MASK。

由于按键按下时为低电平,所以全部设置为Falling edge triggered。
设置完EXT_INT_CON,还要设置EXT_INT_MASK,(外部中断控制寄存器)。

将需要使用的按键对应的外部中断处理 设置为允许中断。
再设置中断选择寄存器VIC0INTSELECT,选择中断模式(一般为IRQ模式)。

之后再设置VICINTENABLE寄存器,中断使能寄存器。

当中断发生时,需要一个存放中断处理的寄存器VICVECTADDR,中断发生后,就跳转到该寄存器里的函数开始执行。
例如:
VIC0VECTADDR0 = (unsigned int)key_isr;
中断发生后就跳转到key_isr处去执行了。
但是涉及到跳转执行的时候,就需要考虑保护现场的操作了。
例如:在key_isr中
key_isr:
/* 计算返回地址:PC的值等于当前执行的地址+8,
** 当CPU正要执行某条指令时(还未执行),被中断,
** 这是这条刚要执行的指令的地址刚好=PC-4(可查三级流水线工作原理) */
sub lr, lr, #4
stmfd sp!, {r0-r12, lr} /* 保护现场 ,由于不知道使用的具体哪个通用寄存器,所以讲0~12全部压栈*/
bl key_handle
/* 恢复现场 */
ldmfd sp!, {r0-r12, pc}^ /* ^表示把spsr恢复到cpsr */
由于用到中断处理,所以对cpsr(当前程序状态寄存器)要进行参数设置,


要使用IRQ中断,就要使i位为0,
/* 开总中断 */
mrs r0, cpsr /*传送cpsr的内容到r0*/
bic r0, r0, #0x00000080 /* 清楚第7位,IRQ中断禁止位,写0使能IRQ */
msr cpsr, r0 /*传送r0的内容到cpsr*/
BIC―――――位清除指令
指令格式:
BIC{cond}{S} Rd,Rn,operand2
BIC指令将Rn 的值与操作数operand2 的反码按位逻辑”与”,结果存放到目的寄存器Rd 中。指令示例:BIC R0,R0,#0x0F ;将R0最低4位清零,其余位不变。
在上面保护现场的时,程序跳转到key_handle执行。
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;
}
程序中EXT_INT_0_PEND寄存器为发生中断后的数据变化。1就是发生了中断。

整体源代码如下:
/*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 /* 声明一个全局的标号 */
.global key_isr
_start:
/* 设置栈,以调用c函数 */
ldr sp, =0x40000000
/* 开总中断 */
mrs r0, cpsr
bic r0, r0, #0x00000080 /* 清楚第7位,IRQ中断禁止位,写0使能IRQ */
msr cpsr, r0
bl main /* 跳转到C函数去执行 */
halt:
b halt
key_isr:
/* 计算返回地址:PC的值等于当前执行的地址+8,
** 当CPU正要执行某条指令时(还未执行),被中断,
** 这是这条刚要执行的指令的地址刚好=PC-4 */
sub lr, lr, #4
stmfd sp!, {r0-r12, lr} /* 保护现场 */
bl key_handle
/* 恢复现场 */
ldmfd sp!, {r0-r12, pc}^ /* ^表示把spsr恢复到cpsr */
上一篇:STM32 Flash详解
下一篇:STM32 IIC详解
史海拾趣
|
新的FT2232C型USB UART/FIFO电路的特征及应用 摘要:FT2232C是一款USB到UART/FIFO转换电路。文中介绍FT2232C的特性、工作原理及应用领域,给出该电路在各种不同场合的典型应用电路。 关键词:通用串行总线;通用异步收发模式/先进先出;FT2232C 引言 在进行室外信息采集时, ...… 查看全部问答> |
|
本信息来自合作QQ群:arm linux fpga 嵌入0群 49900581(超级群) 群主在坛子里ID:wangkj 我问一下各位大虾, 我把U盘插入linux系统的电脑时有一个设备U盘节点/dev/sdb1 当我用open函数打开时打不开 open(\"/dev/sdb1\" ...… 查看全部问答> |
|
请教:使用Identify RTL Debugger出现的问题 我用的是V5 XC5VLX50的FPGA,我建了一个Synplify的工程,然后新建了一个identify instrument ,然后就调用Launch identify instrument ,就在打开它的过程中,出现了一个db_assert的错误提示,点确定 然后就什么都没了 ...… 查看全部问答> |
|
急需请教Raisonancec和COSMICC哪个的编译效果好? 编程环境:STVD +COSIC C,使用STM8S103F2 (4K flash +1K ram)编译从瑞萨单片机(4K flash + 1K RAM)移植过来的程序,编译提示错误信息如下 #error clnk Debug\\vma.lkf:1 segment .text size overflow (3146) The command: "clnk -l"C ...… 查看全部问答> |




