• RAMday9


    设置按键中断,按键1按下,LED亮,再按一次,灭;按键2按下,蜂鸣器响,再按一次,不响;按键3按下,风扇转,再按一次,风扇停

    代码

    do_irq.c

    1. #include "key.h"
    2. extern void printf(const char *fmt, ...);
    3. unsigned int i = 0;
    4. unsigned int num1 = 0, num2 = 0,num3 = 0; //用于记录按键按下次数
    5. void do_irq(void)
    6. {
    7. int irqno;//保存中断号
    8. irqno=GICC->IAR & 0X3FF;
    9. switch(irqno)
    10. {
    11. case 99://key1
    12. //按键1中断处理
    13. printf("KEY1 INT\n");
    14. //灯亮
    15. if(num1 == 0)
    16. {
    17. //PF10
    18. GPIOF->ODR |= (0x1<<10);
    19. //PE10 PE8
    20. GPIOE->ODR |= (0x5<<8);
    21. num1++;
    22. }
    23. //灯灭
    24. else if(num1 > 0)
    25. {
    26. //PF10
    27. GPIOF->ODR &= ~(0x1<<10);
    28. //PE10 PE8
    29. GPIOE->ODR &= ~(0x5<<8);
    30. num1 = 0;
    31. }
    32. //清除挂起中断标志位GICD_ICPENDRx
    33. GICD->ICPENDR[3] |= (0x1<<3);
    34. //清除中断触发标志位EXTI_FPR1
    35. EXTI->FPR1 |= (0x1<<9);
    36. break;
    37. case 97://key2
    38. //按键2中断处理
    39. printf("KEY2 INT\n");
    40. //蜂鸣器转
    41. if(num2 == 0)
    42. {
    43. //PB6
    44. GPIOB->ODR |= (0x1<<6);
    45. num2++;
    46. }
    47. //蜂鸣器停
    48. else if(num2 > 0)
    49. {
    50. //PB6
    51. GPIOB->ODR &= ~(0x1<<6);
    52. num2 = 0;
    53. }
    54. //清除挂起中断标志位GICD_ICPENDRx
    55. GICD->ICPENDR[3] |= (0x1<<1);
    56. //清除中断触发标志位EXTI_FPR1
    57. EXTI->FPR1 |= (0x1<<7);
    58. break;
    59. case 98://key3
    60. //按键3中断处理
    61. printf("KEY3 INT\n");
    62. //风扇转
    63. if(num3 == 0)
    64. {
    65. //PE9
    66. GPIOE->ODR |= (0x1<<9);
    67. num3++;
    68. }
    69. //风扇停
    70. else if(num3 > 0)
    71. {
    72. //PE9
    73. GPIOE->ODR &= ~(0x1<<9);
    74. num3 = 0;
    75. }
    76. //清除挂起中断标志位GICD_ICPENDRx
    77. GICD->ICPENDR[3] |= (0x1<<2);
    78. //清除中断触发标志位EXTI_FPR1
    79. EXTI->FPR1 |= (0x1<<8);
    80. break;
    81. }
    82. //清除处理完的中断号GICC_EOIR
    83. GICC->EOIR =irqno;
    84. }

    led.c

    1. #include "led.h"
    2. //延时
    3. void delay(int ms)
    4. {
    5. int i,j;
    6. for(i = 0;i < ms;i++)
    7. {
    8. for(j = 0;j < 2000;j++);
    9. }
    10. }
    11. //给RCC使能
    12. void rcc_start()
    13. {
    14. RCC->MP_AHB4LPENSETR |= (0x3<<4);
    15. }
    16. //GPIO初始化
    17. void gpio_start()
    18. {
    19. //PE10 PE9 PE8设置为输出模式
    20. GPIOE->MODER &= (~(0x3f<<16));
    21. GPIOE->MODER |= (0x15<<16);
    22. //PF10设置为输出模式
    23. GPIOF->MODER &= (~(0x3<<20));
    24. GPIOF->MODER |= (0x1<<20);
    25. //PB6设置为输出模式
    26. GPIOB->MODER &= (~(0x3<<12));
    27. GPIOB->MODER |= (0x1<<12);
    28. //PE10 PE9 PE8设置为推挽输出
    29. GPIOE->OTYPER &= (~(0x7<<8));
    30. //PF10设置为推挽输出
    31. GPIOF->OTYPER &= (~(0x1<<10));
    32. //PB6设置为推挽输出
    33. GPIOB->OTYPER &= (~(0x1<<6));
    34. //PE10 PE9 PE8设置为低速输出
    35. GPIOE->OSPEEDR &= (~(0x3f<<16));
    36. //PF10设置为低速输出
    37. GPIOF->OSPEEDR &= (~(0x3<<20));
    38. //PB6设置为低速输出
    39. GPIOB->OSPEEDR &= (~(0x3<<12));
    40. //PE10 PE9 PE8设置为无上拉下拉电阻
    41. GPIOE->PUPDR &= (~(0x3f<<16));
    42. //PF10设置为无上拉下拉电阻
    43. GPIOF->PUPDR &= (~(0x3<<20));
    44. //PB6设置为无上拉下拉电阻
    45. GPIOB->PUPDR &= (~(0x3<<16));
    46. }

    led.h

    1. #ifndef __LED_H__
    2. #define __LED_H__
    3. #include "../common/include/stm32mp1xx_exti.h"
    4. #include "../common/include/stm32mp1xx_gpio.h"
    5. #include "../common/include/stm32mp1xx_rcc.h"
    6. #include "../common/include/stm32mp1xx_gic.h"
    7. //延时
    8. void delay(int ms);
    9. //给RCC使能
    10. void rcc_start();
    11. //GPIO初始化
    12. void gpio_start();
    13. #endif

    key.c

    1. #include"key.h"
    2. //按键3的配置
    3. void key3_config()
    4. {
    5. //RCC使能GPIOF时钟
    6. RCC->MP_AHB4ENSETR |= (0x1<<5);
    7. //设置PF8 GPIO输入
    8. GPIOF->MODER &= (~(0x3<<16));
    9. //设置PF8产生EXTI事件 EXTI_EXTICRx
    10. EXTI->EXTICR3 &=(~(0xFF<<0));
    11. EXTI->EXTICR3 |= (0x5<<0);
    12. //设置事件触发方式为下降沿触发EXTI_FTSR1
    13. EXTI->FTSR1 |= (0x1<<8);
    14. //设置EXTI事件触发不屏蔽EXTI_IMR1
    15. EXTI->C1IMR1 |= (0x1<<8);
    16. //使能中断能转发到特定的CPU接口层GICD_ISENABLERx
    17. GICD->ISENABLER[3] |= (0X1<<2);
    18. // GICD_ISENABLERx设置中断优先级
    19. GICD->IPRIORITYR[24] &= (~(0X1F<<19));
    20. //设置当前中断被转发到哪一个CPU处理GICD_ITARGETSRx
    21. GICD->ITARGETSR[24] &= (~(0X3<<16));
    22. GICD->ITARGETSR[24] |= (0X1<<16);
    23. //设置中断优先级掩码GICC_PMR
    24. GICC->PMR |= (0x1F<<3);
    25. //使能CPU可以处理组0转发的中断GICC_CTLR
    26. GICC->CTRL |= 0X1;
    27. }
    28. //按键1 按键2以及GICC层的配置
    29. void key_config()
    30. {
    31. //RCC使能GPIOF时钟
    32. RCC->MP_AHB4ENSETR |= (0x1<<5);
    33. //设置PF9 PF7GPIO输入
    34. //PF9
    35. GPIOF->MODER &= (~(0x3<<18));
    36. //pf7
    37. GPIOF->MODER &= (~(0x3<<14));
    38. //设置PF9 PF7 产生EXTI事件 EXTI_EXTICRx
    39. //pf7
    40. EXTI->EXTICR2 &=(~(0xFF<<24));
    41. EXTI->EXTICR2 |= (0x5<<24);
    42. //pf9
    43. EXTI->EXTICR3 &=(~(0xFF<<8));
    44. EXTI->EXTICR3 |= (0x5<<8);
    45. //设置事件触发方式为下降沿触发EXTI_FTSR1
    46. //pf7
    47. EXTI->FTSR1 |= (0x1<<7);
    48. //pf9
    49. EXTI->FTSR1 |= (0x1<<9);
    50. //设置EXTI事件触发不屏蔽EXTI_IMR1
    51. //PF7
    52. EXTI->C1IMR1 |= (0x1<<7);
    53. //PF9
    54. EXTI->C1IMR1 |= (0x1<<9);
    55. //使能中断能转发到特定的CPU接口层GICD_ISENABLERx
    56. //PF7 97号中断
    57. GICD->ISENABLER[3] |= (0X1<<1);
    58. //PF9 99号中断
    59. GICD->ISENABLER[3] |= (0X1<<3);
    60. // GICD_ISENABLERx设置中断优先级
    61. //PF7
    62. GICD->IPRIORITYR[24] &= (~(0X1F<<11));
    63. //PF9
    64. GICD->IPRIORITYR[24] &= (~(0X1F<<27));
    65. //设置当前中断被转发到哪一个CPU处理GICD_ITARGETSRx
    66. //pf7 97中断
    67. GICD->ITARGETSR[24] &= (~(0X3<<8));
    68. GICD->ITARGETSR[24] |= (0X1<<8);
    69. //pf9 99中断
    70. GICD->ITARGETSR[24] &= (~(0X3<<24));
    71. GICD->ITARGETSR[24] |= (0X1<<24);
    72. //使能组0转发中断GICD_CTLR
    73. GICD->CTRL |= 0X1;
    74. //设置中断优先级掩码GICC_PMR
    75. GICC->PMR |= (0x1F<<3);
    76. //使能CPU可以处理组0转发的中断GICC_CTLR
    77. GICC->CTRL |= 0X1;
    78. }

    key.h

    1. #ifndef __KEY_H__
    2. #define __KEY_H__
    3. #include "../common/include/stm32mp1xx_exti.h"
    4. #include "../common/include/stm32mp1xx_gpio.h"
    5. #include "../common/include/stm32mp1xx_rcc.h"
    6. #include "../common/include/stm32mp1xx_gic.h"
    7. void key_config();
    8. void key3_config();
    9. #endif

    main.c

    1. #include "key.h"
    2. #include "led.h"
    3. int main()
    4. {
    5. //中断初始化
    6. key_config();
    7. key3_config();
    8. //GPIO串口初始化
    9. gpio_start();
    10. while(1)
    11. {
    12. //保证主程序不结束
    13. }
    14. return 0;
    15. }

    现象

  • 相关阅读:
    关于ComfyUI的一些Tips
    Vulnstack----5、ATT&CK红队评估实战靶场五
    GitHub WebHook 使用教程
    Leecode第13题题解
    《C Primer Plus》第10章复习题与编程练习
    linux上如何搭建Java环境
    PostgreSQL 如果想知道表中某个条件查询条件在索引中效率 ?
    如何创建集成 LSP 支持多语言的 Web 代码编辑器
    VIRTIO-SCSI代码分析(2)VIRTIO 驱动分析
    区间合并算法的实现
  • 原文地址:https://blog.csdn.net/weixin_52238362/article/details/133797595