目录

一、硬件原理分析

二、寄存器分析

1、时钟源初始化

2、设置 IO 复用

3、初始化 IO 复用引脚(设置电气属性)

4、初始化GPIO

三、汇编代码(start.s)

四、公共头文件(imx6u.h)

四、C 代码编写

1、clk 模块(bsp_clk.c)

2、led 模块(bsp_led.c)

2、delay 模块(bsp_delay.c)

3、key 模块(bsp_key.c)

4、main.c

五、链接脚本(imx6u.lds)

六、Makefile 文件(测试工程的整体结构)


一、硬件原理分析

我们在《imx6ull 底板原理图》中找到按键 KEY 模块。R12 是一个上拉电阻,当按键 KEY0 没有按下时,KEY0 处于高电平;当按键KEY0 按下时,KEY0 接地,此时KEY0 将变为低电平。

接下来我们要去 核心板原理图上找 KEY0 连接的哪个引脚。我们发现是和 UART1_CTS 这个引脚相连。

二、寄存器分析

1、时钟源初始化

这里就不再赘述,可以参考:时钟源初始化

2、设置 IO 复用

按键属于 IO 的范畴,既然和 IO 有关,那我们就要去找第32章的 IOMUX(IO复用选择器)。根据之前的习惯,我们要找和 UART1_CTS 相关的复用寄存器。

IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B 就是我们要找的寄存器了。UART1_CTS 似乎可以复用为很多功能,我们选择的是复用为 GPIO1_IO18 功能。其他位不变,低四位设为 0101。

寄存器: IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B
基地址: 0x20E008C
初始化值: 0x5    # 低四位为0101,其他位不变

注意:

虽然找的是 UART,但不代表是复用为 UART功能,UART 是用于数据传输的;GPIO 只是简单控制某个设备的开关,或者读取某个设备的状态。

3、初始化 IO 复用引脚(设置电气属性)

接下来我们要初始化复用引脚,此时要找前缀为 IOMUXC_SW_PAD_xxx 而且和 UART 相关的寄存器。然后设置每一位。多数都和驱动LED时的设置一样。(初始化 IO 复用)

  • 0:0
  • 2-1:00
  • 5-3:000 (这里要禁用输出,相当于用于输入)
  • 7-6:10
  • 10-8:000
  • 11:0
  • 12:1
  • 13:1(选择 pull 功能)
  • 15-14:11(按键 KEY0 默认是上拉状态)
  • 16:0
  • 31-17:剩余为 0
寄存器: IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B
基地址: 0x20E0318
初始化值: 0xF080    

4、初始化GPIO

从“设置IO复用”部分我们可以知道,UART_CTS 可被复用为 GPIO1_IO18,因此我们需要去初始化 GPIO1_IO18 引脚,设置的方式和驱动LED使用的方式类似。

寄存器: GPIO1_GDIR
基地址: 0x209C004
初始值: GPIO1_GDIR &= ~(1 << 18)    # 因为是GPIO1的第18个引脚设为输入,即第 18 bit应为0寄存器: GPIO1_DR
基地址: 0x209C000
初始值: - 低电平: GPIO1_DR &= ~(1 << 18)- 高电平: GPIO1_DR |= (1 << 18)

三、汇编代码(start.s)

汇编代码用于搭建C语言环境。关于汇编代码,可以参考之前驱动LED的汇编代码:汇编代码解析

四、公共头文件(imx6u.h)

公共头文件保存了要用到的寄存器的基地址。

#ifndef _IMX6U_H
#define _IMX6U_Htypedef unsigned int uint32_t;/** 时钟相关寄存器地址*/
#define CCM_CCGR0          *((volatile uint32_t*)0x20C4068)
#define CCM_CCGR1          *((volatile uint32_t*)0x20C406C)
#define CCM_CCGR2          *((volatile uint32_t*)0x20C4070)
#define CCM_CCGR3          *((volatile uint32_t*)0x20C4074)
#define CCM_CCGR4          *((volatile uint32_t*)0x20C4078)
#define CCM_CCGR5          *((volatile uint32_t*)0x20C407C)
#define CCM_CCGR6          *((volatile uint32_t*)0x20C4080)/** IOMUX 相关寄存器地址*/
#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03   *((volatile uint32_t*)0x020E0068)        // IO复用为 GPIO1_IO03
#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03   *((volatile uint32_t*)0x020E02F4)        // 设置复用引脚的电气属性#define IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B *((volatile uint32_t*)0x20E008C)          // IO 复用为 GPIO1_IO18
#define IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B *((volatile uint32_t*)0x20E0318)          // 设置复用引脚的电气属性/** 设置GPIO输出相关寄存器地址*/
#define GPIO1_DR            *((volatile uint32_t*)0x0209C000)         // GPIO输出
#define GPIO1_GDIR          *((volatile uint32_t*)0x0209C004)         // 设置输入还是输出#endif 

四、C 代码编写

为了验证开关,我们加入之前的 led 代码,之前的 led 代码已经被封装好了,直接调用函数即可。我们的目的是通过开关控制灯的亮灭。

