08. 按键输入
- 按键原理图
- 代码编写
- GPIO驱动代码
- 按键驱动代码
- 主函数
- 加上清除BSS段,代码不运行
按键原理图
按键KEY0连接到了UART1_CTS上。默认情况下,KEY0为高,当按下KEY0后,UART1_CTS为低电平
代码编写
在bsp下创建一个key和一个gpio文件夹
- 设置UART1_CTS复用为GPIO1_IO88
- 设置UART1_CTS的电气属性
- 配置GPIO_IO08为输出模式
- 读取按键值,获取高低电平
GPIO驱动代码
bsp_gpio.h
#pragma once
#include "imx6ul.h"
typedef enum _gpio_pin_direction
{
kGPIO_DigitalInpput = 0U, // 输入
kGPIO_DigitalOutput = 1U, // 输出
} gpio_pin_direction_t;
typedef struct _gpio_pin_config
{
gpio_pin_direction_t direction; // GPIO方向,输入还是输出
uint8_t outputLogic; // 如果是输出的话,默认输出电平
} gpio_pin_config_t;
void gpio_init(GPIO_Type *base, int pin, gpio_pin_config_t *config);
int gpio_pinread(GPIO_Type *base, int pin);
void gpio_pinwrite(GPIO_Type *base, int pin, int value);
bsp_gpio.c
#include "bsp_gpio.h"
void gpio_init(GPIO_Type *base, int pin, gpio_pin_config_t *config)
{
if(config->direction == kGPIO_DigitalInput) // 输入
{
base->GDIR &= ~(1 << pin);
}
else // 输出
{
base->GDIR |= 1 << pin;
gpio_pinwrite(base, pin, config->outputLogic); // 默认输出电平
}
}
int gpio_pinread(GPIO_Type *base, int pin)
{
return (((base->DR) >> pin) & 0x1);
}
// 指定GPIO输出高低电平
void gpio_pinwrite(GPIO_Type *base, int pin, int value)
{
if(value == 0U)
{
base->DR &= ~(1U<<pin); // 输出低电平
}
else
{
base->DR |= (1U<<pin); // 输出高电平
}
}
按键驱动代码
bsp_key.h
#include "imx6ul.h"
// 定义按键键值
enum keyvalue
{
KEY_NONE = 0,
KEY_VALUE,
};
void key_init();
int key_getvalue();
bsp_key.c
void key_init()
{
gpio_pin_config_t key_config;
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0); // 复用为GPIO1_IO18
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xf080);
key_config.direction = kGPIO_DigitalInput;
gpio_init(GPIO1, 18, &key_config);
}
int key_getvalue()
{
int ret = 0;
static unsigned char release = 1; // 按键松开
if((release == 1)&&(gpio_pinread(GPIO1, 18)==0)) // key0按下
{
delay(10);
release = 0; // 标记按键按下
if(gpio_pinread(GPIO1, 18)==0)
ret = KEY0_VALUE;
}
else if(gpio_pinread(GPIO1, 18) == 1)
{
ret = 0;
release = 1; // 标记按键释放
}
return ret;
}
主函数
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
int main()
{
int i = 0;
int keyvalue = 0;
unsigned char led_state = OFF;
unsigned char beep_state = OFF;
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)
{
i = 0;
led_state = !led_state;
led_switch(LED0, led_state);
}
delay(10);
}
return 0;
}
makefile文件
修改TARGET为key,INCDIRS和SRCDIRS中追加gpio和key的路径
加上清除BSS段,代码不运行
__bss_start=0x87800289。对于32位SOC来说,一般是以4字节访问的,因此会从0x87800288开始清除bss段,但是该地址不属于bss段,所以会出问题,也就需要我们进行内存对齐,即__bss_start=0x8780028c。就是在__bss_start之前进行. = ALIGN(4);然后再赋值