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

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

[复制链接]
STMCU小助手 发布时间:2022-5-15 16:41
实验操作
: X2 {, X- s/ W& ], @0 N0 T2 Y/ ~1、打开cubemax ,芯片选取。
6 t( Y, X" j. I  ]# Z2 l/ C选取STM32F103RCt6 (根据实际情况选择),LQFP64封装的。然后鼠标双击中间那个圈住的地方就可以进入配置界面。9 ~& D' y2 w1 H8 s; J  P
9 L' S/ ]8 i+ i" Z; B- ?
20201021113415189.png 图1、芯片选取界面
, S( s; k7 {. H# K: ^4 ?
' O* O2 H. b- E  X! X: L! A
. W  u4 F  x$ B$ e 20201021114212900.png ' F  Z! ~8 U( l. S4 A( G+ \

$ C, M( c/ p( M图2、配置界面
* C; N* r7 m8 U9 X; T) i, G% b- j! `+ @& J
如上图:/ m& F( B2 i9 W6 E  G1 m4 T
$ L, L) r! ?, `+ q- D! w$ b
            (1)、标号1 为系统核心的配置,其中由晶振的配置。7 D: d- ~# Z; X$ |

% I4 N# l) ~1 q, T0 Q9 H2 d, J            (2)、标号2为模拟量相关的外设配置,如adc,dac,等。$ H, h$ o/ F! Z" ]9 a, f2 D! N: {

/ C& [7 ]* A% D            (3)、标号3为定时器配置。+ B$ a9 _9 K9 K! B5 ~
, s7 {) D  P; Z3 C) b
            (4)、标号4为通信相关的外设。比如串口,CAN等。6 t: e: D* Z1 L3 f; l! K
8 m3 a* |& G" z2 Q
其他图中有标注。
5 Z7 q! k% ^8 A6 k, K
% A  K: d. t: q9 Q4 |  U; Z0 t2、晶振配置2 q/ Z7 I8 ~! Q6 p# r
        晶振是单片机的时钟来源,相当于心脏,先添加晶振,点击上图编号1,然后出现下图,在点击RCC,进入晶振
" [: [! c6 g* E1 d4 j
2 M5 I* G- L2 J1 }0 [6 J 20201021114516692.png 9 \3 Z0 p9 K7 ?3 `" B% a
6 Y  `# K  C# b: y5 X3 k9 _3 Z
20201021114618318.png
7 O; U' L% Z7 n0 O% U
. C% L2 L/ V/ I! I8 U# y: F6 J如上图:HSE 和LSE 都选择Crystal..选项。然后注意芯片示意图上有四个引脚变为绿色。" k" Z9 L7 j* K# K" m/ k( p! `
) G% C; D$ D" }5 ^( B5 C; d/ G
3、时钟树配置6 o' B5 J$ L; n+ g; G# i
% D1 w4 n& _3 P2 @+ F, p  T2 E
点击 20190713232239519.png   出现下图,时钟树:
, E% H& [' g) [) F2 d2 p) f& m- e- z: F% m8 c' p' ]* l
20201021114759826.png
2 D. P4 q3 \$ C* H: o7 L6 J8 F3 p" _  v9 M

: Q# e. M2 k4 t, U! ~/ U配置时钟树如上图,改好后按回车键生效。
/ I( ~7 }  G; L2 k& p! p$ x% Y8 F0 W8 ?! [: g% n& ?( u
4、中断管理配置:
8 x2 p/ f! O0 l+ W% U1 Y+ F! y1 W- C" ?0 ~  Y2 g
20201021114926115.png 9 y1 [6 N( }. Y# |- ^

9 J! b$ T. r# [- y/ T点击NVIC 后,进入如下界面:
! A! Z& I! d. k1 a( ]
4 Z; K& L2 t7 P$ e3 P7 \' [ 20201021115138715.png
  R# q+ f/ I9 D/ \$ [& c0 g. q
  q3 A% g5 k! G0 O1 H3 [2 i到这里我们STM32的系统基础配置就完成了!+ L! ~7 J8 I4 _: w- R( c+ H

3 F9 ]2 F% T5 e5 D4 U' W! _9 L1 a' M5、外设配置- q, }/ M; m4 g) P/ ^; n  \

$ w# `) x3 O! K3 Z/ c" j下面就是结合具体需求来进行配置,例如我们这里讲的是串口1以及串口1的接收中断配置,那么下面开始配置串口1 及其中断。7 n% V, m0 Q7 ^. `  E) b& r: y. ]3 i6 U: L

% g  P; V& o: r 2020102111545925.png " j6 O4 y3 E4 f: C
% R+ B' R( K. C( t  o- \* }) J* w
20201021115640761.png
) j7 p9 i1 M) R  h- b& s3 B8 f+ F4 p+ I" q1 L% M
这里只要选好模式就行,可以注意到,芯片示意图上已经出现了串口1引脚 。但要记住这里的波特率设置为115200了。这里串口就可以正常使用了。但是,我们还需要使用中断,所以还需要配置串口中断。
5 ~! A- K. \8 ?, K
$ ]  `& m( |" E- [9 V" S 20201021115807741.png
7 K3 R/ ~' k$ m3 [' O0 o0 J/ F5 ^4 v9 p% E# ]% @9 m0 x
中断最后还需要设置好优先级:- N4 b& {% ^$ n. q

2 y6 J$ W2 P2 S# a( H 20201021121247742.png
+ o5 r+ W6 r' K: K! A( s* n# J: |7 z) f& h3 {# s
到这里,串口1的中断就算是配置好了。接下来可以生成代码了,但是需要几个小的配置,点击工程管理7 n% Q# r9 \! F# [* i) r7 b4 z0 @

; u$ H  g& a! _7 ` 20190713232951864.png
- L/ k$ ]3 b  `; j6 p1 T( A9 {+ j: ~4 `2 x
进入管理工程界面,
! |6 a( B3 @4 e) g6 O
. j0 d9 U0 {- Q3 _: n $UJ`L$WM4FUXEJE`EC(PG$N.png $ h9 D' i6 s7 T0 t, d: u6 u! ?( b; n

: Z# ]6 i( W) ]5 U6 Y3 a OPZRWX~K_RINCGJ]M@$Q{KM.png
! ?: r* D5 u' \: @. Z' Y7 s( T/ d
- m/ g% N- ~% x) e到这里软件的工程的软件配置部分就结束了,然后生成工程代码,
4 \5 L' U0 \" Z7 ?
9 d8 F' y% x7 Q$ a  ]4 @ MGBK@(SYSJDZ4EEO`J6`9}V.png
* t6 d9 s3 }  Y; U! Y# b# ~
/ p0 ]8 W( q# h9 r# _- e! \. }' S- z4 `; c0 m' t
6、工程代码上的配置以及修改2 m5 R( `- o/ w% C6 P
- J, e* u% d1 Y2 q
使用keil5 打开刚刚生成的工程代码。) {6 S) e3 R# p  l9 S+ r/ [, m& w

% {( x, }" }2 a$ _2 q `RD45$TRIFV7R)1QF[9WG3C.png
% g+ b* t* P& M2 Q+ V
8 n8 J. e; i/ ?0 F9 |. Y1 g KJDYCSUJT7YY@NNNB4UZA%A.png
/ i: ~2 b! b8 U- P! i8 K) s
; N6 G5 ]- N9 v' e* G! J  W找到main.c, 会发现如上图的主函数结构,其中9 n( [+ {1 F2 o! R3 G1 z
$ u4 V& y* p/ _% D
MX_USART1_UART_Init(); 就是软件生成的串口1初始化配置。, L6 F2 Z1 D9 p6 G

/ ]' V# u$ T6 T4 _# @如下图,光标放在相应的函数上,鼠标右击,选择GO TO Definetion..  选项即可进行跳转。+ x# w; b8 X3 Y. r4 s
1 ^& v% Y& f8 }! j" G
HPN1O[VAM@HWG_5J062R_W2.png
* F  k' B6 q0 @; ?! X8 \& n; g- v8 R; A0 P
跳转进入usart.c 文件,会看到,MX_USART1_UART_Init();的函数体。
8 F9 N2 K# i( T, s0 p. R$ d( c( z
7 C& \: M  c0 e! I2 n. U' P) _
  1. #if 1
    9 U$ G: [0 n. Z9 A$ }0 W

  2. $ Z9 W1 B$ ]& \, S
  3. #pragma import(__use_no_semihosting)                             , \! f, P6 e. `6 R/ _

  4. + p0 p* R( A$ Z* L3 m
  5. struct __FILE
    $ i! j! b+ W1 W+ f

  6. 1 [/ o  z# ]% u7 ^( H; U5 }
  7. {& H( i! [2 x3 Y5 O$ _* l! v

  8. / y; W) a' d1 a1 n& F" {
  9. int handle;6 |7 w, o, h# s6 l( D% F. H+ d2 B% e
  10. / r9 [2 q- |# }% E
  11. };
    * o- C: |+ n. `, ]9 |6 A
  12. ! i5 J9 H( q( @& }5 M! p1 J
  13. FILE __stdout;      
    ) O1 ]/ |/ V' H4 G' ~! J* N
  14. + @, _  d; a: G  R/ H8 `8 d
  15. void _sys_exit(int x)
    % R( {0 B9 ?9 r' _/ a" K

  16. - j$ ]& L! ^# n. J  V& Q" n
  17. {
    - r7 w& \4 W: i( }! G0 }$ Q9 D

  18. 6 s% m6 I) l2 b( W0 i" ]& e
  19.    x = x;  h( ?5 N: _" q, ]8 K$ J) j7 M
  20. " B7 l6 E0 Z# s+ J
  21. }8 P9 |: @4 r5 U1 t

  22. ' T* s; C! o. }1 p
  23. int fputc(int ch, FILE *f)
    0 g  b( g4 ?$ M5 f% e
  24. $ z, T. X' f' k& y: k
  25. {     ) {6 q; R2 w  d+ G

  26. 2 K/ s; k1 y4 N7 p" ^
  27.      while((USART1->SR&0X40)==0);  - [  g- t# U( J0 T! t- p
  28. 1 K/ l  R4 |8 }' d$ b9 h& X
  29.     USART1->DR = (uint8_t) ch;     
    - I6 ~2 T# m( G" l
  30. ! W3 c( z' Y- f" e8 y. w% M
  31.      return ch;* c  p6 H) U* J! x5 Y0 B5 a: w- Q% c6 k
  32. + a. S* D- w7 \5 F0 Q4 N: |
  33. }1 C0 N( m. d1 W% w  q

  34. $ r# _* `( s+ y8 q) i4 C
  35. #endif
    / B' z! K2 ?3 q6 ^$ _
复制代码

( x  G$ d2 C2 i4 e
3 C+ q& h% R, [$ A在这个usart.c文件中添加如下代码:,如下图所示% u0 H" Y/ k+ ]) l
3 x- r1 F- H7 X' B9 A7 w, s
这段代码可以在STM32中正常使用printf()函数。具体添加位置可以如下图,注意所在的文件和位置。同时不要忘了在usart.h 文件中添加#include “stdio.h”( e- k' b, F$ a+ d$ \4 A( g" L1 \
3 N0 ^/ x2 h8 I% v' H6 Q
  F& M* V% C8 r
AYV@XN$C3F@BP~]MHI)$PRF.png
& m; r" X* e& J$ U, J$ O4 c+ B7 T' F! B# S7 a

1 P# @5 }% I9 W& r0 |& w( a# s添加 #include “stdio.h”" F+ W- F# U! x' E: N2 o
; T0 ~# G6 ^4 t$ o3 ], f$ |
AJ7OGS8PM5X7(45N[[MSM59.png
" t& }- z0 [- g* H
' }6 U8 S, w1 ^% B4 R3 p$ w0 b1 l2 t
经过上述两步就可以正常使用printf() 函数了。
7 t0 ~1 V8 o0 g7 c/ k9 j
9 W- K; b! [; ?9 ]) b( t最后配置中断相关的函数,
% h0 v3 f# o1 l0 F) [$ v4 @
0 z% p) K  a$ M: H! Z+ z" _- J: B6 M(1)、找到中断服务函数
8 H. R" r( ?; j1 ?- M  d8 A4 _9 z6 q/ ?, ~: N0 r7 e' x
位于stm32f1xx_it.c 文件中" V# s3 w$ C. f+ ~9 O* P0 h+ m  b  [

& x6 J; ^* F" d$ b DX3B~I(B{%R7O$DG)~$IQ%6.png 6 j- n6 s6 x! N# @' ^* o

6 a5 F& @7 X: R( |) q6 [(2)、找到中断回调函数: `% n4 _% F0 M
2 E+ {& c) u, b
1)、HAL_UART_IRQHandler(&huart1);
$ P+ H: K# h9 K3 a6 G' n
  Z+ T. n5 n+ k# T+ `' h+ X2)、UART_Receive_IT(huart);
) @  b0 I+ ?# {9 H! W  S8 B5 D: d% m8 S& i, r! ]5 p
3)、HAL_UART_RxCpltCallback(huart);* d# v  E, r4 r& Y
* k9 c7 B9 u5 j! [: S8 k) I
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
1 ]4 y0 c7 W. `4 r3 P2 A* B- J$ u5 l& L1 i
从1)可以跳转到3),                                    
; h: l2 N( m$ D2 l9 R6 ]- \- d& Y% ^) j( j% X1 Q: P  D
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); 就是串口中断回调函数 。6 u( g1 }5 |  _/ v1 t, q* T

2 d. h1 P: u& v7 p9 `3 r并且将void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)复制到usart.c文件中,如下图。在这个函数中就可以写中断逻辑. Y; G! G1 l. S4 a
% A, b) @  j& m; i( y) |- m$ r

6 [/ b# A7 g2 q' ]( r( y+ k: h4 @0 T' s' {

, H; p# n) ?; X" B  w(3)、开启接收中断% b6 n' F. ?) q7 o

( Z( O9 H6 E% L" MHAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
$ \! o5 _/ K4 `/ V) S) v- h( y+ Q! O- H9 F+ b% l
在这个函数中会使能接收中断,需要三个参数,分别为
1 J6 B9 E6 F9 V) A, ~( D: p8 s& P# W& {1 ~2 V% c
1)、串口句柄,
( {% o* X0 _- B, g  m" l# y: |2 M+ o& K& ?3 l! A. n. Z( O
2)、保存接收数据的数组,
, _2 ?, A8 V0 S3 n( C; D* M2 \' l6 V2 B$ w
3)、每次接受的数据字节数,
3 ^( W4 F, k% h" H, R: q
1 }3 F* A1 \; Y所以我们需要首先定义一个保存接收数据的数组。
# t& z1 ~9 o9 [9 S9 k' B5 Q1 j
$ w& _. |6 s0 z, k) ~+ ?. a9 x B@UB)H5%G5YQUN)QRRQG5XH.png # G) K6 E! g$ x
4 Y& i/ _- y- C/ U
然后开启中断,需要写在两个地方,分别是串口初始化的时候和回调函数的最后,如下图所示,
0 B0 e5 ^3 |% W# A5 d
* F+ `; m7 y+ U$ T/ a1 { ([LNTPKDAX)CR@WNKAS62BW.png
' l# V; b  `$ }' t; w! b0 d, G9 K+ w8 V9 w- B

3 C) k5 S0 Y3 k! F3 K$ R& S最后 在回调函数里加入如下代码进行测试:
; Z( w% i7 ]9 M0 h% Z+ c: H
. {' B% x  e! X( x5 I. ~/ D$ t" L8 t )2VINME338U5}4GM9Z[`{CV.png
9 C% A! g1 b7 W" q$ O2 K- l' K( L3 l1 i$ S' h/ R# T4 f
最后下载程序测试,
! E- Z6 l- x& `0 T! i+ j6 G/ l$ p! {: v/ n
点击发送,单片机收到数据,就会打印出123.(因为我们使用的是串口1的接收中断,所以通过串口助手给串口一发数据,串口1接收到数据,就会触发接收中断,执行中断服务函数,最终执行到回调函数也就是我们的中断逻辑。这里的回调函数只是为了说明问题,实际使用时还需要判断是哪个串口触发的中断。7 J: v( i9 d% o

# X% [8 @" M1 v+ x' d$ H6 ^/ d7 t/ @- S
% r1 q4 v7 j( a* V" z1 p
收藏 评论0 发布时间:2022-5-15 16:41

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版