一、STM32中断
- U# ~% A) a: C7 c6 P# ]" u0 C8 G1. 概念/ z6 A* [' S. W; I9 U/ N8 \% {
中断是由内核外部产生的,一般由硬件引起,比如外设中断和外部中断等。
# _/ N+ b. [/ I2. 中断响应过程# @# o" b6 V1 D3 l
1.中断源发出中断请求2.判断处理器是否允许中断,以及该中断源是否被屏蔽% p2 F- J+ F9 @) e7 o
3.中断优先级排队
7 ^3 H( J# C9 I. Y7 n4.处理器暂停当前程序,保护断点地址和处理器的当前状态,根据中断类型号,查找中断向量表,转到对应的中断服务程序$ n5 s5 l& {9 @
5.执行中断服务程序8 `) i7 Q: Y# v- q% t
6.恢复被保护的状态,执行中断返回指令,回到被中断的程序
) ^$ e0 v- |1 W7 ^
5 `0 R" a" u/ T* R, J; K1 b. `中断全过程
+ H" g$ c+ s' _! {' k& a( j5 C3 `# R
: j8 W+ b6 ^+ T5 @2 D: G* P* F
( j! U! U9 ?5 J9 E; V5 h0 t3 _中断分为同步中断和异步中断:
! K- c" A/ C4 x( q. l* h v, k* b4 Y5 T7 M: x) c P8 r4 k) b+ o
同步中断:同步中断是当指令执行时由控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后 CPU 才会发出中断。
! @# V' c C( C9 a: i异步中断:异步中断是由其他硬件设备依照 CPU时钟信号随机产生的。
1 f& ?/ Z; K9 B3 q! e8 P% ^. a0 Z6 W: \, @! K0 e5 D8 T2 u! q9 K
3. 中断优先级' ?6 r# d* i; \+ ?. [- \
; |3 h) s* D, ]7 N# j; v
2 S- ] e% r! r& D a" p0 j
8 Y3 p" r/ ~' y1 |8 P+ x
多个中断同时出现时,处理器先响应高优先级的中断
; ^9 V6 C& K) p4 |低优先级中断的ISR执行时,可以被高优先级中断再次打断4 E' r! d5 r% q, U6 N! K' S
ISR比App Code拥有更高的执行优先级4 F: h- { `# p, |5 }& s
7 l% ^, g( U) c& E% }, \二、仿中断高低电平控制LED灯
: N& l# L5 f9 I. v& r" J; j, u2 ?$ n1. CubeMx/ q" c8 n2 r) s% L j
进入STM32CubeMX新建项目* s& b, t' g$ D# a
" _# o! e, @$ y3 ?
6 M7 s0 _' h4 q2 o/ T$ q) r0 ?
( ^& K+ w1 J& y: }检索所需芯片,并完成项目的基础创建
/ W/ |3 K v3 {4 |; c/ c
: t9 u. d! \0 m* o$ [( f
8 f* \! l8 d4 R8 H* ~" E) W* M2 B/ E" G0 E
点击sys,将debug->Serial Wire! x" ~6 C3 M$ {! v9 l" B0 M6 A
7 g0 a! `1 ]0 E5 p) q
+ Z5 u5 e" A' R, z( i1 B
: t/ {) r) ?, `/ A3 {, P+ mRcc->HSE->Crystal/Ceramic Resonator
. }/ V+ y2 w* y! G5 R( {3 h- o- F! f: s. @+ m+ l* d2 ]
7 R! e: E7 A3 `: S0 {! }8 R
2 j/ R! b* F- P3 q4 u将PB0选为外部中断触发器,PA2控制led灯的->GPIO_output( u- r$ r: e8 B5 o. M
5 g4 R9 Z7 a9 P9 i# I$ o2 ^
" N9 {/ C% m8 ~ u' F6 ]) k
! k: }+ y. H! S8 A
' i, T6 H! R- F
, L3 S+ K B! b9 D9 b! r- }
设置中断触发器B0( o) {# B! r, c9 o Z
- ]# z; a; n7 J4 g1 T7 e0 c( t: O
9 k4 s7 I; Y8 C3 d' u3 H) {
C* s, \( X Q4 APLLCLK,晶振频率最大值改为72M赫兹
: i, Z x+ Z) S6 f" X( Z* r0 h0 R, T4 R$ N L
% N' a8 a9 I, \2 n
7 i& G. j+ r6 n/ |' @( {NVIC设置:
" N; v' ^/ s* ~6 F0 x: M' ]8 a
7 ~$ c" _, K" `, `; D5 ~/ R
" }: f1 u8 D% y& o# A6 Z6 Y" v
; S( s7 ~" x* U3 j* I6 b- I T完成项目生成
( q0 c G% X; Q; a' H3 mProject配置
4 v# h2 T7 \! K0 \' O+ h, s3 [+ X
+ D1 ^. g: A7 i8 |* B4 q2 E6 y9 }
2 s% J( ^" z; b, |
Code Generator
* s3 d, @% c$ \; s( H
! s3 @$ c, p, b
3 s, a* N1 |" ?7 t* n( J" O
( V) y0 k4 E) i# @. p9 |6 t项目生成$ `. j+ [$ U/ N3 W9 {
" P1 H4 k: j+ N' j1 L+ U# Z
' ^& ~; n( o8 |5 B8 l' y8 _% p
4 v+ A/ \) g/ O7 c; w2. 控制代码编写4 c1 [, l7 B: I8 C
打开工程,搜索HAL_GPIO_EXTI_Callback函数:
) e* l2 @0 |+ J
- z" S. C( V& \
! }+ p. z6 _7 ]; u9 O
+ j+ t) y) S4 N弱函数,需要重写
9 ^' C8 T! b9 d9 R O. _
5 u# e! D+ ^5 }& I" R( _* Y
- V& [; z9 O, j& y1 M" E/ ^6 @/ l6 S0 @/ X2 T
main.c中编写回调函数- Y0 G& x+ l! {! V
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){0 i7 i8 p. k& m' ^1 w
- GPIO_PinState b0_pin = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0); // 读取b0的状态; C, g2 \0 b% s `" [
- switch (GPIO_Pin){. h7 c! ^5 C5 y- Z
- case GPIO_PIN_0:7 Y# L+ m, x1 j" N. _
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, b0_pin); // 将a2写入与b0相同的电位6 @; K( }. o' J2 p% q, a! K
- break;
u0 V* C. H0 V9 p e$ s1 C9 y - }
$ p$ u# u+ e2 ?+ ] c4 m: k' y) U - }
复制代码
9 A" T$ C8 [* o
/ i" P+ Z x) l2 U/ {9 e7 L# M& b" v
3. 编译并烧录
0 V* x; |2 q0 ~6 K/ g5 x e9 y" y& @3 T3 x# S, v) c. l
! V u3 a; Q2 u* U C% f( c& p
% V. C: M+ U2 ^" ~使用mscuip进行烧录/ O* E- X# `. Q$ J% P# k
) j3 Y( U8 _) ~
0 _9 W4 N; j% N/ s6 e! B" C5 m) l
1 Q0 R* z, i$ W/ G. U8 i4. 运行结果9 c8 ~ b) ? w0 u' M
5 V# e1 H& C" I2 ~, F
! d4 {$ e# v, q
2 K) L& C4 X" ~2 K三、HAL库中断方式进行串口通信
) y9 W8 d8 D+ D* h, \4 e$ N3 D1. CudeMX配置项目( b: F y2 @" Z% w( z
点击sys,将debug->Serial Wire" f5 Q8 ~+ l! M: [6 Y% l
( J; w8 E8 `" H- f, z6 Q( ]6 @, N; L7 c |. K: y& B1 i
% ~3 a" Q, b5 Y) k$ ]3 mRcc->HSE->Crystal/Ceramic Resonator
7 u x# u7 G g$ c7 m# }& J
3 c! V0 `& `; k, ^5 G0 E! Q `! I. X8 j
% ^7 }" N" Z! z2 Q# ~: [( E
A-Z->USART1->Mode0 O" Z$ @; g: r- l$ D
' }" ?$ ?% ^7 {2 d" W1 m) X( s
+ I% a9 e3 |) p
; s2 _; ^" R' v! ]
NVIC设置:
4 q/ }9 T$ h* `- k# p" d8 H$ B9 @& j1 r9 K. x
5 M* I% q6 m3 F8 x% A+ A
# E8 f& |+ r2 `$ L- E( @* o5 k完成项目生成9 F+ V4 q( M7 o7 z1 m3 T
Project配置
4 L h- R9 ]! q8 c2 y; }( x% I, C
8 p5 O+ Z5 m8 J
; c& L. `7 ?; f/ p6 M$ H# j9 T/ q) r `( `) f) }; x4 Y& H+ ^
Code Generator
# Q2 V- X I& p
L+ b( `+ }6 E( M+ \
3 s8 g+ S- e, U2 n& \2 s" i
- X y; h, O7 m! B% B+ @项目生成
/ K) X: {- G4 S' F" P* b; z! J& t- r F4 j
; e8 j/ u/ \6 M1 Y5 u$ d1 N
' O! Y `1 y, P
2. Keil代码设置4 G8 \, l# J7 ~) X, M8 |
main函数定义缓冲区大小" R% F" d+ t6 }# i4 j- y
- #define LENGTH 10 // 接收缓冲区大小
复制代码 9 i' K$ l: [) |
8 q, f2 ]3 o8 E; k0 v, }" D% k% C9 V, S0 x! Q& @
2. 定义缓冲区和标志位6 B/ n9 r, D* Q3 r
f) ?7 k: \6 E9 z. S% |; G- uint8_t RxBuffer[LENGTH]; // 接收缓冲区
1 u( `" b% }9 [0 G( a! `% d4 @ - uint8_t Rxflag = 0; // 标志位,0为接收未完成,1为接收完成
复制代码
; ?/ [& `" M2 v" v
" w, v U! i6 Y$ W4 e
) O: ~( \* @! C, B6 j6 B
3. 定义接收成功信息. a$ x6 i& J$ a) I, I# M3 F, g, |
: y5 s$ }" v+ P9 Y0 O
- HAL_UART_Receive_IT(&huart1, (uint8_t*)RxBuffer, LENGTH); // 使能接收中断
' ~4 e r0 B% @ - char data[] = "\nReveive Success\n"; // 接收成功信息
复制代码 1 s( n2 Q5 w J
4.while循环发送信息与接收信息6 @) N, F( ^' a
- if (Rxflag == 1){ // 若数据接收完成
; V( ?1 u' P* F - Rxflag = 0; // 清除标志位, \3 V0 [- c, g5 B, R
- HAL_UART_Transmit(&huart1, (uint8_t *)data, 18, 0xFFFF); // 接收成功信息
% W5 L: Z+ }) J9 y9 b, L$ _ - // 发送接收到的字符# ], x' m' I X# T/ Y: u/ n+ J
- HAL_UART_Transmit_IT(&huart1, (uint8_t*)RxBuffer, LENGTH);$ w! @* X! n+ a( c5 R9 D
- }
复制代码 : ?9 [! B/ M, T; i! c- y6 a
5.定义回调函数9 H( X; p. z9 c% a
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){4 g, z$ h# \" i
- if (huart->Instance == USART1){6 Z4 B) z, v5 E0 `; r
- Rxflag = 1; // 设置标志位为1
9 s! r6 z @2 V& M9 [* h' V - HAL_UART_Receive_IT(&huart1, (uint8_t*)&RxBuffer, LENGTH); // 使能接收中断4 a4 {4 Y) H: f. I" f8 ]: _
- }
& a- Q0 ]2 o! P- b+ q E, q; z - }
复制代码 , i- J5 n$ [1 J& K y
" P8 F1 H+ q0 G# C, X6 w* W$ z! E5 u' {$ @% s2 ^
6. 编译烧录
" a2 I& s/ v. T8 B s6 `
# K: ]+ B& L9 X# c
" G: Y( u. z1 F+ a6 U4 v; h+ Q' M
7. 运行效果4 m0 N& y9 i% G+ h5 p" k2 h5 b
) J% A- z- s. @7 S; G% j) Q/ {7 g
# P# _$ Y1 T5 I0 B, n/ u/ c
2 N3 R3 u) e9 b0 ]( e, O; r
四、总结
! A P1 A, b& d+ |! [: [中断方式不必等待数据的传输过程,只需要在每字节数据收发完成后,由中断标志位触发中断,在中断服务程序中放入新的一字节数据或者读取接收到的一字节数据。
8 c1 t& W9 d6 A8 W ], }2 ?提高Cpu的运行效率,可以处理突发事件& y. A% t- I3 z9 \
————————————————( G2 V0 S/ e+ ~( P6 K J
版权声明:Tarbet" a0 J5 U2 |# X
6 }/ J0 [4 i8 S: U" v) o/ ^
2 G( z; n5 ^2 f% c8 [: y |