你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32进不了外部中断的一个可能原因

[复制链接]
STMCU-管管 发布时间:2020-9-30 09:35

近期在使用一块STM32的板子的时候,用库函数和外部中断来接收霍尔传感器信号,配置了很久,就是进不去外部中断。

IO口的初始化函数如下:

3 T+ I- J# x8 T$ |" I: G

  1. void Hall_GPIO_Init(void)
    2 n7 X, _, }7 x
  2. {
    % K* U3 P* N) Y: O) b4 S
  3.         GPIO_InitTypeDef GPIO_InitStructure;  
    * b( l) g# K+ o9 a! n5 n. C. Q
  4.         EXTI_InitTypeDef EXTI_InitStructure;
    ( x$ `  G9 S' H9 E+ f
  5.         NVIC_InitTypeDef NVIC_InitStructure;
    ' s5 A& w4 D. c6 W% z
  6. * ?, V2 j: _/ \' R) `. j  d, o
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟
    5 z7 ]' P! M" k) K$ ~) r
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟5 J# u( ~% m* j% z% i3 z* D
  9.         ( H6 M7 s2 g' r* `: a
  10.         NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;                        //使能HALL所在的外部中断通道2 C. h; H3 ]# Q+ U9 V! G& z
  11.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;        //抢占优先级0( G3 i, p5 L2 y3 s! ^! t3 u
  12.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x1;                                        //子优先级0 9 ]) q; n  j& i# c
  13.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
    $ n5 ?6 p7 z5 t) j- K7 D5 M$ ^
  14.         NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器          w0 a+ d  Q/ s3 v5 Y
  15.   /* 配置Hall接口IO */
    5 r8 r4 ]7 ~4 Z& Y( r8 S& }( v
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//HALL信号检测端口
    9 Z$ n+ {" t4 v" Z0 b7 D2 i
  17.         GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;& F" q7 d- s' C+ `- \
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;0 D5 @7 i( f! l
  19.         GPIO_Init(GPIOC, &GPIO_InitStructure);
    & A3 I# p* L5 @% x8 k  V1 e; W
  20.         //清空中断标志
    ; C& {. L2 g4 ^7 ~$ |' v# P  j7 Q
  21.     EXTI_ClearITPendingBit(EXTI_Line7);     //清除中断标志位
    ' ~" t9 t( \- I2 {, p
  22.     EXTI_ClearITPendingBit(EXTI_Line8);     //清除中断标志位1 v  F, w: Z$ |, U5 R3 o" w  O# Y8 I
  23.     EXTI_ClearITPendingBit(EXTI_Line9);     //清除中断标志位# R* ]8 q. @; K% |( z
  24.        
    5 N0 m( S% d4 Y. O
  25.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource7 | GPIO_PinSource8 | GPIO_PinSource9 );" B" Q$ P* q$ y( k9 T
  26. 3 P0 C/ Z1 V0 T" f
  27.         EXTI_InitStructure.EXTI_Line=EXTI_Line7 | EXTI_Line8 | EXTI_Line9;       
    + f0 U) ^9 s; u& h8 o
  28.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
    : a  G8 u+ m6 R  r! _
  29.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    # D0 ^0 J) ?2 t
  30.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;# ]. E4 p  L0 I
  31.         EXTI_Init(&EXTI_InitStructure);         ; X) O8 o( r3 F. R4 h1 J# [4 f+ S) \
  32. }
    - i6 W7 w4 R2 P- e' B, I
  33. /* I/O线中断,中断线为PC7、PC8、PC9 */2 Q1 b, r4 N1 r; }8 p: ~" l
  34. void EXTI9_5_IRQHandler(void)
    : [" \! v+ c; Q0 }
  35. {/ N. Q, s6 L0 ]4 p3 L0 Y# D( W
  36.   if(EXTI_GetITStatus(EXTI_Line7) != RESET) //确保是否产生了EXTI Line中断
    ( ?6 A4 }9 O. P
  37.   {  r& R) c: S6 {" x% U
  38.     EXTI_ClearITPendingBit(EXTI_Line7);     //清除中断标志位  A2 Q  m+ d3 m" k
  39.   } . _6 `- |) h* V# W* f, W
  40.   if(EXTI_GetITStatus(EXTI_Line8) != RESET) //确保是否产生了EXTI Line中断
    " P; I1 q+ X9 W9 q
  41.   {" p) m, o1 f: k$ `9 r* f. d
  42.     EXTI_ClearITPendingBit(EXTI_Line8);     //清除中断标志位
    3 K( Z1 F& H9 \& F" h5 K8 V
  43.   }
    ! U1 V# M# C2 I$ b2 n* e; x
  44.   if(EXTI_GetITStatus(EXTI_Line9) != RESET) //确保是否产生了EXTI Line中断
    ) e5 W5 J! Z; g/ \# u; U4 j4 t' H, ^
  45.   {4 `9 C- K1 F+ m, g% f
  46.     EXTI_ClearITPendingBit(EXTI_Line9);     //清除中断标志位! ~0 P" |: x& Q7 _1 m- |
  47.   }        & e# k, X5 N% L+ E
  48.   LED1=!LED1;//每进一次外部中断,LED1切换一次
    3 W7 B; a* Y+ p- ?
  49. }
复制代码

$ w8 J2 @* y! A% [8 _; v
- T, A3 C  P5 f2 K: t

上述初始化代码,咋一看,没发现啥问题,可就是进不了中断。
- f( T1 |, l. A& \. ?2 q% o后来发现是这一语句的问题:

2 h% m7 S: B) R0 Z9 K: D% Y% I

  1. GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource7 | GPIO_PinSource8 | GPIO_PinSource9 );
复制代码
( {4 j8 F' M! G# l5 w* t! O! W

通过GPIO_PinSource的定义,我们可以看到:


7 q" L8 W2 k+ p* Q0 K1 ~

  1. #define GPIO_PinSource0            ((uint8_t)0x00)2 i; b! x/ k2 ~" }) e8 f5 x! w
  2. #define GPIO_PinSource1            ((uint8_t)0x01)& J/ y) e. S/ P( J: H, b5 L
  3. #define GPIO_PinSource2            ((uint8_t)0x02)
    9 k2 l# ?+ _. H1 Q" @
  4. #define GPIO_PinSource3            ((uint8_t)0x03)$ M8 s  a9 K$ j1 d2 A. z' m) `
  5. #define GPIO_PinSource4            ((uint8_t)0x04)
    2 s6 }: U1 M" b3 L; r" |' ?6 [
  6. #define GPIO_PinSource5            ((uint8_t)0x05)$ ~+ V: A2 ]- ]0 G4 {/ }" z; A
  7. #define GPIO_PinSource6            ((uint8_t)0x06)- e1 t1 j6 M' A4 T5 ?1 w9 S
  8. #define GPIO_PinSource7            ((uint8_t)0x07)' H6 u1 S& u3 E3 ?8 G
  9. #define GPIO_PinSource8            ((uint8_t)0x08)/ C  O$ [$ P7 x# z" O
  10. #define GPIO_PinSource9            ((uint8_t)0x09)7 d3 u1 c, N4 I  A
  11. #define GPIO_PinSource10           ((uint8_t)0x0A)
    & n( V; B: U8 |
  12. #define GPIO_PinSource11           ((uint8_t)0x0B)
    # Y, C8 p- e) H0 M
  13. #define GPIO_PinSource12           ((uint8_t)0x0C)) W. r& U9 ]* o0 g7 T  u2 }
  14. #define GPIO_PinSource13           ((uint8_t)0x0D)0 f6 A' m) g3 I( Y
  15. #define GPIO_PinSource14           ((uint8_t)0x0E)5 t* L- t" b! h% K
  16. #define GPIO_PinSource15           ((uint8_t)0x0F)
复制代码
  ^& m- `. Z% J; }/ [" D5 W

这里跟GPIO口的初始化就很大不同了,GPIO口初始化,你可以取或后进行赋值,但是现在:

! ]3 k2 `/ Y8 q

  1. GPIO_PinSource7 | GPIO_PinSource8 | GPIO_PinSource9 =0x07|0x08|0x09=0x0F
复制代码

$ _+ v, A& _  {# U: F# L# R, D) [( n, J

所以,你能还初始化到正确的外部中断吗?!, C4 t/ o$ r, h8 \) c1 M# }) E- O5 U' ^
正确的初始化函数如下:


3 W4 C( T) z/ `( t2 O( U

  1. void Hall_GPIO_Init(void)5 H  [4 j7 O6 N6 I
  2. {
    8 y  C, @; m8 ]
  3.         GPIO_InitTypeDef GPIO_InitStructure;  3 S6 P2 o0 M+ I. a; X* o, t
  4.         EXTI_InitTypeDef EXTI_InitStructure;0 w0 Y, R' A2 `" t
  5.         NVIC_InitTypeDef NVIC_InitStructure;. K8 w3 r" c( {
  6. : }) ^" c) M- S( I# C2 c+ Z
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟: n* B" \2 l  T3 T5 @
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟
    3 U) O  C5 j) v" q8 ~* y) i
  9.        
    & A! C/ a4 S" a+ E( I0 r1 k* j
  10.         NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;                        //使能HALL所在的外部中断通道# W6 ~! j( E* |2 q7 E. `
  11.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;        //抢占优先级0$ A* x2 n: N7 ^$ @2 @" {/ O
  12.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x1;                                        //子优先级0 1 }6 h: |% v; ^/ k  `$ u- \+ L
  13.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道' b' m% S6 m; t: x3 M
  14.         NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器       
    : b5 q! m- z4 x% B) C
  15.   /* 配置Hall接口IO */0 i( }+ F+ k+ h3 Y8 l; Q( N- H
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//HALL信号检测端口
    8 H4 j% r+ H6 _; Z- b
  17.         GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;- M9 R9 Y* r0 K$ q( |
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;2 k1 m* v, w' s! B
  19.         GPIO_Init(GPIOC, &GPIO_InitStructure);/ @" s, m1 q: O& r
  20.         //清空中断标志  T5 F3 w& u- [5 n0 b8 f
  21.     EXTI_ClearITPendingBit(EXTI_Line7);     //清除中断标志位
    : {+ R8 E0 p, ^, W7 {( z1 q
  22.     EXTI_ClearITPendingBit(EXTI_Line8);     //清除中断标志位
    / m9 f" k8 P$ y( G3 S3 Z1 K) v" I6 ?
  23.     EXTI_ClearITPendingBit(EXTI_Line9);     //清除中断标志位
    % ?" ^+ p6 j. A' b  |1 ], \* ^) i
  24.         //老老实实一行一行来
    ; q; b3 T3 W8 K. ?
  25.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource7 );
    ; N( b5 ~9 [" J4 K7 X6 X
  26.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource8 );3 e5 d7 u& {! {2 ?$ N8 l
  27.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource9 );: A% S4 W+ j. Q. M  D, w0 d
  28.    
    8 h! T9 d9 Z3 E
  29.         EXTI_InitStructure.EXTI_Line=EXTI_Line7 | EXTI_Line8 | EXTI_Line9;          W- K6 y8 Z9 \
  30.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
    ) A3 }; S$ H3 [# Y- Q4 C5 V! f
  31.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;0 C1 m& b( j! F9 K. b) P% K
  32.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;1 v* }; q9 N! }& q& |9 V' D" e
  33.         EXTI_Init(&EXTI_InitStructure);         8 l4 L1 u6 A* g
  34. }
复制代码
* ]: v+ u6 V1 Y  b$ q

这样初始化就能正常进入外部中断了。

9 t2 x  C! a3 s
赞 收藏 评论0 发布时间:2020-9-30 09:35

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版