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

【经验分享】STM32CubeMX— 配置串口1 接收中断

[复制链接]
STMCU小助手 发布时间:2022-5-15 16:41
实验操作% m# s% p+ y8 D1 [/ z/ c
1、打开cubemax ,芯片选取。, ~: S6 z# {8 e7 k
选取STM32F103RCt6 (根据实际情况选择),LQFP64封装的。然后鼠标双击中间那个圈住的地方就可以进入配置界面。( d) N& H' o2 f7 }

5 D% y& S$ Y: s 20201021113415189.png 图1、芯片选取界面
- u7 w8 q' z% Z' B1 T
# f" b7 D4 h. i: i! M% v. w2 a0 E6 l1 _+ L( Y' E1 l
20201021114212900.png
6 R# w6 ^6 Y8 s$ L! f) e# A9 e2 ^# F4 d, X# j# p2 u0 C+ ^
图2、配置界面) B/ M5 o. ?# A- x4 r" N: y

$ ?6 N* Z2 v. x- }如上图:! W: X: ^  k9 l! n5 @
% w3 F+ x8 \- v8 Q
            (1)、标号1 为系统核心的配置,其中由晶振的配置。+ w  D! N3 E) ^$ t) G" h
4 w- i; e5 ]& V2 n
            (2)、标号2为模拟量相关的外设配置,如adc,dac,等。
& O( b7 \3 u* ^9 o5 w
" c5 J1 y9 E3 ?7 N  o3 F            (3)、标号3为定时器配置。
& y# N' q. H- ^- h) E* A, Z$ Q! }! R7 h5 g
            (4)、标号4为通信相关的外设。比如串口,CAN等。& ^2 `3 n: g3 l" j# L
, b& w* q+ j; w/ w5 C
其他图中有标注。
' X. f; _5 L2 K9 p. L7 F9 u2 r' ?8 g4 `  E, r9 |# I
2、晶振配置
; g6 k; D+ k4 Z4 R3 [/ L( k+ b" `        晶振是单片机的时钟来源,相当于心脏,先添加晶振,点击上图编号1,然后出现下图,在点击RCC,进入晶振% K4 w3 |" b' d% @! g6 l
; S, d; ~3 i& U1 m
20201021114516692.png
! V. K8 X! M# K: u8 x
  J- w. C- Y) c1 X5 `/ t 20201021114618318.png . I$ T$ b5 B* E: p8 A% S& s
6 R/ E( x* j/ ~# ?, @
如上图:HSE 和LSE 都选择Crystal..选项。然后注意芯片示意图上有四个引脚变为绿色。
) n- y2 Q/ r8 F* _8 x) T* q+ E2 |0 W: Y
3、时钟树配置! _/ k8 r+ z) k3 R& i( m' N

2 e3 l- g% P9 N. P 点击 20190713232239519.png   出现下图,时钟树:2 ^3 u# P3 h7 N; W; C" E+ ~

& Y  e% A+ H: g% k! g3 n% @2 S 20201021114759826.png $ j/ M0 ?8 j7 M. }/ n# _& ^

! z" r) }" l2 T8 M3 v" M; c* C4 Q, V. s
配置时钟树如上图,改好后按回车键生效。0 Q( {5 g! K' I9 o, j$ S: x" e
0 a: q$ K9 [3 v. V! G) K" T" J
4、中断管理配置:
3 J8 r; V* d7 S8 Y0 z2 C' k2 X: h; h- g4 W
20201021114926115.png
4 Y" |; u, {" |+ ?+ x' Q1 {+ {- Z0 S* {
点击NVIC 后,进入如下界面:
* _3 R/ p" o8 c) t* [
; ~% C! R8 V/ a. V 20201021115138715.png
! w" ~9 ~2 m9 v) i, o* G2 g9 U6 d3 ?' a4 v$ O/ z
到这里我们STM32的系统基础配置就完成了!
; k, N; e& m: q$ e5 @
) P- o5 H) P, `4 u* X5、外设配置
1 X& v2 b- }  C" l+ f8 [) U+ Q& v; X2 Z
下面就是结合具体需求来进行配置,例如我们这里讲的是串口1以及串口1的接收中断配置,那么下面开始配置串口1 及其中断。; D# m3 q$ @4 w. ~6 I9 f

8 D& i8 F/ K8 Y$ A8 }" } 2020102111545925.png % |1 z5 J2 ~5 q1 A
# M6 a0 i/ c" y4 f3 _+ y
20201021115640761.png
0 R+ R: E' x  U% c, V- U, n( z
# Y- G, V+ D5 `: g这里只要选好模式就行,可以注意到,芯片示意图上已经出现了串口1引脚 。但要记住这里的波特率设置为115200了。这里串口就可以正常使用了。但是,我们还需要使用中断,所以还需要配置串口中断。
4 f& x; }, Z" U+ J4 h8 a$ O+ ]$ L; j" B4 ^5 E) e
20201021115807741.png ! H& A/ R: b& \9 N2 M! F) T

) @/ ?$ n! N: k7 l. h/ o9 A4 g中断最后还需要设置好优先级:3 `; O0 R; K3 p2 h7 R. P' `8 Q
  Z; E" V( U! ~% e
