12.1. 硬件设计
POR_BUTTON
复位按键。该按键连接至RT1052的POR_B引脚,当该引脚为低电平时会引起RT1052芯片的复位(复位的基本现象是程序从头开始运行)。从按键的原理图可知,该按键在没有被按下的时候,引脚状态为高电平,当按键按下时,引脚状态为低电平(按键所在的电路导通,引脚接到地)。所以,平时POR_B引脚保持高电平,芯片正常运行,按下按键时产生复位。
USER_BUTTON
这个引脚具有GPIO的功能,即我们可以把它设置成GPIO的输入模式,然后检测引脚的输入电平,即可判断按键是否被按下。
on/off按键。on/off按键最为特殊
ONOFF 信号是 RT 的输入。 在参考手册的第 13.5 节中,当我们提到以下内容时: SNVS_LP 内部的 ONOFF 逻辑允许直接连接到 PMIC 或其他稳压器设备。 这意味着您可以将来自 PMIC 的信号直接连接到 ONOFF 引脚,以在电源电压消失或降至特定水平以下时关闭 RT。当您使用 ONOFF 按钮关闭 RT 时,与您通过软件将其发送到 SNVS 模式效果相同。
定义按键的相关引脚;
配置引脚的MUX复用模式及PAD属性配置;
初始化GPIO目标引脚为输入模式;
编写简单测试程序,检测按键的状态,实现按键控制LED灯。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //WAUP按键 #define CORE_BOARD_WAUP_KEY_GPIO GPIO5 #define CORE_BOARD_WAUP_KEY_GPIO_PIN (0U) #define CORE_BOARD_WAUP_KEY_IOMUXC IOMUXC_SNVS_WAKEUP_GPIO5_IO00 #define CORE_BOARD_WAUP_KEY_NAME "CORE_BORE_WAUP_KEY" //MODE按键 #define CORE_BOARD_MODE_KEY_GPIO GPIO1 #define CORE_BOARD_MODE_KEY_GPIO_PIN (5U) #define CORE_BOARD_MODE_KEY_IOMUXC IOMUXC_GPIO_AD_B0_05_GPIO1_IO05 #define CORE_BOARD_MODE_KEY_NAME "CORE_BORE_MODE_KEY" #define KEY_ON 0 //低电平表示按下按键 #define KEY_OFF 1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | /*************************第1部分**************************/ #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pad_config.h" #include "./key/bsp_key.h" /*************************第2部分**************************/ /* 所有引脚均使用同样的PAD配置 */ #define KEY_PAD_CONFIG_DATA (SRE_0_SLOW_SLEW_RATE| DSE_0_OUTPUT_DRIVER_DISABLED| SPEED_2_MEDIUM_100MHz| ODE_0_OPEN_DRAIN_DISABLED| PKE_1_PULL_KEEPER_ENABLED| PUE_1_PULL_SELECTED| PUS_3_22K_OHM_PULL_UP| HYS_1_HYSTERESIS_ENABLED) /* 配置说明 : */ /* 转换速率: 转换速率慢 驱动强度: 关闭 速度配置 : medium(100MHz) 开漏配置: 关闭 拉/保持器配置: 使能 拉/保持器选择: 上下拉 上拉/下拉选择: 22K欧姆上拉 滞回器配置: 开启 (仅输入时有效,施密特触发器,使能后可以过滤输入噪声)*/ /*************************第3部分**************************/ /** * @brief 初始化按键相关IOMUXC的MUX复用配置 * @param 无 * @retval 无 */ static void Key_IOMUXC_MUX_Config(void) { /* 设置按键引脚的复用模式为GPIO,不使用SION功能 */ IOMUXC_SetPinMux(CORE_BOARD_WAUP_KEY_IOMUXC, 0U); IOMUXC_SetPinMux(CORE_BOARD_MODE_KEY_IOMUXC, 0U); } /*************************第4部分**************************/ /** * @brief 初始化按键相关IOMUXC的MUX复用配置 * @param 无 * @retval 无 */ static void Key_IOMUXC_PAD_Config(void) { /* 设置按键引脚属性功能 */ IOMUXC_SetPinConfig(CORE_BOARD_WAUP_KEY_IOMUXC, KEY_PAD_CONFIG_DATA); IOMUXC_SetPinConfig(CORE_BOARD_MODE_KEY_IOMUXC, KEY_PAD_CONFIG_DATA); } /*************************第5部分**************************/ /** * @brief 初始化按键相关的GPIO模式 * @param 无 * @retval 无 */ static void Key_GPIO_Mode_Config(void) { /* 定义gpio初始化配置结构体 */ gpio_pin_config_t key_config; /** 核心板的按键,GPIO配置 **/ key_config.direction = kGPIO_DigitalInput; //输入模式 key_config.outputLogic = 1; //默认高电平(输入模式时无效) key_config.interruptMode = kGPIO_NoIntmode; //不使用中断 /* 初始化按键 GPIO. */ GPIO_PinInit(CORE_BOARD_WAUP_KEY_GPIO, CORE_BOARD_WAUP_KEY_GPIO_PIN, &key_config); GPIO_PinInit(CORE_BOARD_MODE_KEY_GPIO, CORE_BOARD_MODE_KEY_GPIO_PIN, &key_config); } /*************************第5部分**************************/ /** * @brief 初始化控制KEY的IO * @param 无 * @retval 无 */ void Key_GPIO_Config(void) { /* 初始化GPIO复用、属性、模式 */ Key_IOMUXC_MUX_Config(); Key_IOMUXC_PAD_Config(); Key_GPIO_Mode_Config(); } |
第1部分。包含库文件fsl_iomuxc.h及fsl_gpio.h,以便对IOMUXC及GPIO外设进行控制;包含pad_config.h及bsp_key.h以便配置PAD属性及使用前面定义的按键硬件信息相关的宏。
第2部分。定义宏KEY_PAD_CONFIG_DATA,它包含了按键使用的PAD属性配置,它与LED灯例程中最大的区别如下:
因为引脚要用于输入模式,所以关闭了输出驱动强度的控制。
期望引脚在按键没按下的时候有更加稳定的输入,所以设置了22K欧姆的上拉。
按键的输入信号存在抖动,所以使能了施密特触发器进行滤波。
第3部分。使用库函数IOMUXC_SetPinMux配置两个按键引脚的MUX复用选择为GPIO,本例子中也没有开启SION功能。此处大家可能会有疑惑,在LED灯例程中引脚配置为输出模式不需要开启SION,本例子按键引脚配置为输入模式也不需要开启SION,那这功能究竟是什么时候才必需的呢?在后面的《第15章LPI2C—读写EEPROM第21章 》会学习到I2C作为通讯总线它同时具有输入和输出的功能,这就是SION应用的领域。也就是说当引脚被配置成开漏模式的同时需要读取引脚的电平信号,那么必须开启SION。
第4部分。使用库函数IOMUXC_SetPinConfig配置两个按键引脚的PAD属性,PAD属性具体参考第2部分的内容。
第5部分。定义Key_GPIO_Mode_Config函数,其函数内部先是向GPIO初始化结构体赋值,把引脚初始化成输入模式以及不使用中断,其中的outputLogic成员赋值为1或0是不会影响引脚的默认电平的,这个成员的配置仅在引脚用于输出模式时有效。最后利用库函数GPIO_PinInit把该参数配置写入到两个按键对应的GPIO引脚中。
第6部分。把前面定义的Key_IOMUXC_MUX_Config、Key_IOMUXC_PAD_Config以及Key_GPIO_Mode_Config函数封装到Key_GPIO_Config中,以便其它应用直接调用它初始化按键。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * @brief 检测是否有按键按下 * @note 本函数在按键按下时会阻塞,直至释放 * @param base:具体的端口 * @param pin:具体的引脚号 * @retval 按键的状态 * @arg KEY_ON:按键按下 * @arg KEY_OFF:按键没按下 */ uint8_t Key_Scan(GPIO_Type* base, uint32_t pin) { /*检测是否有按键按下 */ if (KEY_ON == GPIO_PinRead(base, pin)) { /*等待按键释放 */ while (KEY_ON == GPIO_PinRead(base, pin)); return KEY_ON; } else return KEY_OFF; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include "fsl_debug_console.h" #include "fsl_gpio.h" #include "fsl_gpt.h" #include "board.h" #include "pin_mux.h" #include "clock_config.h" #include "./led/bsp_led.h" #include "./key/bsp_key.h" /** * @brief 主函数 * @param 无 * @retval 无 */ int main(void) { /* 初始化内存管理单元 */ BOARD_ConfigMPU(); /* 初始化开发板引脚 */ BOARD_InitPins(); /* 初始化开发板时钟 */ BOARD_BootClockRUN(); /* 初始化调试串口 */ BOARD_InitDebugConsole(); /* 打印系统时钟 */ PRINTF("\r\n"); PRINTF("*****欢迎使用 野火i.MX RT1052 开发板*****\r\n"); PRINTF("CPU: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_CpuClk)); PRINTF("AHB: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_AhbClk)); PRINTF("SEMC: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SemcClk)); PRINTF("SYSPLL: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllClk)); PRINTF("SYSPLLPFD0: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd0Clk)); PRINTF("SYSPLLPFD1: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd1Clk)); PRINTF("SYSPLLPFD2: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd2Clk)); PRINTF("SYSPLLPFD3: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd3Clk)); PRINTF("GPIO输入—按键查询检测\r\n"); /************************第1部分****************************/ /* 初始化LED引脚 */ LED_GPIO_Config(); /* 初始化KEY引脚 */ Key_GPIO_Config(); //阻塞检测 PRINTF("阻塞检测示例,按下按键可控制LED灯反转\r\n"); while (1) { /************************第2部分****************************/ /* 检测WAUP按键 */ if (Key_Scan(CORE_BOARD_WAUP_KEY_GPIO, CORE_BOARD_WAUP_KEY_GPIO_PIN) == KEY_ON ) { CORE_BOARD_LED_TOGGLE; PRINTF("检测到 %s 按键操作\r\n", CORE_BOARD_WAUP_KEY_NAME); } /* 检测MODE按键 */ if (Key_Scan(CORE_BOARD_MODE_KEY_GPIO, CORE_BOARD_MODE_KEY_GPIO_PIN) == KEY_ON ) { CORE_BOARD_LED_TOGGLE; PRINTF("检测到 %s 按键操作\r\n", CORE_BOARD_MODE_KEY_NAME); } } } |
联系客服