1、clk 模块(bsp_clk.c)

void clk_init()
{CCM_CCGR0 = 0xffffffff;CCM_CCGR1 = 0xffffffff;CCM_CCGR2 = 0xffffffff;CCM_CCGR3 = 0xffffffff;CCM_CCGR4 = 0xffffffff;CCM_CCGR5 = 0xffffffff;CCM_CCGR6 = 0xffffffff;
}

2、led 模块(bsp_led.c)

void led_init()
{/* 1、设置IO复用为GPIO1_IO03 */IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x5;/* 2、初始化复用引脚,设置电气属性 */IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 = 0x10B0;/* 3、初始化GPIO1 */GPIO1_GDIR |= (1 << 3);
}void led_on()
{GPIO1_DR &= ~(1 << 3);
}void led_off()
{GPIO1_DR |= (1 << 3);
}void switch_led(uint8_t status)
{if (status == ON){led_on();}else{led_off();}
}

2、delay 模块(bsp_delay.c)

void delay_short(volatile unsigned int n)
{while(n--){}
}void delay(volatile unsigned int n)
{while(n--){delay_short(0x7ff);}
}

3、key 模块(bsp_key.c)

void key_init()
{/* 1、设置IO复用为GPIO1_IO03 */IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B = 0x5;/* 2、初始化复用引脚,设置电气属性 */IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B = 0xF080;/* 3、初始化GPIO1 */GPIO1_GDIR &= ~(1 << 18);
}int read_key()
{int ret = 1;static unsigned char release = 1;       /* 按键松开 */ if ((release==1)&&((GPIO1_DR >> 18) & 0x01) == 0){delay(10);        /* 延时消抖*/release = 0;  /* 标记按键按下 */if (((GPIO1_DR >> 18) & 0x01) == 0){ret = 0;}}else if((GPIO1_DR >> 18) & 0x01 == 1){ret = 1;release = 1;}return ret;
}

4、main.c

int main(void)
{clk_init();     // 初始化时钟led_init();     // 初始化LEDkey_init();     // 初始化按键led_on();       // LED 初始为亮while (1){if (read_key() == 0){led_off(); }delay(1000);led_on();}return 0;
}

五、链接脚本(imx6u.lds)

SECTIONS
{. = 0x87800000;.text :{obj/start.o*(.text)}.rodata ALIGN(4) : { *(.rodata) }.data ALIGN(4) : { *(.data) }. = ALIGN(4);__bss_start = . ;.bss ALIGN(4) : { *(.bss) *(COMMON) }__bss_end = . ;
}

六、Makefile 文件(测试工程的整体结构)

测试工程的结构如下:

