需求:找到控制按键的寄存器位置,设置模式,以及数据
1.本次使用的是开发板上k2按键和led3,先查原理图
可以观察到他俩使用的都是GPX1的寄存器,只是位不同,led灯的控制在于我们需要设置输出模式,亮就输出高电平,灭则是低电平,分别对应1和0, 按键检测需要设置输入模式,低电平表示按下,高电平表示未按下
2.接下来就去查芯片手册,芯片手册的第六章GPIO里直接搜索GPX1,可以看到关于GPX1的相关寄存器,我们需要选择设置模式的GPX1CON以及发送数据的GPX1DAT。
3. 在汇编的启动文件里设置好异常向量表,栈,以及启动,跳转到我们的main.c文件
以下是汇编文件代码 start.s
.global _start
_start:
b reset
ldr pc,_undefined_instruction
ldr pc,_software_interrupt
ldr pc,_prefetch_abort
ldr pc,_data_abort
ldr pc,_not_used
ldr pc,_irq
ldr pc,_fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word _software_interrupt
_prefetch_abort: .word _prefetch_abort
_data_abort: .word _data_abort
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq
svc_stack: .space 16*8 /* set svc stack */
svc_stacktop: .word svc_stack+16*8
usr_stack: .space 16*8 /*set usr stack*/
usr_stacktop: .word usr_stack+16*8
swi_flag: .space 4
reset:
/*set mode : svc*/
mrs r0,cpsr
bic r0,#0x1F
orr r0,#0xd3
msr cpsr,r0
/*set tabel address */
ldr r0,=0x41000000
mcr p15,0,r0,c12,c0,0
/*initialization svc_stack*/
ldr r0,=svc_stacktop
ldr sp,[r0]
/* set mode: usr */
mrs r0,cpsr
bic r0,#0x1F
orr r0,#0xd0
msr cpsr,r0
ldr r0,=usr_stacktop
ldr sp,[r0]
bl main
4.接下来就是main.c文件
/* GPX1CON 0x11000C20 [3:0] 0x1 output
*
* GPX1DAT 0x11000C24 [0] 0x1 high
* */
#define GPX1CON *(volatile unsigned int*)0x11000C20 //led3 k2
#define GPX1DAT *(volatile unsigned int*)0x11000C24
int main()
{
GPX1CON = GPX1CON & ~(0xF) | (0x1); //设置led的输出模式
GPX1CON = GPX1CON & ~(0xF<<4); //input 设置按键的输入模式
while(1){
if((GPX1DAT & (1<<1)) == 0){
GPX1DAT = GPX1DAT | (0x1);
}else{
GPX1DAT = GPX1DAT & ~(0x1);
}
}
return 0;
}
由于led是GPX1CON的第0-3位,所以我们需要先把它的0-3位清0,然后设置输出模式,就需要或 0x1
由于按键是GPX1CON的第4-7位,所以我们需要把它的4-7位直接置为0,0就是输入模式
如何检测按键按下呢?通过取出GPX1DAT的第1位,让它与0作比较,如果是0说明是低电平,表示按键按下,反则表示未按下