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

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

[复制链接]
STMCU小助手 发布时间:2022-5-15 16:41
实验操作, J5 y* ^, T; e3 F7 O, O# M8 C
1、打开cubemax ,芯片选取。
' Y5 Y! j4 M! s# I8 @% [. y选取STM32F103RCt6 (根据实际情况选择),LQFP64封装的。然后鼠标双击中间那个圈住的地方就可以进入配置界面。
2 h1 m- v5 K5 A3 }; B) U# ~1 L5 ]! a7 ?6 c! S8 \5 a
20201021113415189.png 图1、芯片选取界面% Q- K: U4 D: L" @, ^& X' D

  z; o! I2 Q+ `
3 g, c, }$ Z; f8 K 20201021114212900.png 2 J, ^1 g; }9 G, A- ?! P5 x# G. b

2 j1 E8 x! X9 X, q图2、配置界面
# t; N# V7 r$ }4 u7 t
( {- A" y& r$ U4 Q: H6 x, N; [7 N如上图:/ `, N& T" _& M/ z: M/ v+ z7 ^
% B* l5 ]  s0 u& e
            (1)、标号1 为系统核心的配置,其中由晶振的配置。" W- m; m. M+ T/ \9 _- u& |

: r& f7 p) K, G+ J5 u; g            (2)、标号2为模拟量相关的外设配置,如adc,dac,等。# P- Q& e) i) t2 j3 V  `$ y! F5 j. |
3 m6 y, h9 c+ ~! u. s  r
            (3)、标号3为定时器配置。
, F0 n6 x4 y; d3 j1 n  G. C3 O! I/ Q. x
            (4)、标号4为通信相关的外设。比如串口,CAN等。
# g1 p: t; l( |
2 r! s7 s( t3 i. J其他图中有标注。* Q3 F4 d  Y2 \# t6 ^! v$ H% Y
2 R8 n0 x3 ?  ~: `- U
2、晶振配置* [: s4 J8 w- f- f: K
        晶振是单片机的时钟来源,相当于心脏,先添加晶振,点击上图编号1,然后出现下图,在点击RCC,进入晶振3 \- Q+ ]2 [- }
  |% |9 g" m' i+ m
20201021114516692.png
& `, {& ~) h9 K8 O% Y5 W( B' Y2 M! I' `# x; @& z
20201021114618318.png & _0 w: ?1 q# U& i: M5 d; q

- _' Q# f" W* {/ G1 A& B$ \如上图:HSE 和LSE 都选择Crystal..选项。然后注意芯片示意图上有四个引脚变为绿色。) k% @3 \7 p6 R9 s4 w; {

/ w* ^- z. B; E8 s. n' C8 E  x# U0 z3、时钟树配置
+ J! t( N0 M/ b" a/ @1 Z/ I' }
, ?4 ^9 N  |+ Y1 I5 F& l2 ]# X 点击 20190713232239519.png   出现下图,时钟树:9 ~& J( I/ n2 |
9 K% ^6 q# Q* C. H( Z
20201021114759826.png ) n: n% o1 W" `- l
4 a% ?# z) b& x) k5 f
9 w/ Y6 ~9 |# f. g8 w
配置时钟树如上图,改好后按回车键生效。: @1 n% ~* \, ]+ ~1 y
4 {# Q* z# d  N: v6 ~
4、中断管理配置:
1 }, ], z0 D5 f# @" q8 q+ S6 w% a5 n' h
20201021114926115.png
: O' ~  R8 T4 x) M$ e8 L3 d3 b/ J1 q0 v
点击NVIC 后,进入如下界面:5 @, h5 |7 g8 c$ f1 T

