《嵌入式硬件(十):基于IMX6ULL的按键操作》
一、提高代码复用性
顶层与底层硬件区分开
gpio.c
#include "gpio.h"//传递参数为初始化的GIPIO的组,引脚号,状态void init_gpio(GPIO_Type *base, int pin, struct GPIO_Type_t *gpio)
{if(gpio->direction == gpio_output){base->GDIR |= (1 << pin);if(gpio->defalut_value){base->DR |= (1 << pin);}else{base->DR &= ~(1 << pin);}}else{base->GDIR &= ~(1 << pin);}
}void write_gpio(GPIO_Type *base, int pin, int value)
{if(value){base->DR |= (1 << pin);}else{base->DR &= ~(1 << pin);}
}int read_gpio(GPIO_Type *base, int pin)
{return (base->DR & (1 << pin)) != 0;//返回1高电平,0低电平
}
gpio.h
#ifndef _GPIO_H_
#define _GPIO_H_#include "MCIMX6Y2.h"enum GPIO_Diection
{gpio_output,gpio_input
};struct GPIO_Type_t
{enum GPIO_Diection direction;int defalut_value;
};extern void init_gpio(GPIO_Type *base, int pin, struct GPIO_Type_t *gpio);
extern void write_gpio(GPIO_Type *base, int pin, int value);
extern int read_gpio(GPIO_Type *base, int pin);#endif
根据上面的函数,那么我们的代码:led.c,beep.c就可以修改
led.c
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "led.h"
#include "gpio.h"void enable_clocks(void)
{CCM->CCGR0 = 0xffffffff;CCM->CCGR1 = 0xffffffff;CCM->CCGR2 = 0xffffffff;CCM->CCGR3 = 0xffffffff;CCM->CCGR4 = 0xffffffff;CCM->CCGR5 = 0xffffffff;CCM->CCGR6 = 0xffffffff;
}void init_led(void)
{IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0x10b0);//GPIO1 -> GDIR |= (1 << 3);struct GPIO_Type_t t = {.direction = gpio_output,.defalut_value = 1,};init_gpio(GPIO1, 3, &t);
}void led_on(void)
{//GPIO1 -> DR &= ~(1 << 3);write_gpio(GPIO1, 3, 0);
}void led_off(void)
{//GPIO1 -> DR |= (1 << 3);write_gpio(GPIO1, 3, 1);
}void led_nor(void)
{//GPIO1 -> DR ^= (1 << 3);write_gpio(GPIO1, 3, !read_gpio(GPIO1, 3)) ;
}void delay(unsigned int n)
{while(n--);
}
beep.c
#include "beep.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
#include "gpio.h"void init_beep(void)//1500
{IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01, 0);IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01, 0x10b0);//GPIO5 -> GDIR |= (1 << 1);struct GPIO_Type_t t = {.direction = gpio_output,.defalut_value = 1,};init_gpio(GPIO5, 1, &t);
}void beep_on(void)
{//GPIO5 -> DR &= ~(1 << 1);write_gpio(GPIO5, 1, 0);
}void beep_off(void)
{//GPIO5 -> DR |= (1 << 1);write_gpio(GPIO5, 1, 1);
}void beep_nor(void)
{//GPIO5 -> DR ^= (1 << 1);write_gpio(GPIO5, 1, !read_gpio(GPIO5, 1)) ;
}
二、按键原理
1.底板原理图
key0按下低电平,不按高电平
2.功能复用
3.电气属性
加一个22k的上拉电阻,值为0xF0B0
4.输入输出方向
5.数据寄存器
三、步骤
1)初始化时钟
2)设置引脚功能复用(GPIO)
3)引脚电气属性(功率、电阻)
4)设置外设引脚的输入输出方向
5)设置数据寄存器拉低/拉高电平
四、代码
结构与之前一样
1.bsp
1)key.c
#include "key.h"
#include "fsl_iomuxc.h"
#include "gpio.h"
#include "core_ca7.h"void init_key(void)
{IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);struct GPIO_Type_t t ={.direction = gpio_input};init_gpio(GPIO1, 18, &t);
}int key_pressed(void)
{if(read_gpio(GPIO1, 18) == 0){return 1;}else{return 0;}
}
2)key.h
#ifndef _KEY_H_
#define _KEY_H_#include "fsl_iomuxc.h"
#include "gpio.h"extern void init_key(void);
extern int key_pressed(void);#endif
3)led.c---beep.c
2.project
1)main.c
#include "led.h"
#include "beep.h"
#include "MCIMX6Y2.h"
#include "key.h"
#include "core_ca7.h"void enable_clocks(void)
{CCM->CCGR0 = 0xFFFFFFFF;CCM->CCGR1 = 0xFFFFFFFF;CCM->CCGR2 = 0xFFFFFFFF;CCM->CCGR3 = 0xFFFFFFFF; CCM->CCGR4 = 0xFFFFFFFF;CCM->CCGR5 = 0xFFFFFFFF;CCM->CCGR6 = 0xFFFFFFFF;
}void delay(unsigned int n)
{while(n--);
}int main(void)
{enable_clocks();init_led();init_beep();init_key();while(1){if(key_pressed()){led_on();beep_on();}}return 0;
}
2)start.S
.global _start_start:ldr pc, =_reset_handlerldr pc, =_undefine_handlerldr pc, =_svc_handlerldr pc, =_prefetch_abort_handlerldr pc, =_data_abort_handlerldr pc, =_reserved_handlerldr pc, =_irq_handlerldr pc, =_fiq_handler_undefine_handler:ldr pc, =_undefine_handler_svc_handler:ldr pc, =_svc_handler_prefetch_abort_handler:ldr pc, =_prefetch_abort_handler_data_abort_handler:ldr pc, =_data_abort_handler_reserved_handler:ldr pc, =_reserved_handler_irq_handler:ldr pc, =_irq_handler_fiq_handler:ldr pc, =_fiq_handler_reset_handler:mrs r0, cpsrbic r0, r0, #0x1Forr r0, r0, #0x12 //irqmsr cpsr, r0ldr sp, =0x80600000mrs r0, cpsrbic r0, r0, #0x1Forr r0, r0, #0x1F //systemmsr cpsr, r0 ldr sp, =0x80400000bl _bss_clearb main_bss_clear:ldr r0, =__bss_startldr r2, =__bss_end
loop:mov r1, #0str r1, [r0]add r0, r0, #4cmp r0, r2blt loopbx lrfinished:b finished