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

STM32外部中断使用注意事项

[复制链接]
lastimy 发布时间:2017-9-30 10:46
stm32尽管所有的gpio都可以设置为外部中断的功能,但是不能把所有的gpio同时设置为外部中断。例如不能把PA0和PB0同时设置为外部中断,因为PA0和PB0共用一个中断线,MCU只把最后完成初始化的管脚设置为外部中断。. k6 z" |2 r* X
" P/ d8 z. Z4 [9 ^" u2 _( C! t
如果代码编写者明确知道PA0和PB0不会同时触发,并且触发有相互依赖关系,可以通过分时设置PA0和PB0的外部中断功能。但是在大多数情况下,外部中断的触发都是随机的,那么在设计原理图的时候就要考虑到这种情况,把用到的外部中断管脚设置到后缀不同的管脚上,如PA0,PA1,PB3,PC8,....PD12,PF16,在一个工程中最多能使用16个外部中断,并且每个管脚的后缀不同。. T5 C+ V7 g- @: T* C0 E! g3 Z6 P3 i, ^
) \8 b5 ?. w0 g' E/ W+ w$ Q, M
+ q' }' L; N) R! g- w$ X
如果设计电路板没有考虑到这种情况,则需要根据实际情况把触发频繁的设置为外部中断,不频繁的通过检测管脚电平变化来判断是否有触发。
; `. }0 R2 u7 m1 H' `2 Z
  A% L& `& y2 I7 F1 [9 q

: ?3 h3 I# _) u8 s检测管脚电平变化的一种方法:
, s2 V/ ^. q+ p2 o5 ]5 R: |设计一个周期1ms的定时器,在定时器中断服务函数中通过判断管脚电平,来捕获上升沿和下降沿。$ K' `) a0 A9 |5 q1 u, [
3 T1 x( T5 D0 G# l+ w; s+ a

: d7 n/ W2 k4 W+ o5 k% [4 Z# ~5 F1 S8 e3 g/ X9 Q

% s: g* v% ]: O
  1. <span style="background-color: white;">//捕获下降沿, Y9 y& I( N- X% T4 G1 p' G' W
  2. void timer_isr(void)//定时器1ms的中断服务子函数! d! Z- u8 I) T$ X6 G, M
  3. {$ s' X9 Y; ~# Z/ |4 K* b4 |6 ?
  4. if(READ_PIN)0 y2 m7 i& v, c, ?
  5. {
    4 k1 o- ?" X& M  J
  6.   state = waitting_falling_edge;
    7 v1 r2 C, Z# a0 d
  7. }
    ! n' I( H6 I# |9 M  M6 I
  8. else' Q$ t8 i+ n$ o" g" s
  9. {& Y- u# e9 H6 y- N$ u- _
  10. if(state == waitting_falling_edge)
    0 n7 d( Z+ e  W! d
  11. {
    + z* ~0 ~6 I7 x6 [( r& W- d$ J7 z
  12. falling_trigger = 1;//捕获下降沿% l8 Z# W( ?/ Z# w& d. i' v3 ~
  13. state = falling_edge_detected;
      H7 {  E# i3 F; ]  [5 F+ [
  14. }" q% b- H! b/ T
  15. }
    5 ]. \4 Y3 k2 Z( g
  16. }
    / V* i8 i# A) @# }' [4 ~* l
  17. //捕获上升沿
    4 {- b/ C* ?8 O8 x9 e) n5 v! M0 C
  18. void timer_isr(void)//定时器1ms的中断服务子函数
    , y  ?- F# a$ W8 z* `8 t; p$ T
  19. {0 M* W( ^' X- i$ O1 g4 d
  20. if(!READ_PIN)+ i; I/ v8 P5 R
  21. {1 ~, Y! F$ W! Y+ k
  22.   state = waitting_rising_edge;6 Z4 A; U5 w$ @1 U5 o0 q/ C2 X
  23. }
    0 O8 s6 q) f/ w9 r
  24. else- i: J6 D! `3 v) v
  25. {* R- o, Q( M$ t5 Y4 c
  26. if(state == waitting_rising_edge)& B# }+ _4 m3 t- G
  27. {: j# |' @2 z  I4 W8 [, }
  28. rising_trigger = 1;//捕获上升沿! ?- z$ \" h  p8 S. |' w
  29. state = rising_edge_detected;8 }6 J3 ^+ I7 }' a
  30. }
    3 K, |+ X! u6 _/ `" F
  31. }
    7 s  R/ {: D% w# D
  32. }
    9 {+ n8 K$ }& S$ S2 p3 I6 k
  33. $ @: {+ |6 y# i3 K% D
  34. 类比FPGA的捕获上升沿、下降沿代码(verilog语言)
    $ \/ ]. _  ]4 J! a( F* h4 G1 E" v
  35. //捕捉上升沿8 }8 g4 e. @  G- O; r
  36. module capture_rising(iclock, ireset, isignal, orising);+ q. N7 b  f* u2 a
  37. input iclock;
    $ o. n: ^" i6 ?# L; W8 @, {, @
  38. input ireset;
    1 w2 S3 ]% i5 {1 U0 X& s9 A2 q
  39. input isignal;
    0 L: Z* ]/ L8 z' M7 v
  40. output orising;' C3 ?* `7 e3 j* A+ ~0 f: Z) ?: l1 W
  41. reg isignal_temp0;
    5 a- @% a- P) X& f8 z* ~
  42. reg isignal_temp1;+ s% y+ o/ T8 T/ Q) |" U1 A
  43. always @(posedge iclock or negedge ireset)* ?3 a* _, B& s3 y& g. ~8 h8 u+ J5 k& F
  44. begin
    ) B0 B4 `, }2 e8 T; T
  45. if(!ireset)
    + h* Z7 D% Y: q
  46. begin
    : A, t. U4 L4 c6 Y9 Y
  47. isignal_temp0 <= 1'b0;
    . |) i+ ~" `" Z# e+ R& ?
  48. isignal_temp1 <= 1'b0;
    . C* }$ J' u6 \) q) s/ y
  49. end
    ; o) f; X; E' X
  50. else0 X5 n" ]* c2 C2 Q  r5 O
  51. begin, x. R* s) t; t. v% V& S
  52. isignal_temp0 <= isignal;
    6 U* w0 I' s: q8 N5 y4 n, P
  53. isignal_temp1 <= isignal_temp0;
    " l; H% s7 ?- Z! c. b
  54. end1 i1 X8 u8 F0 I  `* z8 a( _
  55. end
    4 G+ o! m8 H4 \1 G: q
  56. , o4 L8 o/ [3 i. _5 D) @' e
  57. assign orising = ~isignal_temp1 & isignal_temp0;0 J4 c5 Q; s+ p! {7 z, q
  58. endmodule8 y5 t' V3 \4 a; m3 Q
  59. 0 [# \( W) n% Z
  60. //捕捉下降沿
    ) C0 [) C$ O, P1 }/ U
  61. module capture_falling(iclock, ireset, isignal, ofalling);
    8 w( |2 y7 B& V
  62. input iclock;
    , B, K* G0 C0 S: R2 _! m
  63. input ireset;
    # \) X. C# z8 H" @% K$ a
  64. input isignal;
    6 X8 V# b$ K/ S: m1 `6 ?
  65. output ofalling;9 x5 b/ L1 V7 n. j- X5 J( P
  66. reg isignal_temp0;
    : I; M. z  i9 y! n9 i1 r# @  w- F
  67. reg isignal_temp1;
    6 y/ C# Q* S) g+ U8 i: B0 S
  68. always @(posedge iclock or negedge ireset)
    3 M5 p& j- Z" [5 R
  69. begin; S  ^8 D8 G6 u! t8 A. u) G7 X) N: F- I
  70. if(!ireset)2 R0 |% L, X* \. Y1 J- Y) M  R
  71. begin4 `- I8 h. ?  D0 e: Z
  72. isignal_temp0 <= 1'b0;
    - `, ^+ x3 k9 e0 D3 b* B% ]
  73. isignal_temp1 <= 1'b0;
    6 U  I7 h2 s  S4 G
  74. end1 q- k* {6 [! J6 j' T! e: c7 `
  75. else* Y) j4 X6 D( ^' i7 h5 B
  76. begin
    . T  J0 u$ f& A+ K7 U% @
  77. isignal_temp0 <= isignal;. w9 I4 }9 {8 n% F. O0 S, c
  78. isignal_temp1 <= isignal_temp0;" E; c; \8 T4 k; K, P
  79. end/ k4 r- f7 B5 s3 a
  80. end  w# t6 h2 n, l; y/ h
  81. ! m1 a" j! R6 a) s7 G+ Z/ C
  82. assign ofalling = isignal_temp1 & ~isignal_temp0;1 J; ]/ s+ J6 b& y" y) t8 d
  83. endmodule</span>
复制代码
+ C: O0 I+ K2 H) s: R+ y  N9 v- q1 P

7 @7 s  ^* c( H: y* s" ^虽然代码不同,但是思路是一样的:寄存上一周期的状态,并与当前状态相结合进行判断。
0 i6 X& m' b: Z: ?7 u( \stm32的1ms定时器(即每1ms执行一次定时器中断服务子函数)相当于fpga的1个时钟100ns(iclock-10mhz),检测速度相差1万倍。
$ g" [" E& X  q6 @! P( u8 h; r) {

! H- y9 n" L' Z( s& S9 Q  D3 |& r' ?8 U+ j3 k- I6 F# ~+ Q4 N
赞 收藏 评论1 发布时间:2017-9-30 10:46

举报

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