! t5 i' Y% ]3 | 20201021115138715.png
' W* _$ L1 m2 [( i
6 Y3 ?; `" G7 T9 k到这里我们STM32的系统基础配置就完成了!1 q2 }" T4 T$ q) p" j& @7 U

: v& w9 ~6 y3 s$ C2 u7 _3 p& C7 x5、外设配置
$ f3 K5 E0 D  l  v8 R
1 B2 S) ^; Y4 x) A/ }下面就是结合具体需求来进行配置,例如我们这里讲的是串口1以及串口1的接收中断配置,那么下面开始配置串口1 及其中断。! r; T9 ?6 I# z% a+ c1 G- j- j

3 s7 l! P2 T; ~# l 2020102111545925.png
' p# u& s5 k5 P
$ M) l( j( G8 b+ O6 o 20201021115640761.png
& L; h/ q$ D& f! K" @5 @! e
: g0 E3 K0 D& S这里只要选好模式就行,可以注意到,芯片示意图上已经出现了串口1引脚 。但要记住这里的波特率设置为115200了。这里串口就可以正常使用了。但是,我们还需要使用中断,所以还需要配置串口中断。
1 h) j) U6 c$ Y; ?1 Y% u2 a$ L+ d6 F) m1 _( B1 [" s
20201021115807741.png
: f) M9 \6 d3 K* Z7 h" |
, T, ?5 D3 C( B! V! A* c中断最后还需要设置好优先级:  D! ?! ~. _9 b0 o2 }" Q
" `( `' z: e9 V. N, b1 S
20201021121247742.png ; }; `1 p! `& ?; }' M! `
% p% K7 D" h& k
到这里,串口1的中断就算是配置好了。接下来可以生成代码了,但是需要几个小的配置,点击工程管理
. {, l% ~' \: n: y& G" `
% `# E0 ]  s/ ^5 q1 ]' u/ P" B 20190713232951864.png ( i# ]3 N: k' J8 s" a! ?2 B

9 F# [) @1 G6 j进入管理工程界面,; y, p% B, a1 B! z0 T% Q
+ B, m% l9 J8 ?9 Z
$UJ`L$WM4FUXEJE`EC(PG$N.png ) ]$ T" N' z: v) f+ l
' B& m3 _) r2 `* u) O# r
OPZRWX~K_RINCGJ]M@$Q{KM.png 6 y2 \5 j) N; r9 C" i+ Q$ Q9 n( C
% q& X) M3 _: g$ U5 b7 h- S' U
到这里软件的工程的软件配置部分就结束了,然后生成工程代码,; o. x7 y9 a( e5 y/ I" u2 j
) e! t' e5 H6 E% R- M1 K
MGBK@(SYSJDZ4EEO`J6`9}V.png ; p' U* ~) H! M; _3 y7 w: V

. O5 @: M2 b# ^- n" i  k
! ?/ U* Y9 u+ ]6、工程代码上的配置以及修改
" h" v) V9 s) b. H1 x: G
- l% X3 G# f/ [# v7 V6 B
使用keil5 打开刚刚生成的工程代码。3 p3 b8 _4 _' t- n% |2 G
9 ^$ b0 n! n. u. U1 E; J) b
`RD45$TRIFV7R)1QF[9WG3C.png 6 Z) x4 l# h- s) G& F

" }+ E; P; _+ s- i5 E KJDYCSUJT7YY@NNNB4UZA%A.png
( q' L% R: [  u) \+ `
3 K; S1 d1 i# Q7 V& j找到main.c, 会发现如上图的主函数结构,其中! S$ s: F. |" W6 F  {; A

