开发环境
Ubuntu
正点原子Linuxmini开发板
IMX6U芯片
Cortex-A7内核
硬件原理图
程序编写
为方便配置GPIO的读写功能,添加了bsp_gpio
bsp_gpio.h
#ifndef _BSP_GPIO_H#define _BSP_GPIO_H#define _BSP_KEY_H#include "imx6ul.h"/* 枚举类型和结构体定义 */typedef enum _gpio_pin_direction{kGPIO_DigitalInput = 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);#endif
bsp_gpio.c
#include "bsp_gpio.h"/** @description : GPIO初始化。* @param - base : 要初始化的GPIO组。* @param - pin : 要初始化GPIO在组内的编号。* @param - config : GPIO配置结构体。* @return : 无*/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);/* 设置默认输出电平 */}}/** @description : 读取指定GPIO的电平值 。* @param - base : 要读取的GPIO组。* @param - pin : 要读取的GPIO脚号。* @return : 无*/int gpio_pinread(GPIO_Type *base, int pin){return (((base->DR) >> pin) & 0x1);}/** @description : 指定GPIO输出高或者低电平 。* @param - base : 要输出的的GPIO组。* @param - pin : 要输出的GPIO脚号。* @param - value : 要输出的电平,1 输出高电平, 0 输出低低电平* @return : 无*/void gpio_pinwrite(GPIO_Type *base, int pin, int value){if (value == 0U){base->DR &= ~(1U << pin); /* 输出低电平 */}else{base->DR |= (1U << pin); /* 输出高电平 */}}
按键驱动,会通过调用gpio的函数完配置引脚为读功能
bsp_key.h
#ifndef _BSP_KEY_H#define _BSP_KEY_H#include "imx6ul.h"/* 定义按键值 */enum keyvalue{KEY_NONE = 0,KEY0_VALUE,KEY1_VALUE,KEY2_VALUE,};/* 函数声明 */void key_init(void);int key_getvalue(void);#endif
bsp_key.c
#include "bsp_key.h"#include "bsp_gpio.h"#include "bsp_delay.h"/** @description : 初始化按键* @param : 无* @return : 无*/void key_init(void){gpio_pin_config_t key_config;/* 1、初始化IO复用, 复用为GPIO1_IO18 */IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0);IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xF080);/* 3、初始化GPIO *///GPIO1->GDIR &= ~(1 << 18); /* GPIO1_IO18设置为输入 */key_config.direction = kGPIO_DigitalInput;gpio_init(GPIO1,18, &key_config);}/** @description : 获取按键值* @param : 无* @return : 0 没有按键按下,其他值:对应的按键值*/int key_getvalue(void){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;}
蜂鸣器驱动基本和LED驱动类似
bsp_beep.h
#ifndef __BSP_BEEP_H#define __BSP_BEEP_H#include "imx6ul.h"/* 函数声明 */void beep_init(void);void beep_switch(int status);#endif
bsp_beep.c
#include "bsp_beep.h"/** @description : 初始化蜂鸣器对应的IO* @param : 无* @return : 无*/void beep_init(void){/* 1、初始化IO复用,复用为GPIO5_IO01 */IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0);IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0X10B0);/* 3、初始化GPIO,GPIO5_IO01设置为输出 */GPIO5->GDIR |= (1 << 1);/* 4、设置GPIO5_IO01输出高电平,关闭蜂鸣器 */GPIO5->DR |= (1 << 1);}/** @description : 蜂鸣器控制函数,控制蜂鸣器打开还是关闭* @param - status : 0,关闭蜂鸣器,1 打开蜂鸣器* @return : 无*/void beep_switch(int status){if(status == ON)GPIO5->DR &= ~(1 << 1); /* 打开蜂鸣器 */else if(status == OFF)GPIO5->DR |= (1 << 1); /* 关闭蜂鸣器 */}
main.c
#include "bsp_clk.h"#include "bsp_delay.h"#include "bsp_led.h"#include "bsp_beep.h"#include "bsp_key.h"/** @description : main函数* @param : 无* @return : 无*/int main(void){int i = 0;int keyvalue = 0;unsigned char led_state = OFF;unsigned char beep_state = OFF;clk_enable(); /* 使能所有的时钟 */led_init(); /* 初始化led */beep_init(); /* 初始化beep */key_init(); /* 初始化key */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,内容基本没变,修改了目标名,添加了新加文件的路径
CROSS_COMPILE ?= arm-linux-gnueabihf-TARGET ?= keyCC := $(CROSS_COMPILE)gccLD := $(CROSS_COMPILE)ldOBJCOPY := $(CROSS_COMPILE)objcopyOBJDUMP := $(CROSS_COMPILE)objdumpINCDIRS := imx6ul \bsp/clk \bsp/led \bsp/delay \bsp/beep \bsp/gpio \bsp/keySRCDIRS := project \bsp/clk \bsp/led \bsp/delay \bsp/beep \bsp/gpio \bsp/keyINCLUDE := $(patsubst %, -I %, $(INCDIRS))SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))SFILENDIR := $(notdir $(SFILES))CFILENDIR := $(notdir $(CFILES))SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))OBJS := $(SOBJS) $(COBJS)VPATH := $(SRCDIRS).PHONY: clean$(TARGET).bin : $(OBJS)$(LD) -Timx6ul.lds -o $(TARGET).elf $^$(OBJCOPY) -O binary -S $(TARGET).elf $@$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis$(SOBJS) : obj/%.o : %.S$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<$(COBJS) : obj/%.o : %.c$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<clean:rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
编译烧写同前面一样

