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

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

[复制链接]
STMCU小助手 发布时间:2022-5-15 16:41
实验操作7 ^# S; l0 N  Z! g9 L( ~! ^# x
1、打开cubemax ,芯片选取。3 p& r" x1 Z. r8 V
选取STM32F103RCt6 (根据实际情况选择),LQFP64封装的。然后鼠标双击中间那个圈住的地方就可以进入配置界面。4 j/ a. G. N/ J

9 x+ d# P& l; L/ b 20201021113415189.png 图1、芯片选取界面
! @( A) o2 M' E  i3 m8 R( a, J  _/ _5 V0 E& W4 \# I

- M) ~0 L6 k* u5 M4 E 20201021114212900.png
9 f/ v4 n7 X4 o( C. V' _
. i1 k- o# f2 i& G' V$ S6 V' S图2、配置界面
0 e9 T9 |& a' i, u
7 X6 [, A- L- ?4 V. h' {- N" _如上图:% U( e2 ?  J( D. _* ^
  \. [0 g" ]" G
            (1)、标号1 为系统核心的配置,其中由晶振的配置。7 }6 }8 ?3 R3 x. Y/ u, B

! h& q9 b% t+ D1 m7 h# T$ S1 b            (2)、标号2为模拟量相关的外设配置,如adc,dac,等。6 L0 [2 y3 E# Z3 `8 p. J
$ D: |! D; t$ D# }* i7 a, W
            (3)、标号3为定时器配置。7 \: g& k) ?4 @7 I