20201021121247742.png 2 `$ U& j9 _& n6 `$ g4 F  q

: f# H2 s* q+ a* p- p8 |到这里,串口1的中断就算是配置好了。接下来可以生成代码了,但是需要几个小的配置,点击工程管理* h. C) ?9 t3 i# O0 s
8 i+ e5 i& c7 t
20190713232951864.png
) Y1 i9 s: n& ~$ H- u
+ P  {+ g5 [$ U9 y1 F. b6 |7 ^进入管理工程界面,
% h* Q7 d; B9 ]+ U2 G% q6 `& ]
7 m' A6 j1 i. h- y2 \# Y $UJ`L$WM4FUXEJE`EC(PG$N.png 0 q1 u2 n: ?3 b% F+ z$ E. l

  M' {9 l! e# t6 Q1 u9 p! b' N OPZRWX~K_RINCGJ]M@$Q{KM.png
2 H4 n3 o' \( i: R8 M# z
- _2 l4 i, a: G4 D9 N5 I: {9 x到这里软件的工程的软件配置部分就结束了,然后生成工程代码,
4 d" g8 J, B+ \
1 @" s# W! v( V6 G MGBK@(SYSJDZ4EEO`J6`9}V.png : a/ y8 l& j  \7 K; g) U
  Q* t& j* j. ?; Y/ g

& {1 e# i- z* _; G5 K0 u6、工程代码上的配置以及修改) y# K6 g+ C( O7 \. u2 F9 |9 N7 r
- c/ f6 ?8 I5 t1 g8 R
使用keil5 打开刚刚生成的工程代码。; x2 Y6 j$ v+ [' `- l; l
9 Z( Y) x1 U1 {$ d
`RD45$TRIFV7R)1QF[9WG3C.png
9 I3 F  M3 ]  y* Z" T
/ X! V! @! G) Z/ M! N KJDYCSUJT7YY@NNNB4UZA%A.png : r* d+ {/ d% o( b3 R

& \8 U0 v" O$ _( t  g! j$ V/ X, B找到main.c, 会发现如上图的主函数结构,其中, ?) t- A9 @0 \: t0 [1 q
$ k9 y, l" k2 D! x
MX_USART1_UART_Init(); 就是软件生成的串口1初始化配置。
- p3 }2 o+ g* ^; v/ T7 h3 _9 G4 v) l$ e$ G2 V
如下图,光标放在相应的函数上,鼠标右击,选择GO TO Definetion..  选项即可进行跳转。" C  T9 g5 V9 @+ k) ]- O+ F
+ n- V: {/ `- A4 ~, }6 f5 f
HPN1O[VAM@HWG_5J062R_W2.png + g- Q5 y, p) T. T; r8 Q; M4 E

! y: h9 U* T  L5 V4 F4 s) ^4 |0 \跳转进入usart.c 文件,会看到,MX_USART1_UART_Init();的函数体。
$ ?6 J* }+ H  J/ ~! L3 ?( Y) V. a$ `8 H2 J
  1. #if 1
    6 E8 h, x6 \. d" U2 D, |

  2. 1 j9 i9 [/ ^4 l
  3. #pragma import(__use_no_semihosting)                             # n+ l+ k% M7 }; B' t8 ^8 a& e% ?

  4. % H8 ]2 K' H. N/ G2 q, v, k
  5. struct __FILE
    * m+ {" p2 g; G9 {" ^. F* S

  6. 7 i' S/ ~# f; N' y
  7. {1 w* K: E& v& [$ E
  8. " K3 E3 G6 ^% o- J5 ]% o2 R2 {
  9. int handle;5 O! U( ]5 R( d
  10. / M1 e8 y# n8 w& m+ B8 I9 H6 h( h
  11. };9 u. p5 P+ t* H  J2 A7 Y

  12. 2 Z9 ?1 k$ b9 a) g
  13. FILE __stdout;      
    & z0 c  |# z( W9 g8 x
  14. ( Y8 N/ q0 R% w7 J* O
  15. void _sys_exit(int x)
    $ @) f! e1 R2 G
  16. + v- {' ]  W' w2 t
  17. {
      L9 P8 q/ Q1 j3 _6 n
  18.   i, G" p. o. d2 V8 s. r
  19.    x = x;
    $ y6 _- K) i* o2 z0 i: O' H. S- v
  20. 0 A  k+ E' U; I. u; R
  21. }4 t8 j, z% O' V2 W% a" a

  22. " \3 l& U. \2 o- k/ s5 w( I; }
  23. int fputc(int ch, FILE *f)
    ( i; |/ k0 w$ G8 [6 n7 t
  24.   l8 {3 L7 ^/ w. E; z, i
  25. {     - c' N8 f4 p% `( ]- v. \% @
  26. / b' W; m/ T; @$ j3 }- p
  27.      while((USART1->SR&0X40)==0);  . v+ }! w4 x+ q2 c
  28. 1 M3 e) K% M4 k: J$ i: i
  29.     USART1->DR = (uint8_t) ch;     
    ! {( g/ ?9 `: r) N6 I
  30. 9 u: ^- N  t+ Y- |; l8 s. a6 p
  31.      return ch;; a- w* x9 P3 M& S  Y

  32. 0 i% Z- W( p3 C. p
  33. }0 K6 r. x" g% f2 z

  34. 7 s+ B. ]! k# p6 r+ U, \! [
  35. #endif
    & U9 V+ `2 e. o- B4 q+ m3 W) N
复制代码
' N  }7 ^% D1 P8 V+ A) x/ E
4 y# k4 B% i# a* T0 a, A
在这个usart.c文件中添加如下代码:,如下图所示- B) i- t, W6 Q7 t# a2 i

