08. 按键输入

08. 按键输入

  • 按键原理图
  • 代码编写
    • GPIO驱动代码
    • 按键驱动代码
    • 主函数
  • 加上清除BSS段,代码不运行

按键原理图

08. 按键输入_第1张图片
按键KEY0连接到了UART1_CTS上。默认情况下,KEY0为高,当按下KEY0后,UART1_CTS为低电平

代码编写

在bsp下创建一个key和一个gpio文件夹

  1. 设置UART1_CTS复用为GPIO1_IO88
  2. 设置UART1_CTS的电气属性
  3. 配置GPIO_IO08为输出模式
  4. 读取按键值,获取高低电平

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);然后再赋值

你可能感兴趣的:(嵌入式硬件)