初学嵌入式,从一本书上学习到下面代码,对照自己的开发板写了以下代码,两个LED常亮,按键无反映。
测试过以下情况:
1.硬编码控制LED灯点亮、熄灭没有问题
2.将判断按键是否按下的判断调换是全熄灭
怀疑没有独到按键状态,其中GPN在手册中的每个管脚是 XEINTn/GPNn (既可以做中断,又可以做GPIO?)
我拿到的原理图上按键连接的地方 是 EINT9,EINT12,EINT1,EINT3
问题:
1.GPN 作为中断的话使用不能同时作为普通GPIO使用么?是连接电路不同么?
2.电路设计为中断模式,可以初始化为普通GPIO使用么?
2.如果问题一答案是可以同时用,我的代码有哪些问题呢?
哪位老师提供思路,万分感谢。
crt0.s
- Assembly code
PRESERVE8 AREA |crt0|, CODE, READONLY IMPORT _main ; C entrypoint for Steppingstone loader. ENTRYstart LDR R0, =0x7E004000 ; WATCHDOG 寄存器地址 MOV R1, #0x0 STR R1, [R0] ; WTCON[0] Enable or disable bit of ; Watchdog timer output for reset signal. LDR sp, =1024*8 ; 设置堆栈,6410 I-RAM 是 8KB ; SD 卡启动后 BL1 的 8K 内容被复制到内部RAM BL _main ; 调用 C 程序中的 main 函数end B end END
key_led.c
- C/C++ code
#define GPECON (*(volatile unsigned long *)0x7F008080)#define GPEDAT (*(volatile unsigned long *)0x7F008084)#define GPNCON (*(volatile unsigned long *)0x7F008830)#define GPNDAT (*(volatile unsigned long *)0x7F008834)/* * LED1-2 对应 GPE0、GPE1 */#define GPE0_out (1<<0*4)#define GPE1_out (1<<1*4)/* * K1-K4 对应GPN9、GPN12、GPN1、GPN3 */#define GPN9_in ~(3<<9*2)#define GPN12_in ~(3<<12*2)#define GPN1_in ~(3<<1*2)#define GPN3_in ~(3<<3*2)int _main(){ unsigned long dwDat; GPECON = GPE0_out | GPE1_out; GPNCON = GPNCON & GPN9_in & GPN12_in & GPN1_in & GPN3_in; while(1) { dwDat = GPNDAT; if(dwDat & (1<<9)) GPEDAT &= ~(1<<0); else GPEDAT |= (1<<0); if(dwDat & (1<<12)) GPEDAT &= ~(1<<1); else GPEDAT |= (1<<1); }}
------解决方案--------------------
1. GPIO可以按照需要配置成不同的功能, 但是同一时刻只能具有一种功能,.从楼主的代码设置GPNCON看, GPN作为输入是没有问题的. 而且这个时候也只具有输入功能.
2. 出现楼主描述的情况, 应该是输入Pin的上下拉电阻没有配置. 如果电路图上按键按下GPN9与地导通,从而GPE0置为高的话, 那么在没有按下GPN9时, Pin的状态是不能确定的.
3. dwDat 是否也需要声明成volatile变量呢.
------解决方案--------------------
补充楼上的,
(1)我记得以前写单片机的按键检测的时候,有一段防抖动代码,你看看是不是这个原因
(2)程序的while循环里面直接加printf()调试,看按键的时候有没有读到变化