" g0 t! |2 D+ q- y4 B7 m, kMX_USART1_UART_Init(); 就是软件生成的串口1初始化配置。
5 J: t& a. g3 G+ O9 V# |/ p  x
! s  _* p" L; ^& A/ C& A/ E如下图,光标放在相应的函数上,鼠标右击,选择GO TO Definetion..  选项即可进行跳转。
) Q3 h7 U; }: {" h% C! m) h) n( M; M# Y$ p' `& ?
HPN1O[VAM@HWG_5J062R_W2.png ) m1 ?# w( E1 x' e

, K0 c4 t# N: M/ H/ ^# @4 }( N跳转进入usart.c 文件,会看到,MX_USART1_UART_Init();的函数体。! C1 T# _' O" D% U1 R' N) Z6 u
/ a( C5 o& W3 {( z9 y0 t
  1. #if 1* F# a3 u0 Y3 Z' e- v

  2. 1 H) t! w; |3 z# c0 B" p
  3. #pragma import(__use_no_semihosting)                             
    , {9 W# @1 H8 ]

  4. . W; C& t4 U/ s9 s
  5. struct __FILE
    + ^# d( K+ ?" ]' l, h  A' h+ L( u
  6. 9 B+ g- c- r+ s8 }0 o" L
  7. {% h" ]$ d. T8 w3 U

  8. / K8 \- k1 s: I+ f0 ?# C2 e4 F
  9. int handle;
    ! h% j+ J$ W- [: N$ N; \" C
  10. * c0 @1 k2 u8 l
  11. };
    2 n$ y) X* p/ X* X. D! v. C' w9 ]8 K

  12. ( a  m/ o0 q9 B! i, P. L& w4 u4 w
  13. FILE __stdout;      + s  ^. n& E7 S: g1 D
  14. ) P5 Z" z# ]0 Q; H
  15. void _sys_exit(int x)7 K  d+ H# S- X  j+ _" u

  16. 2 {( y* \* e* x6 t
  17. {
    * V' w% s% [2 \9 C

  18. : ^( D9 S; z' l- l8 u6 I
  19.    x = x;
    * Q1 w: u# l, e* w9 K

  20. 7 @' p$ \9 Q; T! A! D' m
  21. }
    7 s* M0 [8 E1 ?

  22. 3 A& F0 l5 A% r  [) ?. E8 V) s# D
  23. int fputc(int ch, FILE *f)
    1 T/ }# U  ^" \# |! o

  24. " U) t: x; h- Y8 d7 h9 G
  25. {     
    6 e; ^$ a! r( D! q& H6 C  J  |

  26. 1 |& K! w8 U1 H" n: J, w
  27.      while((USART1->SR&0X40)==0);  : c& ]2 s4 v- k4 {! W: F" [7 W; W7 F
  28. $ [/ T7 f  K, _' G' A4 N6 }8 ?
  29.     USART1->DR = (uint8_t) ch;     # s% w3 F( h' R
  30. $ p8 F" p0 G8 h2 z3 r
  31.      return ch;
    # f) ~( ?. X" a/ G

  32. 8 z' a% {5 P& h# O$ U
  33. }
    ' L5 B0 V6 a4 M( w5 E: D

  34. 4 y" F0 l) z; ]9 G8 G( d
  35. #endif
    ! I; a5 p0 Q/ Q. C
复制代码
6 I  _; m, B! `' K+ h

) p9 q6 j' T/ R在这个usart.c文件中添加如下代码:,如下图所示
. {7 S: l- S" |# W; i5 g4 I2 W7 m# T, r1 y8 V! O
这段代码可以在STM32中正常使用printf()函数。具体添加位置可以如下图,注意所在的文件和位置。同时不要忘了在usart.h 文件中添加#include “stdio.h”
# ~' p/ z8 j$ V% V( n, v3 m
$ I& w/ s# ?! @. N3 \4 @7 x) p6 k6 f# Q. J. y# D. q# h
AYV@XN$C3F@BP~]MHI)$PRF.png
3 Q( d# g/ l7 `3 U0 P5 Y% S7 \  ]+ \; Q! t( O! G& z! t
4 n$ _8 o& N8 r8 y7 Z
添加 #include “stdio.h”+ B7 ?" ]0 X" U  W

8 R$ `7 L+ L& _ AJ7OGS8PM5X7(45N[[MSM59.png 1 i5 U: w: f, m" n6 m6 ]2 O
, e! ]3 M! G: ?+ m0 b) c. m0 ?
7 a0 q& h6 k  }/ C8 v/ B% z+ |
经过上述两步就可以正常使用printf() 函数了。
5 k! _, A" L: v# B
* k% G& G5 V& V最后配置中断相关的函数,' H6 ]+ M4 D6 M- Y9 [2 y
) a  I0 W  D! \
(1)、找到中断服务函数- i8 u. q* m! D+ u: A' a7 B4 Y

6 y9 O$ c8 K& V! M6 Z! D/ s位于stm32f1xx_it.c 文件中
: X* K8 T7 y% `1 g0 Y* h' o5 A
4 l6 g- |0 g! K3 R DX3B~I(B{%R7O$DG)~$IQ%6.png
0 i' v; _- ^& I' g1 z7 N
7 x: u7 R9 n8 c+ C& h" K(2)、找到中断回调函数
  ]1 C8 [$ ~3 ^; J6 ~
8 N' E$ w; E! W, u9 I1)、HAL_UART_IRQHandler(&huart1); ' |3 w9 d; Q+ q
9 p  ~0 p  N8 k' g
2)、UART_Receive_IT(huart);
* Y* Q+ W: @$ i% F) E" _' p% \
0 X9 O" t$ P, k" ~/ [2 p; I3)、HAL_UART_RxCpltCallback(huart);
0 n- V% G( R! g( F- Y1 o2 x; n! T! B) _
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/ J2 M8 g/ O4 X  t# r+ {0 I# F$ m/ l9 D- P$ L& b. Y! e3 Q5 K
从1)可以跳转到3),                                    
1 _7 t  T2 N8 B  L! D% k: Q' I2 m; _! Z; V3 t; [
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); 就是串口中断回调函数 。3 c  r8 j; L: j' p$ x6 L( W

+ ]' q/ \% n. s8 [$ ]5 t并且将void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)复制到usart.c文件中,如下图。在这个函数中就可以写中断逻辑
, V! t% G" P$ j9 e( J' c6 y4 q8 `# R. l( l
/ a0 t6 b1 _0 |8 y6 R- I$ M% w6 F

7 N) k1 @3 [& H) k$ k
1 {, u8 q1 r% F9 _/ L(3)、开启接收中断& i% j1 Q. p4 N( }" t/ {

' D; B7 p1 V. k+ |' w. k2 e% ?HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)) n4 z1 x# V$ L1 }
4 J1 w+ e. O3 A- \. n$ i, n. c* j
在这个函数中会使能接收中断,需要三个参数,分别为
- q" ^( f  }. a* u5 d, m; ^5 s$ |- A+ F/ B- ^: ]& c2 b* u
1)、串口句柄,9 s( k4 G5 s9 G4 G9 o9 f9 t6 R

$ U* D: F6 j7 R3 G2)、保存接收数据的数组,
' L3 t' F$ p) m3 |. A, t0 [% K7 z  h! b& @& i% g/ K4 n/ X; b
3)、每次接受的数据字节数,6 N6 ]' ?4 d" p: U
$ t1 G3 r2 @7 s) L3 c2 S
所以我们需要首先定义一个保存接收数据的数组。, J- \: h4 ^- n# g3 I2 a; x9 J; f
% e# d4 G: s! K/ f/ O
B@UB)H5%G5YQUN)QRRQG5XH.png $ g% Y  P; C( |6 M6 i

( Y) i& h% G9 p/ f然后开启中断,需要写在两个地方,分别是串口初始化的时候和回调函数的最后,如下图所示,. u# w+ M6 q% M1 y5 r8 h$ d; `

. Z9 p+ b2 V7 W6 ~; k ([LNTPKDAX)CR@WNKAS62BW.png " }; r- I* F! \
0 K4 v) H8 S8 p

6 {' }5 r2 V2 }# g$ R) N7 H最后 在回调函数里加入如下代码进行测试:8 t6 E4 W  _2 s2 I: w

! a4 R! T  I1 K7 M7 V )2VINME338U5}4GM9Z[`{CV.png
2 b+ |# n( P7 G2 [+ G" k* f! E* z
8 {; E8 Q' e0 n; ]* m0 H最后下载程序测试,5 s! n$ S) C, K# o" i, V. M+ b8 \. }' O

  [1 V. C, p, h) B7 ?9 N; V. U5 [点击发送,单片机收到数据,就会打印出123.(因为我们使用的是串口1的接收中断,所以通过串口助手给串口一发数据,串口1接收到数据,就会触发接收中断,执行中断服务函数,最终执行到回调函数也就是我们的中断逻辑。这里的回调函数只是为了说明问题,实际使用时还需要判断是哪个串口触发的中断。! Z# G( F" u# F( _

" K* F1 d0 Z" b5 Z: f7 n- ]  [2 X8 Z' `/ x

! O7 R9 U3 u) l1 D& Z8 P
收藏 评论0 发布时间:2022-5-15 16:41

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版