当前位置:   article > 正文

STM32F407-外部中断_stm32f407读取flahs最后2k的字节时出现硬件错误中断

stm32f407读取flahs最后2k的字节时出现硬件错误中断

一.基本概念

 

STM32F4的每个IO都可以作为外部中断输入。  

STM32F4的中断控制器支持22个外部中断/事件请求:

EXTI线0~15:对应外部IO口的输入中断。

EXTI线16:连接到PVD输出。

EXTI线17:连接到RTC闹钟事件。

EXTI线18:连接到USB OTG FS唤醒事件。

EXTI线19:连接到以太网唤醒事件。

EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。

EXTI线21:连接到RTC入侵和时间戳事件。

EXTI线22:连接到RTC唤醒事件。 每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。

 

2.中断线与IO口的对应关系

中断线只有16根,因此

将PIOx.0映射到EXTI0

GPIOx.1映射到EXTI1

.......

GPIOx.15映射到EXTI15 

每一根中断线接收多个端口的映射,就解决了中断线不够用的情况

3.对于每个中断线,可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能。

IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数

从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数外部中断线10~15分配一个中断向量,共用一个中断服务函数。 

4.中断服务函数列表:

EXTI0_IRQHandler        

EXTI1_IRQHandler

EXTI2_IRQHandler          

EXTI3_IRQHandler          

EXTI4_IRQHandler          

EXTI9_5_IRQHandler        

EXTI15_10_IRQHandler      

外部中断常用库函数:

①void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);    //设置IO口与中断线的映射关系    exp: SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);     //将PE2映射到2号中断线

②void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);  //初始化中断线:触发方式等

③ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); //判断中断线中断状态,是否发生

④void EXTI_ClearITPendingBit(uint32_t EXTI_Line); //清除中断线上的中断标志位

⑤RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟 //这个函数非常重要,在使用外部中断的时候一定要先使能SYSCFG时钟

 

二、中断编写

1.中断配置一般过程

①使能SYSCFG时钟:          RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

②   初始化IO口为输入。        GPIO_Init();

③设置IO口与中断线的映射关系。         void SYSCFG_EXTILineConfig();

④初始化线上中断,设置触发条件等。        EXTI_Init();

⑤配置中断分组(NVIC),并使能中断。        NVIC_Init();

⑥编写中断服务函数。       EXTIx_IRQHandler();

⑦清除中断标志位       EXTI_ClearITPendingBit();

 

2.硬件连接

3.

中断服务函数:delay_ms(10)用于判断按键按下若超过10ms,就说明是真的按下了,也就是消除抖动的作用。

  1. void EXTIx_IRQHandler(void)
  2. {
  3. delay_ms(10);
  4. if(WK_UP==1)
  5. {
  6. BEEP=!BEEP;
  7. }
  8. EXTI_ClearITPendingBit(EXTI_Linex);
  9. }

 4.初始化线上中断,映射到2号中断线,设置模式为中断,下降沿触发,初始使能。

  1. EXTI_InitStructure.EXTI_Line=EXTI_Line2;
  2. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  3. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  4. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  5. EXTI_Init(&EXTI_InitStructure);

5.配置中断分组(NVIC),并使能中断。设置中断通道,抢占优先级,子优先级,使能外部中断通道。

  1. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  2. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  3. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
  4. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  5. NVIC_Init(&NVIC_InitStructure);

 

 

6.完整exti代码:

其中

key0对应蜂鸣器响停,抢占优先级:0,响应优先级:2,中断线0,中断处理函数EXTI0_IRQn

key1对应LED0翻转,抢占优先级:3,响应优先级:2,中断线2,中断处理函数EXTI2_IRQn

key2对应LED1翻转,抢占优先级:2,响应优先级:2,中断线3,中断处理函数EXTI3_IRQn

key3对应LED0,LED1同时翻转,抢占优先级:1,响应优先级:2,中断线4,中断处理函数EXTI4_IRQn

 

  1. void EXTI0_IRQHandler(void)
  2. {
  3. delay_ms(10);
  4. if(WK_UP==1)
  5. {
  6. BEEP=!BEEP;
  7. }
  8. EXTI_ClearITPendingBit(EXTI_Line0);
  9. }
  10. void EXTI2_IRQHandler(void)
  11. {
  12. delay_ms(10);
  13. if(KEY2==0)
  14. {
  15. LED0=!LED0;
  16. }
  17. EXTI_ClearITPendingBit(EXTI_Line2);
  18. void EXTI3_IRQHandler(void)
  19. {
  20. delay_ms(10);
  21. if(KEY1==0)
  22. {
  23. LED1=!LED1;
  24. }
  25. EXTI_ClearITPendingBit(EXTI_Line3);
  26. }
  27. void EXTI4_IRQHandler(void)
  28. {
  29. delay_ms(10);
  30. if(KEY0==0)
  31. {
  32. LED0=!LED0;
  33. LED1=!LED1;
  34. }
  35. EXTI_ClearITPendingBit(EXTI_Line4);
  36. }
  37. void EXTIX_Init(void)
  38. {
  39. NVIC_InitTypeDef NVIC_InitStructure;
  40. EXTI_InitTypeDef EXTI_InitStructure;
  41. KEY_Init();
  42. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  43. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
  44. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
  45. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
  46. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
  47. EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  48. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  49. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  50. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  51. EXTI_Init(&EXTI_InitStructure);
  52. EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line4;
  53. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  54. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  55. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  56. EXTI_Init(&EXTI_InitStructure);
  57. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  58. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  59. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
  60. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  61. NVIC_Init(&NVIC_InitStructure);
  62. NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
  63. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
  64. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//×ÓÓÅÏȼ¶2
  65. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  66. NVIC_Init(&NVIC_InitStructure);
  67. NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
  68. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
  69. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
  70. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  71. NVIC_Init(&NVIC_InitStructure);
  72. NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
  73. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  74. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
  75. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  76. NVIC_Init(&NVIC_InitStructure);
  77. }

7.总结

在进行STM32F407外部中断按键实验时,通过key0绑定蜂鸣器,key1绑定led0(亮灭),key2绑定led1(亮灭),key3绑定led0和led1(同时反转),样例给定时延为10ms,在进行按键检测时,发现并未体现函数中的抢占优先级,思考过后可能是由于时延太短,无法在10ms内看出其中的差别,因此我首先将时延设置为1000ms,给予充分的观察时间,设立优先级:

首先保持子优先级(响应优先级)相同,全部设为2,对于抢占优先级:

0级:key0(蜂鸣器)

1级:key1(LED0)

2级:key2(LED1)

3级:key3(LED0和LED1)

在进行试验时,按下key0与key1,在按下的时候有意的略微早一点按下key1,然后再按下key0,按照优先级抢占原则,key1的优先级为1,key0的优先级为0,虽然先按下key1,先进入key1的中断处理,但是由于key0的抢占优先级高于key1,于是将会先响应key0的中断,再响应key1的中断,最后实验发现确实如此,蜂鸣器先响,然后led0才亮,此后尝试了key2,key3均符合该原理。

 

另设优先级:

key0,key1抢占优先级设为0,子优先级(响应优先级)设为1,3

key2,key3抢占优先级设为1,子优先级(响应优先级)设为2,2

实验发现:

抢占优先级等级高于子优先级(响应优先级),子优先级低的抢占优先级高的会先响应,在抢占优先级相同的情况下,子优先级(响应优先级)高的将会先响应,两个优先级均相同的情况下,先来的会先响应。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50654
推荐阅读
相关标签
  

闽ICP备14008679号