+ n6 G9 D+ e: y& a8 t7 t 这段代码可以在STM32中正常使用printf()函数。具体添加位置可以如下图,注意所在的文件和位置。同时不要忘了在usart.h 文件中添加#include “stdio.h”
: T0 p3 S* M. e' r7 F3 W8 `6 b! A- W: \- G4 ?. u/ Q7 T  \4 I7 x
* ^4 v! a" }& @
AYV@XN$C3F@BP~]MHI)$PRF.png / u( D; h$ {* ^5 b9 W# C
# X/ C6 ]2 `2 L, U' S, ^

& Z, V9 k7 O3 o- g4 [/ X添加 #include “stdio.h”) B9 y1 C0 A( q, M4 S* f
7 H/ o1 d/ s( u( f9 j5 q
AJ7OGS8PM5X7(45N[[MSM59.png ' k2 n1 h) i+ J% o" J2 m) }" [2 ]

( ], v% J) q8 K: N
5 r) }4 [+ g1 o. C经过上述两步就可以正常使用printf() 函数了。/ a& j, X5 ]$ _1 H+ M

0 _- S8 _: f1 ~$ t最后配置中断相关的函数,
" @9 q2 J2 L* w- S2 `5 G$ x4 a7 t2 }8 ^& |1 i( n) R8 D
(1)、找到中断服务函数
5 I1 v1 S- R$ i: @- }3 c, L6 D* z: H  N- K
位于stm32f1xx_it.c 文件中+ ]) E  k: e% P: Y5 L- h* I

: f! R6 H% \8 ]" E# w DX3B~I(B{%R7O$DG)~$IQ%6.png & B; j& O0 |1 Y9 J
1 g% Z2 k4 w0 Y: q
(2)、找到中断回调函数! v% _- Y1 l; D( x% L! F5 Q- W- S+ G
: k8 B7 T6 p& J+ j" P
1)、HAL_UART_IRQHandler(&huart1); $ {3 R5 C; C" U5 X$ P4 i
" ^* \8 U# f3 Q* M0 ?
2)、UART_Receive_IT(huart);
  W3 b5 d. y% K$ d; ^0 [
; `! |5 N3 |! k7 U3)、HAL_UART_RxCpltCallback(huart);0 W2 u8 g. k- t4 a6 }& X' T% Z4 Q
* j  {% K& ~% T/ ]0 \
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart), S  H( z1 B  N" W9 Q7 |
% m( ?' H' s- V* G5 l" c$ h2 [/ f; G
从1)可以跳转到3),                                    
& m8 B. M4 C# G9 ]" k7 ?8 D1 c
: d( l! L& i7 @void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); 就是串口中断回调函数 。
1 p2 @% m+ r/ O. S/ h
# c/ B9 ~" ~1 o9 U2 {( t并且将void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)复制到usart.c文件中,如下图。在这个函数中就可以写中断逻辑, f. {$ ?0 l# s: ]

  ^3 w; C6 Y" U3 \2 q/ N# F 6 I9 i# V1 a$ O, B6 W! _

$ z2 H3 F2 O+ G: D" Y3 Q4 F) i, r
! `0 I0 j2 Z: n* L* F" B( `9 X(3)、开启接收中断
0 T5 k1 I9 a0 U' i; g) H
. l$ Q- b0 t7 DHAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
# ]* U* D2 r# ~: l7 S* a
$ j5 S2 _* E/ P2 s% D0 Y/ H/ }在这个函数中会使能接收中断,需要三个参数,分别为
+ D6 |3 B: R6 k8 X
. D. q* n8 d8 l9 T2 P) t1)、串口句柄,
7 l) Q/ G2 j4 P2 |8 W7 g5 W0 N! b0 j' [% n# _  S5 D
2)、保存接收数据的数组,6 |% U* u3 h0 C