7 k& j9 K; L7 P" T5 _! L            (4)、标号4为通信相关的外设。比如串口,CAN等。
6 {; p( B. w5 b/ E" z; E" ]* e% N1 `* B+ j; f$ U/ x+ D/ ]
其他图中有标注。
/ L& j2 R* E) I* ]" j# q# b) l
2 u' Q% N7 [  q: X! t! G, E! s/ S2、晶振配置" s- g/ |" C0 h2 ]( @
        晶振是单片机的时钟来源,相当于心脏,先添加晶振,点击上图编号1,然后出现下图,在点击RCC,进入晶振  G* d- `* M" {+ s

( x$ b  x. \0 l: m* U 20201021114516692.png $ P3 a3 b# ^: F

& s$ G( \6 N1 [0 _7 n3 B 20201021114618318.png % z( S1 c) S9 u! ?$ C5 q3 \, D
) H! a6 {( r" E  O: ~
如上图:HSE 和LSE 都选择Crystal..选项。然后注意芯片示意图上有四个引脚变为绿色。
6 g- l; H, {6 s5 U$ W' W; w: G
3 y( @. T$ e( z4 o& e' \3、时钟树配置
: i! I$ x. K# S1 M% l. p  m, a/ D& g; H. n* F' x
点击 20190713232239519.png   出现下图,时钟树:' d) H. N! `+ y- j9 Y
+ R( G! e2 ~0 E5 l7 E* P! r
20201021114759826.png 1 U0 B( t- _$ F# d0 ^9 y) x

) N' l2 t' c% J
, S" E3 Z$ I# w/ B2 D4 h, |配置时钟树如上图,改好后按回车键生效。
8 Q, }0 C+ B- ]- r& p6 A! x3 p" [0 ^3 C- B: {1 _/ G6 D
4、中断管理配置:
5 z2 o6 |7 X- M2 c8 e) h; H9 p7 c' m. L6 o
20201021114926115.png 8 \! h" m. p0 v3 p/ x
7 }, ~! ~& l( e$ x1 Y
点击NVIC 后,进入如下界面:
  I1 X9 M% w& b, W' ?. {1 |
9 q! z: X7 U3 c 20201021115138715.png
) A' ?* j' B1 k( O* M. W' f& l: L2 Z2 o' O
到这里我们STM32的系统基础配置就完成了!$ X8 Q  R* `1 F1 D$ ^, u7 T
% Q* ~2 z0 B2 V, B
5、外设配置
$ Q* b' z% z5 n; h3 G' P8 e. W) P6 @0 g$ V. n3 M
下面就是结合具体需求来进行配置,例如我们这里讲的是串口1以及串口1的接收中断配置,那么下面开始配置串口1 及其中断。+ W& C. L# h/ |8 W( H5 r# r

. z4 _% r$ s4 o0 |2 K8 c: E6 z2 r 2020102111545925.png , z/ I$ S0 \2 [0 L& X

  {8 q0 F) C3 @3 r6 V 20201021115640761.png
! ?' P2 B$ y9 M7 k4 C
7 b' T1 n6 W3 |2 c% O这里只要选好模式就行,可以注意到,芯片示意图上已经出现了串口1引脚 。但要记住这里的波特率设置为115200了。这里串口就可以正常使用了。但是,我们还需要使用中断,所以还需要配置串口中断。
; P4 W. h7 k$ f9 V
6 ?. @7 A2 K/ m: q: d 20201021115807741.png
" J4 w$ ^' M6 H# K% B7 W! r' \. Y" i$ e, Q* P1 _. X# G
中断最后还需要设置好优先级:
3 \& x/ f( ^4 V5 m3 W$ G+ {, |7 |1 Z
20201021121247742.png 5 x! i# H$ G# T3 Z+ v4 z$ p
" U& U6 }  e6 r
到这里,串口1的中断就算是配置好了。接下来可以生成代码了,但是需要几个小的配置,点击工程管理
  L/ r% h& K  w$ Y  p/ d+ `5 d, M  ]
$ k# p) V8 J% b. R& `2 a3 q/ J 20190713232951864.png ' O; t, Z+ n9 z

* B; [; i5 f7 Z! [2 @进入管理工程界面,: r0 b6 c# m3 R% H3 [/ k( g. _% @$ c

4 S5 p/ @5 A  ]5 y $UJ`L$WM4FUXEJE`EC(PG$N.png
* g# ]% [% o9 E% v1 v$ J4 ^9 F
* C6 u; H% C! Z OPZRWX~K_RINCGJ]M@$Q{KM.png
$ `! _1 Z) z9 G( V% p- |
1 L3 @) [% r" S0 U到这里软件的工程的软件配置部分就结束了,然后生成工程代码,
% m) f" Z# @2 [' w. I& U
( W; k3 V/ Q. N; l# ]) M MGBK@(SYSJDZ4EEO`J6`9}V.png 2 e% A% d  |9 _: q* H- u

* ]- G! k$ w$ c; s& F. k( J2 b9 p" U$ |" Y! X- y) I+ |
6、工程代码上的配置以及修改
$ k( A1 P! G1 b7 `& D) @) P( ?7 J
0 R( V1 V+ ?$ W6 e* W; C
使用keil5 打开刚刚生成的工程代码。
% u  C+ _2 P3 j9 B: \
! N$ y( K$ }9 ]+ P3 h% l5 m `RD45$TRIFV7R)1QF[9WG3C.png
  G5 c, B; S) O) Z& |4 Z# X9 j4 ?( v: H. c& Y+ R9 S
KJDYCSUJT7YY@NNNB4UZA%A.png 8 q9 K' H2 X( A1 ^% K  D& Z8 K

8 V  Y- y+ J0 y0 E) j找到main.c, 会发现如上图的主函数结构,其中5 d: f# Q- v8 z+ Q

4 ?. ~# C7 ]6 C% O) KMX_USART1_UART_Init(); 就是软件生成的串口1初始化配置。
# b, {$ Y; b4 R( s1 Q8 U; D& [7 O) |
如下图,光标放在相应的函数上,鼠标右击,选择GO TO Definetion..  选项即可进行跳转。
4 L9 i4 H6 r) [- s, e* K5 f) {5 h  Y$ F
HPN1O[VAM@HWG_5J062R_W2.png 5 t4 Z0 s* b% W* ~, a/ T6 r

5 S) U5 {3 R" u; L跳转进入usart.c 文件,会看到,MX_USART1_UART_Init();的函数体。2 ?* N" F5 W/ {+ {9 R4 K* ?/ B
% B7 Q, T, x/ R: g
  1. #if 1( A1 U) r% \: R+ ]
  2. * }1 B8 K1 P5 |3 l
  3. #pragma import(__use_no_semihosting)                             
    - y+ C: r3 f+ o4 e" i. D0 v- r; u

  4. ; a2 F+ |( K' Y, g$ ^
  5. struct __FILE% D% N: ?5 L1 Z8 v8 u) X

  6. 7 z( o8 h4 G0 j* z% t
  7. {
    7 U$ T; z( H7 ~  v* _# }* }
  8. 5 T3 f, N" A/ v* C- B( h* p9 m0 w
  9. int handle;
    # `) y2 Z9 Y, R9 S
  10. * J0 F9 D1 @  A& x5 E' n! [) M
  11. };
    7 D& v% M8 a6 _! g% w6 Z
  12. ' i6 [4 w+ E2 @' E9 U5 Z% u1 p
  13. FILE __stdout;      " x6 V! p, i2 p7 ?. t( |' u
  14. 2 i9 M2 W# Q/ e! ]3 T& S
  15. void _sys_exit(int x)2 R. a) z- R* e5 A

  16. ) r" H+ X+ I+ j; }$ j
  17. {
    1 ^5 H, j% k- s$ Z; q( u5 A% t

  18. : t% V5 h3 L+ r$ Z0 S3 C" X2 E( t
  19.    x = x;
    ! }& B) A  L$ o( u7 Q/ A# N, G9 \
  20. 9 I  }' A# e  j8 U# ^% s" x
  21. }0 H& w5 B8 R5 b) [. m5 X
  22. ! t0 Q5 `5 O8 H! t) K! o( M
  23. int fputc(int ch, FILE *f)
    5 f! [4 R& i% t3 N( s4 P; @
  24. $ U" V- n0 X4 x" {1 x
  25. {     
    3 |) H$ L( w4 l5 R, e; _0 n

  26. ! Z2 I2 J+ \2 P" G9 I
  27.      while((USART1->SR&0X40)==0);  
    " I/ O) o: ]& s. V/ e

  28. $ V- A/ v4 Z1 f6 H9 x/ n& J. P
  29.     USART1->DR = (uint8_t) ch;     
    " s: d$ x' S* ^+ O- V9 k9 G+ s- F/ F

  30. : E* I% C( w+ ~2 N: w0 g
  31.      return ch;4 d4 ^/ B* q/ v  }- k' Y

  32. , L: H% p! u5 y# @( {* B
  33. }
    ' q% z) V1 u7 |: U
  34. 3 o1 c, ^$ Z2 a/ f
  35. #endif3 A# v/ [+ ^! B( [* H
复制代码
, h7 V: S  ?& Q$ [- k: X" ]' t. }
; w* C+ Q8 l- b( g) T" N  ?
在这个usart.c文件中添加如下代码:,如下图所示. E3 P5 b+ `  D" g$ U  m* n9 A- z" |$ G8 q- j

/ x0 ?; y1 q. t8 v. H 这段代码可以在STM32中正常使用printf()函数。具体添加位置可以如下图,注意所在的文件和位置。同时不要忘了在usart.h 文件中添加#include “stdio.h”
# `& u2 U* l7 Z' p8 Q; h/ O% c% e7 i7 W$ G% N+ I7 Q4 m% j# r1 ?

/ `9 q4 [( U) z8 E7 b* K AYV@XN$C3F@BP~]MHI)$PRF.png % y8 {7 b$ x7 P

: ~9 M$ C: E( I! U/ O8 P
; P3 f1 a5 @- v9 n添加 #include “stdio.h”3 L/ f$ {- p1 r& Y

0 K5 k7 F# [4 ^1 e0 h4 c AJ7OGS8PM5X7(45N[[MSM59.png
5 Z8 E2 \5 w0 Y4 a9 |$ o3 u! u. l
& A1 x! _% A5 l. O
经过上述两步就可以正常使用printf() 函数了。  Y, Y2 M5 D/ m+ r& _
: d# ^! g0 W- |% ?4 \
最后配置中断相关的函数,
# l, j/ @; C6 P( g- u- S, d* P
) g$ O$ s/ i* I! \" i" j(1)、找到中断服务函数- B5 O, ^, H3 s1 }; \4 y
0 e" m- A( T7 e# T. o" z, l4 g
位于stm32f1xx_it.c 文件中
9 B- e! {% z/ w9 I9 {% O0 S7 g5 k& S1 S, ]
DX3B~I(B{%R7O$DG)~$IQ%6.png   \6 B8 E, a6 \
  F5 `  W, x" e. M' Q( H" k$ @
(2)、找到中断回调函数; \/ j% G, R) a

