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

【经验分享】认识STM32 的中断及如何使用

[复制链接]
STMCU小助手 发布时间:2022-6-21 17:24
中断是一种机制,通过这种机制,I/O或指令可以暂停处理器的正常执行,并像具有最高优先级一样先执行自己的任务。也就是说,当外部中断发生时(比如来自某个传感器),处理器暂停其正在执行,首先提供中断服务,然后继续其正常执行。
, y% Q/ h- Y- s6 [% t) c7 e' [; b2 e( k+ ?
为了了解 STM32F103C8 中的中断,我们将使用按钮作为外部中断。在这里,我们让从一个变量从 0 开始每秒增1,并将其显示在16x2 LCD上,当按下按钮时,LED亮起,LCD 显示屏会显示 INTERRUPT,松开按钮LED熄灭。
7 d" i: e  T) m; s
7 z$ |9 `/ Z; o3 |5 \中断类型和 ISR(中断服务程序)
. D! ~; r6 B* y' g中断大致可以分为两类:; q  z0 V6 s; X
  ~; ]) E. j3 i. p! E
硬件中断: 如果到处理器的信号来自某些外部设备,例如按钮或传感器,或者来自其他信号并告诉处理器执行 ISR 中存在的特定任务的硬件设备,则称为硬件中断。
; S' x6 f9 v3 p8 M0 n5 r! Y, d1 Z/ W
软件中断:由软件指令产生的中断。) x/ E2 N1 x2 Y7 H5 Z
# z" `# F* [! ^+ b2 `
中断服务程序:中断服务程序或中断处理程序是其中包含少量指令的事件,当发生中断时,处理器首先执行 ISR 中的这些代码,然后再继续执行中断之前正在执行的任务。6 K( X+ e5 j: A9 Z
) H! ^3 q% E* X' ^+ E2 B/ v2 T
STM32中的中断语法% Y7 a- Q4 }! S
在Arduino IDE中,启用ISR具有以下语法attachInterrupt (digitalPinToInterrupt(pin), ISR, mode),同样可以在 STM32 中使用,因为本文正是使用 arduino IDE 上传代码。3 W# g/ m) x: X. b
8 c6 }  x8 k6 B, }  O& Q
digitalPinToInterrupt(pin):就像在Arduino board Uno中,我们有引脚2,3,而在mega中,我们有2,3,18,19,20,21用于中断。在STM32F103C8中,我们也有中断引脚,任何GPIO引脚都可以用于中断。我们只需要指定用于中断的输入引脚。但是,当同时使用多个中断时,我们可能需要遵循一些限制。4 ~1 p% W0 i( x$ ^1 ?& r- L
- H+ w% z7 @) P2 {9 E
ISR:它是一个在发生外部中断时调用的中断处理函数。它没有参数和返回值。
9 q* A" z3 J! i* x* c" P; t
) K. c' g/ E1 ^# y. b& umode:触发中断的方式条件! _/ I# e% w5 K( g3 J
" y/ U( I0 p3 E: W6 L& P8 j
上升沿:当引脚从 低电平变为 高电平时触发中断。
/ {& _8 J$ |, o
/ R. \- @  t& g* z% @  M: N' o下降沿:当引脚从 高电平变为 低电平时触发中断。
( O" R4 x  K0 g7 i7 Z! k& k
- J( T: {* U1 w5 B* S双边沿触发(CHANGE):当引脚从 低电平变为 高电平或 高电平变为 低电平时触发中断(即,当引脚电平发生变化时)。% a) _8 \4 }5 Q: Z3 H3 Y- ^
. e/ d+ y+ f( p! v5 b9 w
使用中断注意事项
; b& R6 O7 W. ?8 F3 J2 u1 R, m2 H" O6 G" ]. m( r! B9 S0 o  m
中断服务程序功能 (ISR) 必须尽可能短。
+ \: i1 }5 T: A& C# G2 [. Z
7 g& y3 s- f- k* C避免在ISR中使用delay函数。6 P+ _( K1 }6 I1 I4 ]

$ Z- [$ E2 Y+ K1 U' J' r8 B电路图和连接说明
2 J/ V* |" C* n9 v. R1 ~* `
8 S2 M' N$ a& o/ I6 i 1e164c14399d28795bde127d0011b4d2.png
8 Z' ^# ~/ N$ A$ B) v' B& e0 A- e5 }; ~1 r- h! P8 t* a% d
按钮引脚的一侧连接到 STM32 的 3.3V,另一侧通过下拉电阻连接到 STM32 的输入引脚(PA0)。
: k% K4 D- I6 E- f; Q* u# u" H9 X4 T; h" K& ]( j1 Y
关于使用下拉电阻器,当按下或释放按钮时,微控制器只会在其输入端获得高电平或低电平。如果没有下拉电阻,按钮没有按下,输入端状态不确定(不是高也不是低),并且容易受外界影响,输入端电平可能是浮动随机值(忽高忽低)。
6 d% r% }, }/ P: `! V
1 n4 _0 p6 y& K& \& k" r+ p 20147b5351a9ec2d1d012949f75cafd8.jpg 4 L# k( D. G, Z; N1 r$ E0 P& D& R
. E) c3 B3 h% p7 f7 r% ~8 J
STM32F103C8与LCD的连接5 \5 o: H- ?# u  Y% c1 l

/ @  Y8 {% P8 A2 F' L' S# f' s下表显示了 LCD (1602) 和 STM32F103C8 微控制器之间的引脚连接。& V; j6 X, T& e# Y$ v" j; e

0 u& }. W" J; h) V/ j 7a2123bf0e8cf73333b657979fd5ebf3.jpg ' v9 J7 Z7 r7 u% c' k5 T

" U$ ]) |+ U1 N9 U+ _STM32F103C8中断编程
5 |- M7 b1 ]- ^9 o* e" [9 r( r$ r程序很简单,使用Arduino IDE编程。7 J- Z( X. c2 V7 q$ E2 C

, D: }+ p1 e3 v我们将一个变量从 0 开始每秒自增1并将其显示在 1602 LCD 上,每当按下按钮时,LED亮起,LCD 显示屏会显示“Interrupt”,松开按钮LED熄灭。+ e  U% ~' g4 k+ k- v
; X+ t8 u* a5 m5 m
46ba66fcbaf8f0d7d10de405d31591d8.jpg
' s+ j7 z/ \$ @  @( R. T/ Z+ F- h$ X
8 J% h6 [& a& [; U' G
  1. //声明LCD 引脚连接到STM32 的哪个引脚: f7 C  q" J0 A( I0 O) R
  2. const int rs= PB10,en= PB11,d4= PB0,d5= PB1,d6= PC13,d7= PC14;/ L8 j% i& G6 Q4 l. S; T! o" ^) h
  3. #include<LiquidCrystal.h>//LCD 库
    + Z: Y9 r4 n0 @3 ^9 \2 P
  4. LiquidCrystal lcd (rs,en,d4,d5,d6,d7);//初始化LCD0 B& q& n& K. }/ \# Z& Z; W
  5. volatile boolean ledOn = false; //LED状态标识
    * V  y# ?5 A2 N8 A$ V

  6. , c4 D) ?( l, ~* Y3 @
  7. void setup()( r" b* J6 c2 p  N
  8. {6 ]# \& n% X8 U' F  j% O
  9.   lcd.begin(16,2);// 将 LCD 设置为 16x2 类型
    1 g7 e/ h2 K" Z. {/ N8 R& u
  10.   lcd.print("Hello World"); //LCD 显示 Hello World!; _* G% i1 v5 \. _0 ]4 I0 |; g
  11.   delay(2000); //延时2秒
    - b7 c) y/ j3 E
  12.   lcd.clear(); //清屏+ z2 j7 Y+ N: i: R- |8 s
  13.   pinMode(PA1,OUTPUT); //将引脚 PA1 设置为输出$ m+ p5 n3 D  j: Q0 [& R
  14.   pinMode(PA0,INPUT); //将引脚 PA0 设置为输入; o" S: j: N, e
  15.   int i = 0;
    1 f" [1 T- n9 ~/ J" A7 \' B
  16.   attachInterrupt(PA0,buttonPressed,CHANGE);// 创建外部中断
    . d' ]' z! D: b! _
  17. }3 |- s4 R- ]7 M0 ?  Q! d( s

  18. 4 M) C/ F2 T' V2 _
  19. void loop()5 ^' q+ v- F1 V4 I% a
  20. {
    & ]$ D# N3 S4 U- V: l7 Z( N- Q
  21.   lcd.clear();//清屏
    7 T- ]% T' O' ~* E1 p
  22.   lcd.print("NUMBER:"); //LCD显示NUMBER:. F4 c! v+ Y( E2 B0 L2 }" E5 Y6 S
  23.   lcd.print(i);//LCD 显示“i”值% d, g7 W9 U8 E$ E1 c5 ^
  24.   ++i; //“i” 自增 1
    . h. c% f3 D9 S7 V" O
  25.   delay(1000); //延时1秒  ~& B& Y% W3 h3 k
  26. }
    + c# d7 u, o4 \

  27. 1 Z# v" Z, h! Q* L# t; m8 G. i" @
  28. void buttonPressed() //ISR中断子函数3 E# U2 h; ?# W( @
  29. {
    $ u8 ]% P* v- g% Q4 R# d
  30.   //松开按钮
      [7 o" |8 w# p& \+ f- `4 \
  31.   if(ledOn) //当发生中断时判断LED 状态标识,如果LED是亮起状态% a! ]+ n& A, p5 f# P- B) I
  32.   {1 p& h' G( I( T1 v& d0 m
  33.     ledOn=false; //则设置LED状态标识为熄灭
    % Q5 t6 J' x2 A# \3 R( u5 V
  34.     digitalWrite(PA1,LOW); //同时把PA1设置为低电平,熄灭LED) ^- B6 o" R# d4 t: N
  35.   }. o" o/ K6 a* p
  36. ' S5 ~" ]& K) h, E9 s% q
  37.   //按下按钮0 U; u. E/ [$ I3 {0 [+ K
  38.   else // 否则(即如果LED状态标识为熄灭)
    9 r. F$ ?  F5 S7 x1 q  f* j
  39.   {* a4 V0 R+ o$ {8 n/ l" T0 W
  40.     ledOn = true; //则设置LED状态标识为亮起8 Z8 X/ I( H. U5 L7 ]
  41.     digitalWrite(PA1,HIGH); //同时把PA1设置为高电平,点亮LED
    1 w  W4 p5 R# N" `
  42.     lcd.setCursor(0,1); //将光标设置在第一列和第二行, _& m' l. b6 z% j: r
  43.     lcd.print("Interrupt"); //LCD显示Interrupt4 h8 l7 E" n' J; N& S3 r
  44.   }( A; F4 i1 h/ E  j9 t
  45. }
    ' w: t/ t, y, e/ v: J) U
  46. 0 R9 _2 j& b% [8 e& n4 P
复制代码
" z" V0 t1 y9 n- A" B! V8 o; Q0 }2 F
赞 收藏 评论0 发布时间:2022-6-21 17:24

举报

0个回答

所属标签

相似技术帖

官网相关资源

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