本节学习按键输入,先拷贝上一节工程文件,
1、驱动编写
新建 key 的 .h 和 .c 文件;
再查看一下硬件原理图如下;
由此可知,KEY0 按键接在 UART1_CTS 引脚上,默认情况下为高电平,按键按下为低电平;和之前不同的是,GPIO 由输出变成了输入;
参考数据手册;
定义读取按键值的函数;
// 读取按键值
int read_key(void)
{
int ret = 0;
ret = ((GPIO1->DR) >> 18) & 0x1;
return ret;
}
int key_getvalue(void)
{
int ret = 0;
static unsigned char release = 1; // 为 1 表示按键释放
if((release == 1) && (read_key() == 0)) // 按键按下
{
delay_ms(10);
release = 0;
if(read_key() == 0) // 按键有效
{
ret = KEY0_VALUE;
}
}
else if(read_key() == 1) // 没有按下
{
ret = KEY_NONE;
release = 1;
}
return ret;
}
在头文件中声明;
2、编写 main.c
#include "main.h"
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
int main(void)
{
int i = 0;
unsigned char led_state = OFF;
unsigned char beep_state = OFF;
int keyvalue = 0;
clk_enable();
led_init();
beep_init();
key_init();
while(1)
{
// 按键处理控制蜂鸣器
keyvalue = key_getvalue();
if(keyvalue) // 如果按键值为正则是有效的按键值
{
switch (keyvalue)
{
case KEY0_VALUE:
beep_state = !beep_state;
beep_switch(beep_state);
break;
}
}
i++;
if(i == 50) // 50*10=500
{
i = 0;
led_state = !led_state;
led_switch(LED0,led_state);
}
delay_ms(10);
}
return 0;
}
3、修改部分内容
首先就是修改头文件包含路径;
修改 Makefile 文件;
4、编译烧写
下载之后 led 亮了一次,就不亮了,key0 是可以控制 beep 的,那么肯定是 led 相关的地方出了问题,找到 led 控制的函数,才发现参数写错了,按照以下修改;
再次编译工程,烧写之后功能正常了;
I.MX6ULL_key
5、回顾,问题解决
解决另一个问题,在【ARM 裸机】NXP 官方 SDK 使用 这一小节中,加上清除 bss 段的代码是不会运行的,所以清除 bss 段的代码被注释掉了,这是因为对 32 位的芯片来说,是 4 字节访问的,查看反汇编文件可知;
_bss_start 的起始地址是 0x87800271,这是不能被 4 整除的,所以要对 _bss_start 进行 4 字节对齐操作;
再来看一下反汇编文件;
编译工程烧写之后正常运行。