' V( R: M; o% m2 R# L) K4 \  l1)、HAL_UART_IRQHandler(&huart1);
2 P. x% h1 V& l5 K, u- k1 G! m" s$ k" `; e" y: g, [8 D: Z5 f5 E
2)、UART_Receive_IT(huart);1 w/ Z6 {0 P+ b9 f" t

( T$ a/ p! h' _: i- N3)、HAL_UART_RxCpltCallback(huart);
) V' r" J3 h3 t/ ]' P* o* `- o3 x  P2 x2 h4 w$ [% J- L: t
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart): c+ ]- K! b# r- F

- T! c" p( C4 U7 G从1)可以跳转到3),                                    
# v5 f4 O) o& U7 D# E0 _* u/ X
5 c  c) y7 ~5 {. V! Cvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); 就是串口中断回调函数 。9 D( B3 _0 D- e- H/ O: ]

, w" F0 c2 U9 S7 T. e4 Y并且将void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)复制到usart.c文件中,如下图。在这个函数中就可以写中断逻辑
1 ~9 U0 P  h* k
2 Z/ `9 s+ O$ ?% n( n
/ I  x( c% D& M; ?( }6 B5 d; p0 M. p  T+ Q
* v- q' o; p- X% w" {' x6 ^
(3)、开启接收中断
# }  X4 h; M  S: }
. f3 s8 |" _+ C6 o: ^HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)! n6 a* b& B+ L) z0 I+ m
# G, ?) q! S/ |  ~
在这个函数中会使能接收中断,需要三个参数,分别为
3 ^! ^6 r; f  v. \* i: \0 ~) _( K' ]& h  l- K
1)、串口句柄,4 i; a& }, g2 p( H, A+ a' d
: J  I0 @6 W9 q7 P/ H+ X- }- c* L
2)、保存接收数据的数组,
: J$ l3 N( o! l- [' d9 ?: `* g2 b3 E% M1 O# E; l
3)、每次接受的数据字节数,9 @) Z8 `! [0 }7 c8 N) R
2 r- A- I1 |& x
所以我们需要首先定义一个保存接收数据的数组。
- _5 G  ~  h; O+ ^. x. J  ?6 x6 P' `
B@UB)H5%G5YQUN)QRRQG5XH.png + j8 C) H& S9 J1 @
2 v3 h0 r: A3 u2 y
然后开启中断,需要写在两个地方,分别是串口初始化的时候和回调函数的最后,如下图所示,- ?' E" W: {# Q7 V. ^, R0 X7 F$ Y
0 P0 n6 t6 a( b
([LNTPKDAX)CR@WNKAS62BW.png 6 J$ r1 d6 B9 ~' J  v- U$ \

& w; L8 e, ^/ O
' b7 r9 s3 X$ X: \+ [6 U: {2 W! @最后 在回调函数里加入如下代码进行测试:+ ^+ |5 ~: m( M0 ^0 l
. e$ k9 q0 v' a5 i6 o4 R2 Y
)2VINME338U5}4GM9Z[`{CV.png . w2 _8 ?8 N4 e- i! p- H

6 r3 a6 D" y5 g! ?最后下载程序测试,6 H3 g! C% |/ Y2 u2 \: U% b' k5 ]

8 J. |) x- T1 h% J' g+ W1 j点击发送,单片机收到数据,就会打印出123.(因为我们使用的是串口1的接收中断,所以通过串口助手给串口一发数据,串口1接收到数据,就会触发接收中断,执行中断服务函数,最终执行到回调函数也就是我们的中断逻辑。这里的回调函数只是为了说明问题,实际使用时还需要判断是哪个串口触发的中断。- f4 w" A1 a9 T4 W8 Q) T
# F' Y# _0 S5 j$ F2 o5 K5 n

& d; y* A8 N8 a! y. I0 [1 l, T  F3 k
赞 收藏 评论0 发布时间:2022-5-15 16:41

举报

0个回答

所属标签

相似技术帖

官网相关资源

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