# ################################################################
# # 指定编译器、获取源文件、指定目标文件的生成位置
# ################################################################
# 编译器
TOOLCHAIN_PATH      := /home/pigeon/workspace/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
CC                  := $(TOOLCHAIN_PATH)/arm-linux-gnueabihf-gcc
LD                  := $(TOOLCHAIN_PATH)/arm-linux-gnueabihf-ld
OBJCOPY             := $(TOOLCHAIN_PATH)/arm-linux-gnueabihf-objcopy
OBJDUMP             := $(TOOLCHAIN_PATH)/arm-linux-gnueabihf-objdump# 目标文件名
TARGET_NAME     := key
OBJ_DIR         := obj# 引入头文件
INCLUDES        := -Icommon -Ibsp# 获取到一级子目录下的源文件
DIR1            := project
SOURCES         += $(wildcard ${DIR1}/*.c ${DIR1}/*.s)# 获取到二级子目录下的源文件
DIR2            := bsp
SUBDIRS         = $(shell ls $(DIR2) -l | grep ^d | awk '{print   $$9}')
SOURCES         += $(foreach subdir,${SUBDIRS}, $(wildcard $(DIR2)/${subdir}/*.c))# 创建 $(OBJ_DIR) 目录
$(shell \if test -e $(OBJ_DIR); then \rm -rf $(OBJ_DIR)/*; \else \mkdir -p $(OBJ_DIR); \
fi)# 生成 .o 文件
define compile
OBJ = $(if $(findstring .c,$1), $(patsubst %.c,%.o,$1), $(patsubst %.s,%.o,$1))
NODIR_OBJ = $$(notdir $$(OBJ))
$$(shell $$(CC) -o $$(OBJ_DIR)/$$(NODIR_OBJ) -c $1 $$(INCLUDES))
OBJ_FILE    += $$(OBJ_DIR)/$$(NODIR_OBJ)
endefOBJ_FILE       :=
$(foreach src_file, ${SOURCES}, $(eval $(call compile, $(src_file))))   # 遍历每一个源文件,同时生成对应的 .o 文件# ################################################################
# # 编译生成目标文件、库文件/执行文件
# ################################################################
default:$(LD) -Timx6u.lds -o $(OBJ_DIR)/$(TARGET_NAME).elf $(OBJ_FILE)$(OBJCOPY) -O binary -S -g $(OBJ_DIR)/$(TARGET_NAME).elf $(OBJ_DIR)/$(TARGET_NAME).bin$(OBJDUMP) -D $(OBJ_DIR)/$(TARGET_NAME).elf > $(OBJ_DIR)/$(TARGET_NAME).dis# ################################################################
# # 伪目标/自定义函数
# ################################################################
.PHONY:clean
clean:rm -rf ${OBJ_DIR}/*

【裸机开发】按键输入实验相关推荐

  1. 【正点原子MP157连载】第十二章 按键输入实验-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  2. ARM(IMX6U)裸机按键输入实验(BSP+SDK、GPIO输入与输出、按键消抖)

    参考:Linux之ARM(IMX6U)裸机按键输入实验(GPIO的输出与输入) 作者:一只青木呀 发布时间: 2020-08-17 21:43:37 网址:https://blog.csdn.net/ ...

  3. 判断按键值_ALIENTEK 阿波罗 STM32F767 开发板资料连载第七章 按键输入实验

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第七章 按键输入实验 上 ...

  4. 【正点原子STM32连载】 第十五章 按键输入实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

    1)实验平台:正点原子stm32f103战舰开发板V4 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视 ...

  5. stm32 工业按键检测_「正点原子STM32Mini板资料连载」第七章 按键输入实验

    1)实验平台:正点原子STM32mini开发板 2)摘自<正点原子STM32 不完全手册(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第七章 按键输入实验 上一章,我们介 ...

  6. 【STM32学习笔记】(11)——按键输入实验详解

    按键输入实验 实验内容:通过 ALIENTEK 精英 STM32F103 上已有的 3 个按键(KEY_UP.KEY0 和 KEY1),来控制板上的 2 个 LED(DS0 和 DS1)和蜂鸣器,其中 ...

  7. 嵌入式 按键输入实验(修改版)

    按键输入实验 1. 硬件设计: 开发板上有4个按键:key0,key1,key2和wk_up,分别接在PE4,PE3,PE2和PA0上: 2. 软件设计: KEY0. KEY1 和 KEY2 是低电平 ...

  8. 基于STM32F103ZET6库函数按键输入实验

    基于STM32F103ZET6库函数按键输入实验 GPIO_ReadInputDataBit函数 硬件设计 软件设计 我们将通过 ALIENTEK 精英 STM32F103 上载有的 3 个按钮(KE ...

  9. 【吃灰板子捡起来】按键输入实验

    按键输入实验 一.驱动源码 二.应用源码 三.实验总结 一.驱动源码 硬件原理图 #include "nuc972_gpio.h"#include <linux/module ...

  10. Linux按键输入实验(体验一下输入驱动,实际开发使用input子系统处理)

    目录 Linux下按键驱动原理(使用原子操作) 硬件原理图分析 实验程序编写 修改设备树文件 按键驱动程序编写 编写测试APP(循环读取按键值) 运行测试 编译驱动程序和测试APP 运行测试(whil ...

最新文章

  1. 文件解析库doctotext源码分析
  2. R语言ggplot2可视化时间序列数据并突出标注重要时间点数据实战:特殊节点标签标注、特殊区域标注
  3. s:iterator获取遍历数据的索引下标
  4. 一门杀人于无形的艺术——社会工程
  5. python在什么系统写代码合适-python用什么软件写代码
  6. Google App Engine平台下JDOQL查询报异常的问题解决方案
  7. c语言双精度百分号,C语言输出百分号%的方法和示例
  8. uniapp‘急‘速入门
  9. 微x怎么设置主题_微话题:小区设置公共晾衣架,您怎么看?您有什么建议?...
  10. [笔记分享] [SD] 块设备驱动学习小结
  11. SVN版本控制器使用攻略
  12. 数据集成-3-数据集成框架
  13. 远程springmvc ajax请求乱码,网络编程springMVC解决ajax请求乱码的三种方法
  14. win10家庭版启用远程桌面
  15. Html5新特性总览
  16. 背包问题专栏(01,完全,多重)
  17. Linux重启网卡,重启指定网卡
  18. cindy java_Cindy User Guide
  19. models.__dict__[args.model]()
  20. 让 AirDrop 支持有线传输,甚至让不支持 AirDrop 的 Mac 也能使用该功能 黑苹果也可以的哦

热门文章

  1. 网络霸屏推广,让每一个网络搜索用户能找到你
  2. windows10如何打开计算机配置文件,Win10电脑怎么设置打开文件夹选项?
  3. 我的出国留学之路,献给大家[转]
  4. java实验报告8 异常处理
  5. ubuntu 18.04 深度学习环境配置
  6. 生命快乐,源于自尊与自爱
  7. apiDoc生成接口文档,不费吹灰之力
  8. abap 会计凭证过账(BAPI_ACC_DOCUMENT_POST)非资产过账填写资产号写不进去
  9. 设计模式 — UML常见符号
  10. Ubuntu16.04 创建桌面快捷方式