• ARM 按键按下灯状态取反


    1. #ifndef __KEY_H__
    2. #define __KEY_H__
    3. #include "stm32mp1xx_rcc.h"
    4. #include "stm32mp1xx_gpio.h"
    5. #include "stm32mp1xx_exti.h"
    6. #include "stm32mp1xx_gic.h"
    7. #define EXTI0 0
    8. #define EXTI1 1
    9. #define EXTI2 2
    10. #define EXTI3 3
    11. #define EXTI4 4
    12. #define EXTI5 5
    13. #define EXTI6 6
    14. #define EXTI7 7
    15. #define EXTI8 8
    16. #define EXTI9 9
    17. #define EXTI10 10
    18. #define EXTI11 11
    19. #define EXTI12 12
    20. #define EXTI13 13
    21. #define EXTI14 14
    22. #define EXTI15 15
    23. //灯引脚编号封装
    24. #define GPIO_PIN_0 0
    25. #define GPIO_PIN_1 1
    26. #define GPIO_PIN_2 2
    27. #define GPIO_PIN_3 3
    28. #define GPIO_PIN_4 4
    29. #define GPIO_PIN_5 5
    30. #define GPIO_PIN_6 6
    31. #define GPIO_PIN_7 7
    32. #define GPIO_PIN_8 8
    33. #define GPIO_PIN_9 9
    34. #define GPIO_PIN_10 10
    35. #define GPIO_PIN_11 11
    36. #define GPIO_PIN_12 12
    37. #define GPIO_PIN_13 13
    38. #define GPIO_PIN_14 14
    39. #define GPIO_PIN_15 15
    40. //模式寄存器封装
    41. typedef enum{
    42. INPUT, //输入模式
    43. OUTPUT, //输出模式
    44. ALT, //复用功能模式
    45. ANALOG, //模拟模式
    46. }gpio_moder_t;
    47. //输出类型寄存器封装
    48. typedef enum{
    49. PP,//推挽
    50. OD,//开漏
    51. }gpio_otyper_t;
    52. //输出速率寄存器封装
    53. typedef enum{
    54. LOW,//低速
    55. MED,//中速
    56. HIGH,//高速
    57. VERY_HIGH,//快速
    58. }gpio_ospeedr_t;
    59. //是否需要上下拉电阻进行封装
    60. typedef enum{
    61. NO_PU_PD,//禁止上下拉电阻
    62. PU,//上拉
    63. PD,//下拉
    64. }gpio_pupdr_t;
    65. //封装初始化结构体
    66. typedef struct{
    67. gpio_moder_t moder; //模式相关寄存器
    68. gpio_otyper_t otyper; //输出类型寄存器
    69. gpio_ospeedr_t ospeedr; //输出速率寄存器
    70. gpio_pupdr_t pupdr; //是否需要上下拉电阻寄存器
    71. }gpio_init_t;
    72. //输出高低电平
    73. typedef enum{
    74. GPIO_RESET_T,//低电平
    75. GPIO_SET_T,//高电平
    76. }gpio_status_t;
    77. //RCC/GPIO章节初始化
    78. void hal_rcc_gpio_init();
    79. void hal_led_init(gpio_t* gpio,int n);
    80. //EXTI章节初始化--->KEY1
    81. //void hal_exti_key1_init();
    82. //GIC章节初始化---->KEY1
    83. //void hal_gic_key1_init();
    84. //************************封装函数方式实现按键123*******************************//
    85. //封装EXTI初始化函数 (EXTI编号,GPIOF组号,触发方式)
    86. void hal_exti_init(const unsigned int node,const unsigned int group,const int type);
    87. //封装GIC初始化函数(中断号,中断优先级)
    88. void hal_gic_init(int interrupt_id,int priority);
    89. //函数功能:gpio相关初始化操作
    90. //参数1:GPIO组编号
    91. //参数2:GPIO引脚编号
    92. //参数3:初始化相关内容
    93. //返回值:无
    94. void hal_gpio_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init);
    95. void hal_led_on(gpio_t* GPIO,unsigned int pin);
    96. #endif

    key.c

    1. #include "key.h"
    2. //KEY1 ---> PF9
    3. //KEY2 ---> PF7
    4. //KEY3 ---> PF8
    5. //**************************RCC/GPIO章节初始化**********************************//
    6. void hal_rcc_gpio_init()
    7. {
    8. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~RCC章节初始化~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    9. //1.使能GPIOF组控制器 MP_AHB4ENSETR[5] = 1
    10. RCC->MP_AHB4ENSETR |= (0x1 << 5);
    11. RCC->MP_AHB4ENSETR |= (0x3 << 4);
    12. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~GPIO章节初始化~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    13. //1.设置KEY1-->PF9引脚为输入模式 MODER[19:18] = 00
    14. GPIOF->MODER &= (~(0x3 << 18));
    15. //2.设置KEY2-->PF7引脚为输入模式 MODER[15:14] = 00
    16. GPIOF->MODER &= (~(0x3 << 14));
    17. //3.设置KEY3-->PF8引脚为输入模式 MODER[17:16] = 00
    18. GPIOF->MODER &= (~(0x3 << 16));
    19. }
    20. /***********************EXTI章节初始化--->KEY1********************************
    21. void hal_exti_key1_init()
    22. {
    23. //1.设置EXTI中断选择寄存器 PF9--->EXTI9 EXTICR3[15:8] = 0x05
    24. EXTI->EXTICR3 &= (~(0xff << 8));
    25. EXTI->EXTICR3 |= (0x05 << 8);
    26. //2.设置PF9引脚,中断触发方式为下降沿触发 FTSR1[9] = 1
    27. EXTI->FTSR1 |= (0x1 << 9);
    28. //3.设置EXTI层中断不屏蔽 C1IMR1[9] = 1
    29. EXTI->C1IMR1 |= (0x1 << 9);
    30. }
    31. ************************GIC章节初始化---->KEY1*******************************
    32. void hal_gic_key1_init()
    33. {
    34. //~~~~~~~~~~~~~~~~~~~~~~~GICD章节初始化~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    35. //1.设置GICD层使能组0 CTRL[0] = 1
    36. GICD->CTRL |= (0x1 << 0);
    37. //2.设置GICD层中断设置使能寄存器 ISENABLER[3] 第3位写1
    38. GICD->ISENABLER[3] |= (0x1 << 3);
    39. //3.设置GICD层中断优先级寄存器 IPRIORITYR[24] 第[31:27] = 00000
    40. GICD->IPRIORITYR[24] &= (~(0x1f << 27));
    41. //4.设置GICD层中断目标分配寄存器 ITARGETSR[24] 第[25:24] = 01
    42. GICD->ITARGETSR[24] &= (~(0x3 << 24));
    43. GICD->ITARGETSR[24] |= (0x1 << 24);
    44. //~~~~~~~~~~~~~~~~~~~~~~~GICC章节初始化~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    45. //1.设置GICC层使能组0 CTRL[0] = 1
    46. GICC->CTRL |= (0x1 << 0);
    47. //2.设置GICC层中断优先级寄存器 PMR[7:3] = 11111
    48. GICC->PMR &= (~(0x1f << 3));
    49. GICC->PMR |= (0x1f << 3);
    50. }
    51. */
    52. //**********************************封装函数方式实现按键123***********************************//
    53. //封装EXTI初始化函数 (EXTI编号,GPIOF组号,触发方式)
    54. void hal_exti_init(const unsigned int node,const unsigned int group,const int type)
    55. {
    56. //1.设置EXTI中断选择寄存器,因为8位管理一个EXTI编号,一个寄存器32位,所以最多管理4个EXTI
    57. //要管理16个EXTI,需要16/4=4个寄存器
    58. if((node/4) == 0)
    59. {
    60. EXTI->EXTICR1 &= (~(0xff << ((node%4)*8)));
    61. EXTI->EXTICR1 |= (group << ((node%4)*8));
    62. }
    63. else if((node/4) == 1)
    64. {
    65. EXTI->EXTICR2 &= (~(0xff << ((node%4)*8)));
    66. EXTI->EXTICR2 |= (group << ((node%4)*8));
    67. }
    68. else if((node/4) == 2)
    69. {
    70. EXTI->EXTICR3 &= (~(0xff << ((node%4)*8)));
    71. EXTI->EXTICR3 |= (group << ((node%4)*8));
    72. }
    73. else if((node/4) == 3)
    74. {
    75. EXTI->EXTICR4 &= (~(0xff << ((node%4)*8)));
    76. EXTI->EXTICR4 |= (group << ((node%4)*8));
    77. }
    78. //2.设置“按键”引脚,中断触发为下降沿触发 =1
    79. EXTI->FTSR1 |= (type << node);
    80. //3.设置EXTI层中断不屏蔽 =1
    81. EXTI->C1IMR1 |= (0x01 << node);
    82. }
    83. //封装GIC初始化函数(中断号,中断优先级)
    84. void hal_gic_init(int interrupt_id,int priority)
    85. {
    86. //*********************GICD章节初始化***************************//
    87. //1.GICD组控制寄存器使0
    88. GICD->CTRL |= (0X1 << 0);
    89. //2.设置GICD层中断使能,共288个中断号,一个寄存器32位,一个寄存器最多管理32个中断号
    90. //288/32=9 (0~8个寄存器)
    91. GICD->ISENABLER[interrupt_id/32] |= (0x1 << (interrupt_id%32));
    92. //3.设置GICD层中断优先级寄存器
    93. GICD->IPRIORITYR[interrupt_id/4] &= (~(0x1f << ((interrupt_id%4)*8+3)));
    94. GICD->IPRIORITYR[interrupt_id/4] |= (priority << ((interrupt_id%4)*8+3));
    95. //4.设置GICD层中断目标分配给CPU0
    96. GICD->ITARGETSR[interrupt_id/4] &= (~(0x3 << ((interrupt_id%4)*8)));
    97. GICD->ITARGETSR[interrupt_id/4] |= (0x01 << ((interrupt_id%4)*8));
    98. //*********************GICC章节初始化******************************//
    99. //1.使能GICC组0
    100. GICC->CTRL |= (0x1 << 0);
    101. //2.设置GICC层中断优先级寄存器
    102. GICC->PMR |= (0x1f << 3);
    103. }
    104. void hal_gpio_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init)
    105. {
    106. //设置模式
    107. gpiox->MODER &= (~(0x3 << (pin * 2)));
    108. gpiox->MODER |= (init->moder << (pin * 2));
    109. //设置输出类型
    110. gpiox->OTYPER &= (~(0x1 << pin));
    111. gpiox->OTYPER |= (init->otyper << pin);
    112. //设置输出速率
    113. gpiox->OSPEEDR &= (~(0x3 << (pin * 2)));
    114. gpiox->OSPEEDR |= (init->ospeedr << (pin * 2));
    115. //设置是否需要上下拉电阻
    116. gpiox->PUPDR &= (~(0x3 << (pin * 2)));
    117. gpiox->PUPDR |= (init->pupdr << (pin * 2));
    118. }
    119. void hal_led_on(gpio_t* GPIO,unsigned int pin)
    120. {
    121. GPIO->ODR ^= (0x1 << pin);
    122. }

    main.c

    1. #include "key.h"
    2. extern void printf(const char *fmt, ...);
    3. void delay_ms(int ms)
    4. {
    5. int i,j;
    6. for(i = 0; i < ms;i++)
    7. for (j = 0; j < 1800; j++);
    8. }
    9. int main()
    10. {
    11. hal_rcc_gpio_init();//RCC/GPIO章节初始化
    12. //GPIOE组/GPIOF组使能
    13. //结构体初始化
    14. gpio_init_t init = {OUTPUT,PP,LOW,NO_PU_PD};
    15. hal_gpio_init(GPIOE,GPIO_PIN_10,&init);
    16. hal_gpio_init(GPIOF,GPIO_PIN_10,&init);
    17. hal_gpio_init(GPIOE,GPIO_PIN_8,&init);
    18. // hal_exti_key1_init();//EXTI章节初始化
    19. hal_exti_init(EXTI9,0x05,1);//EXTI章节初始化
    20. hal_exti_init(EXTI7,0x05,1);//EXTI章节初始化
    21. hal_exti_init(EXTI8,0x05,1);//EXTI章节初始化
    22. // hal_gic_key1_init();//GIC章节初始化
    23. hal_gic_init(99,9);
    24. hal_gic_init(98,8);
    25. hal_gic_init(97,7);
    26. while(1)
    27. {
    28. }
    29. return 0;
    30. }

  • 相关阅读:
    ES6对象
    神经网络 模型表示2
    AcWing 2811. 最长公共子串(后缀自动机 fa 指针的性质)
    Python学习路线
    经验风险最小化与结构风险最小化:优化机器学习模型的两种方法
    【Mysql高级篇】MVCC的原理
    浅谈压力测试的重要目标及意义
    【Unity细节】Json序列化时出现:An item with the same key has already been added. Key:
    LeetCode 2651. 计算列车到站时间:取模
    如何知道你的Linux内核占用的内存大小?
  • 原文地址:https://blog.csdn.net/Meng_fighting/article/details/133322588