学习目标

  1. 理解GPIO的上拉下拉输入
  2. 理解外部上拉下拉
  3. 掌握输入状态的获取

    学习内容

    按键点灯一

    176.png177.png
  • 按下按键,LED1亮
  • 抬起按键,LED1灭

    开发流程

  1. GPIO初始化
  2. 按键扫描,按下点灯,抬起灭灯

    输入状态

  3. 默认状态:由电路图觉得,当前按键默认接地,因此默认为低电平。

  4. 按下按键,3V3导通,输入变为高电平

GPIO初始化,需要考虑到当前引脚的初始状态,初始化配置为不上拉也不下拉。
因此,抬起时,默认为低电平;按下时,为高电平。

实现逻辑

  1. /********************* PE3 LED0引脚 *********************/
  2. // 1. 时钟初始化
  3. rcu_periph_clock_enable(RCU_GPIOE);
  4. // 2. 配置GPIO 输入输出模式
  5. gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
  6. // 3. 配置GPIO 模式的操作方式
  7. gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_3);
  8. /********************* PA0 按键引脚 *********************/
  9. // 时钟初始化
  10. rcu_periph_clock_enable(RCU_GPIOA);
  11. // 配置GPIO模式
  12. gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
  1. FlagStatus pre_state = RESET;
  2. while(1) {
  3. FlagStatus state = gpio_input_bit_get(GPIOA, GPIO_PIN_0);
  4. if(SET == state && pre_state == RESET) {
  5. // 当前高电平, 上一次为低电平,按下开灯
  6. pre_state = state;
  7. gpio_bit_set(GPIOE, GPIO_PIN_3);
  8. } else if(RESET == state && pre_state == SET) {
  9. // 当前低电平, 上一次为高电平,抬起关灯
  10. pre_state = state;
  11. gpio_bit_reset(GPIOE, GPIO_PIN_3);
  12. }
  13. }

按键点灯二

174.png175.png177.png

  • 按下按键PD0,LED1亮
  • 抬起按键PD0,LED1灭

    开发流程

  1. GPIO初始化
  2. 按键扫描,按下点灯,抬起灭灯

    输入状态

  3. 默认状态:由电路图觉得,当前按键通过开关接地,因此默认什么都没有接,状态不确定。

  4. 按下按键,开关导通接地,输入变为低电平

GPIO初始化,需要考虑到当前引脚的初始状态,初始化配置为上拉,给一个默认的状态。
因此,抬起时,默认为高电平;按下时,为低电平。

实现逻辑

  1. /********************* PE3 LED0引脚 *********************/
  2. // 1. 时钟初始化
  3. rcu_periph_clock_enable(RCU_GPIOE);
  4. // 2. 配置GPIO 输入输出模式
  5. gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
  6. // 3. 配置GPIO 模式的操作方式
  7. gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_3);
  8. /********************* PD0 按键引脚 *********************/
  9. // 时钟初始化
  10. rcu_periph_clock_enable(RCU_GPIOD);
  11. // 配置GPIO模式
  12. gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0);
  1. FlagStatus pre_state2 = SET;
  2. while(1) {
  3. FlagStatus state = gpio_input_bit_get(GPIOD, GPIO_PIN_0);
  4. if(RESET == state && pre_state2 == SET) {
  5. // 当前低电平, 上一次为高电平,按下
  6. pre_state2 = state;
  7. gpio_bit_set(GPIOE, GPIO_PIN_3);
  8. } else if(SET == state && pre_state2 == RESET) {
  9. // 当前高电平, 上一次为低电平,抬起
  10. pre_state2 = state;
  11. gpio_bit_reset(GPIOE, GPIO_PIN_3);
  12. }
  13. delay_1ms(20);
  14. }

完整代码

  1. #include "gd32f4xx.h"
  2. #include "systick.h"
  3. #include <stdio.h>
  4. #include "main.h"
  5. /**
  6. PA0为按键引脚
  7. **/
  8. static void GPIO_config() {
  9. /********************* PE3 LED0引脚 *********************/
  10. // 1. 时钟初始化
  11. rcu_periph_clock_enable(RCU_GPIOE);
  12. // 2. 配置GPIO 输入输出模式
  13. gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
  14. // 3. 配置GPIO 模式的操作方式
  15. gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_3);
  16. /********************* PA0 按键引脚 *********************/
  17. // 时钟初始化
  18. rcu_periph_clock_enable(RCU_GPIOA);
  19. // 配置GPIO模式
  20. gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
  21. /********************* PD0 按键引脚 *********************/
  22. // 时钟初始化
  23. rcu_periph_clock_enable(RCU_GPIOD);
  24. // 配置GPIO模式
  25. gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0);
  26. }
  27. int main(void)
  28. {
  29. systick_config();
  30. GPIO_config();
  31. FlagStatus pre_state = RESET;
  32. FlagStatus pre_state2 = SET;
  33. while(1) {
  34. FlagStatus state = gpio_input_bit_get(GPIOA, GPIO_PIN_0);
  35. if(SET == state && pre_state == RESET) {
  36. // 当前高电平, 上一次为低电平,按下开灯
  37. pre_state = state;
  38. gpio_bit_set(GPIOE, GPIO_PIN_3);
  39. } else if(RESET == state && pre_state == SET) {
  40. // 当前低电平, 上一次为高电平,抬起关灯
  41. pre_state = state;
  42. gpio_bit_reset(GPIOE, GPIO_PIN_3);
  43. }
  44. state = gpio_input_bit_get(GPIOD, GPIO_PIN_0);
  45. if(RESET == state && pre_state2 == SET) {
  46. // 当前低电平, 上一次为高电平,按下
  47. pre_state2 = state;
  48. gpio_bit_set(GPIOE, GPIO_PIN_3);
  49. } else if(SET == state && pre_state2 == RESET) {
  50. // 当前高电平, 上一次为低电平,抬起
  51. pre_state2 = state;
  52. gpio_bit_reset(GPIOE, GPIO_PIN_3);
  53. }
  54. delay_1ms(20);
  55. }
  56. }

练习题

  1. 实现按键点灯