1 u8 h) w& `# X$ a, x3)、每次接受的数据字节数,
3 O( L' |% J7 B# S. o8 W! J" J
% ^& h% k0 f( W所以我们需要首先定义一个保存接收数据的数组。
3 P) V; {) u6 y, n8 P" R/ X9 ^
' _7 b* G* n  Z5 m B@UB)H5%G5YQUN)QRRQG5XH.png ( M- ~" @6 g+ |' o# y& @
) P$ D) T; }9 ]& @
然后开启中断,需要写在两个地方,分别是串口初始化的时候和回调函数的最后,如下图所示,
. j0 d, h) d( N# p( V* P* |$ v8 l% g; L- A
([LNTPKDAX)CR@WNKAS62BW.png
3 ?" c* A: \4 |  }' h/ i6 i" V
4 a' C1 S0 Y, c5 D2 F. }  w# n# M0 j  P  L( {- \* H
最后 在回调函数里加入如下代码进行测试:7 R: l6 o5 }. g

2 X. p  [" h' p4 {& {# ?$ t )2VINME338U5}4GM9Z[`{CV.png
; I. b/ L$ |! Y% h% a3 F# N; p: A: l( o. _3 _4 n- g7 r2 ]
最后下载程序测试,
! ]3 s; D8 {( w! K8 W& `4 Z' `6 f. x/ ^- g- y
点击发送,单片机收到数据,就会打印出123.(因为我们使用的是串口1的接收中断,所以通过串口助手给串口一发数据,串口1接收到数据,就会触发接收中断,执行中断服务函数,最终执行到回调函数也就是我们的中断逻辑。这里的回调函数只是为了说明问题,实际使用时还需要判断是哪个串口触发的中断。# g2 s2 a8 ?7 t$ E7 F% b
2 q9 R0 g( s7 E% k3 X0 A8 ^$ [

  G* S+ ?( H& Y+ [1 G5 J# f
- _. j0 C# a0 \& J; P- s( C
赞 收藏 评论0 发布时间:2022-5-15 16:41

举报

0个回答

所属标签

相似技术帖

官网相关资源

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