• ARM-day9作业


    main.c:

    1. #include "uart.h"
    2. #include "key_it.h"
    3. int main()
    4. {
    5. char c;
    6. char *s;
    7. uart4_init(); //串口初始化
    8. //中断初始化
    9. key_it_config();
    10. key3_it_config();
    11. //完成GPIO相关初始化
    12. all_led_init();
    13. //风扇初始化
    14. fs_init();
    15. //蜂鸣器初始化
    16. fmq_init();
    17. while(1)
    18. {
    19. //保证主程序不结束
    20. }
    21. return 0;
    22. }

    key_it.c:

    1. #include"key_it.h"
    2. void key3_it_config()
    3. {
    4. RCC->MP_AHB4ENSETR |= (0x1<<5);
    5. GPIOF->MODER &= (~(0x3<<16));
    6. EXTI->EXTICR3 &= (~(0xFF)<<0);
    7. EXTI->EXTICR3 |= (0x5<<0);
    8. EXTI->FTSR1 |= (0x1<<8);
    9. EXTI->C1IMR1 |= (0x1<<8);
    10. GICD->ISENABLER[3] |= (0x1<<2);
    11. GICD->IPRIORITYR[24] &= (~(0x1F<<19));
    12. GICD->ITARGETSR[24] &= (~(0x3<<16));
    13. GICD->ITARGETSR[24] |= (0x1<<16);
    14. }
    15. void key_it_config()
    16. {
    17. //RCC使能GPIOF时钟
    18. RCC->MP_AHB4ENSETR |= (0x1<<5);
    19. //设置PF9PF7PF8 GPIO输入
    20. //PF9
    21. GPIOF->MODER &= (~(0x3<<18));
    22. //PF8
    23. GPIOF->MODER &= (~(0x3<<16));
    24. //PF7
    25. GPIOF->MODER &= (~(0x3<<14));
    26. //设置PF9PF7PF8产生EXIT事件 EXTI_EXTICRx
    27. //PF7
    28. EXTI->EXTICR2 &= (~(0xFF)<<24);
    29. EXTI->EXTICR2 |= (0x5<<24);
    30. //PF8
    31. EXTI->EXTICR3 &= (~(0xFF)<<0);
    32. EXTI->EXTICR3 |= (0x5<<0);
    33. //PF7
    34. EXTI->EXTICR3 &= (~(0xFF)<<8);
    35. EXTI->EXTICR3 |= (0x5<<8);
    36. //设置事件触发方式为下降沿触发EXTI_FTSR1
    37. //PF7
    38. EXTI->FTSR1 |= (0x1<<7);
    39. //PF8
    40. EXTI->FTSR1 |= (0x1<<8);
    41. //PF9
    42. EXTI->FTSR1 |= (0x1<<9);
    43. //设置EXTI事件触发不屏蔽EXTI_IMR1
    44. //PF7
    45. EXTI->C1IMR1 |= (0x1<<7);
    46. //PF8
    47. EXTI->C1IMR1 |= (0x1<<8);
    48. //PF9
    49. EXTI->C1IMR1 |= (0x1<<9);
    50. //使能中断能转发到特定的CPU接口层GICD_ISENABLERx
    51. //PF7 97号中断
    52. GICD->ISENABLER[3] |= (0x1<<1);
    53. //PF8 98号中断
    54. GICD->ISENABLER[3] |= (0x1<<2);
    55. //PF9 99号中断
    56. GICD->ISENABLER[3] |= (0x1<<3);
    57. //GICD_ISENABLERx设置中断优先级
    58. //PF7
    59. GICD->IPRIORITYR[24] &= (~(0x1F<<11));
    60. //PF8
    61. GICD->IPRIORITYR[24] &= (~(0x1F<<19));
    62. //PF7
    63. GICD->IPRIORITYR[24] &= (~(0x1F<<27));
    64. //设置当前中断被转发到那一个cpu处理GICD_ITARGETSRx
    65. //PF7 97中断
    66. GICD->ITARGETSR[24] &= (~(0x3<<8));
    67. GICD->ITARGETSR[24] |= (0x1<<8);
    68. //PF8 98中断
    69. GICD->ITARGETSR[24] &= (~(0x3<<16));
    70. GICD->ITARGETSR[24] |= (0x1<<16);
    71. //PF9 99中断
    72. GICD->ITARGETSR[24] &= (~(0x3<<24));
    73. GICD->ITARGETSR[24] |= (0x1<<24);
    74. //使能组0转发中断GICD_CTLR
    75. GICD->CTRL |= 0x1;
    76. //设置中断优先级掩码GICC_CTLR
    77. GICC->PMR |= (0x1F<<3);
    78. //使能CPU可以处理组0转发的中断GICC_CTLR
    79. GICC->CTRL |= 0x1;
    80. }
    81. //延时函数
    82. void deley(int ms)
    83. {
    84. int i,j;
    85. for(i=0;i<ms;i++)
    86. {
    87. for(j=0;j<2000;j++);
    88. }
    89. }
    90. //GPIO初始化
    91. void all_led_init()
    92. {
    93. //RCC使能
    94. RCC->MP_AHB4ENSETR |= (0x3<<4);
    95. //设置PE10PF10、PE8为输出
    96. GPIOE->MODER &= (~(0x3<<20));
    97. GPIOE->MODER |= (0x1<<20);
    98. GPIOF->MODER &= (~(0x3<<20));
    99. GPIOF->MODER |= (0x1<<20);
    100. GPIOE->MODER &= (~(0x3<<16));
    101. GPIOE->MODER |= (0x1<<16);
    102. //设置推挽输出
    103. GPIOE->OTYPER &= (~(0x1<<10));
    104. GPIOF->OTYPER &= (~(0x1<<10));
    105. GPIOE->OTYPER &= (~(0x1<<8));
    106. //设置三个管脚低速输出
    107. GPIOE->OSPEEDR &= (~(0x3<<20));
    108. GPIOF->OSPEEDR &= (~(0x3<<20));
    109. GPIOE->OSPEEDR &= (~(0x3<<16));
    110. //设置三个管脚输出时无上拉电阻和下拉电阻
    111. GPIOE->PUPDR &=(~(0x3<<20));
    112. GPIOF->PUPDR &=(~(0x3<<20));
    113. GPIOE->PUPDR &=(~(0x3<<16));
    114. }
    115. //风扇初始化
    116. void fs_init()
    117. {
    118. //RCC使能
    119. RCC->MP_AHB4ENSETR |= (0x1<<4);
    120. //设置PE9为输出
    121. GPIOE->MODER &= (~(0x3<<18));
    122. GPIOE->MODER |= (0x1<<18);
    123. //设置推挽输出
    124. GPIOE->OTYPER &= (~(0x1<<9));
    125. //设置管脚低速输出
    126. GPIOE->OSPEEDR &= (~(0x3<<18));
    127. //设置管脚输出时无上拉电阻和下拉电阻
    128. GPIOE->PUPDR &=(~(0x3<<18));
    129. }
    130. //蜂鸣器初始化
    131. void fmq_init()
    132. {
    133. //RCC使能
    134. RCC->MP_AHB4ENSETR |= (0x1<<1);
    135. //设置PB6为输出
    136. GPIOB->MODER &= (~(0x3<<12));
    137. GPIOB->MODER |= (0x1<<12);
    138. //设置推挽输出
    139. GPIOB->OTYPER &= (~(0x1<<6));
    140. //设置管脚低速输出
    141. GPIOB->OSPEEDR &= (~(0x3<<12));
    142. //设置管脚输出时无上拉电阻和下拉电阻
    143. GPIOB->PUPDR &=(~(0x3<<12));
    144. }

    do_irq.c:

    1. #include"key_it.h"
    2. extern void printf(const char *fmt, ...);
    3. unsigned int i=0;
    4. void do_irq(void)
    5. {
    6. int irqno; //保存中断号
    7. irqno=GICC->IAR & 0x3FF;
    8. switch(irqno)
    9. {
    10. case 99://key1
    11. {
    12. //按键1中断处理
    13. printf("KEY1 INT\n");
    14. if((GPIOE->ODR==(GPIOE->ODR&(~(0x1<<10))))&&(GPIOF->ODR==(GPIOF->ODR&(~(0x1<<10))))&&(GPIOE->ODR==(GPIOE->ODR&(~(0x1<<8)))))
    15. {
    16. GPIOE->ODR |= (0x1<<10);
    17. GPIOF->ODR |= (0x1<<10);
    18. GPIOE->ODR |= (0x1<<8);
    19. }
    20. else if((GPIOE->ODR==(GPIOE->ODR|(0x1<<10)))&&(GPIOF->ODR==(GPIOF->ODR|(0x1<<10)))&&(GPIOE->ODR==(GPIOE->ODR|(0x1<<8))))
    21. {
    22. GPIOE->ODR &= (~(0x1<<10));
    23. GPIOF->ODR &= (~(0x1<<10));
    24. GPIOE->ODR &= (~(0x1<<8));
    25. }
    26. //清除挂起中断标志位GICD_ICPENDRx
    27. GICD->ICPENDR[3] |= (0x1<<3);
    28. //清除中断触发标志位EXTI_FPR1
    29. EXTI->FPR1 |= (0x1<<9);
    30. break;
    31. }
    32. case 97://key2
    33. {
    34. //按键2中断处理
    35. printf("KEY2 INT\n");
    36. if(GPIOB->ODR==(GPIOB->ODR&(~(0x1<<6))))
    37. {
    38. GPIOB->ODR |= (0x1<<6);
    39. }
    40. else if(GPIOB->ODR==(GPIOB->ODR|(0x1<<6)))
    41. {
    42. GPIOB->ODR &= (~(0x1<<6));
    43. }
    44. //清除挂起中断标志位GICD_ICPENDRx
    45. GICD->ICPENDR[3] |= (0x1<<1);
    46. //清除中断触发标志位EXTI_FPR1
    47. EXTI->FPR1 |= (0x1<<7);
    48. break;
    49. }
    50. case 98://key3
    51. {
    52. //按键3中断处理
    53. printf("KEY3 INT\n");
    54. if(GPIOE->ODR==(GPIOE->ODR&(~(0x1<<9))))
    55. {
    56. GPIOE->ODR |= (0x1<<9);
    57. }
    58. else if(GPIOE->ODR==(GPIOE->ODR|(0x1<<9)))
    59. {
    60. GPIOE->ODR &= (~(0x1<<9));
    61. }
    62. //清除挂起中断标志位GICD_ICPENDRx
    63. GICD->ICPENDR[3] |= (0x1<<2);
    64. //清除中断触发标志位EXTI_FPR1
    65. EXTI->FPR1 |= (0x1<<8);
    66. break;
    67. }
    68. }
    69. //清除处理完的中断号GICC_EOIR
    70. GICC->EOIR=irqno;
    71. }

    key_it.h:

    1. #ifndef __KEY_IT_H__
    2. #define __KEY_IT_H__
    3. #include"stm32mp1xx_rcc.h"
    4. #include"stm32mp1xx_gpio.h"
    5. #include"stm32mp1xx_exti.h"
    6. #include"stm32mp1xx_gic.h"
    7. void key_it_config();
    8. void key3_it_config();
    9. void deley(int ms);
    10. void all_led_init();
    11. void fs_init();
    12. void fmq_init();
    13. #endif

    现象:

  • 相关阅读:
    C++ 学习之旅(2.5)——变量与函数
    商业模式画布框架
    顶刊BMJ杂志推荐方法学文章!断点回归方法介绍
    Ceph-deploy跳过gpg-key验证(离线环境安装Ceph)
    谈谈悲观锁
    黑豹程序员 - java实现朗读文字
    详解GPU、CPU差异
    PMP备考大全:经典题库(敏捷管理第7期)
    Shell编程从看懂到看开①(Shell概述、变量、运算符、条件判断)
    消除卡顿 mac MATLAB2022b m1/m2原生下载安装 教程
  • 原文地址:https://blog.csdn.net/2301_77616453/article/details/133799411