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

基于STM32串口通信经验分享

[复制链接]
攻城狮Melo 发布时间:2023-4-30 17:47
前言% ?2 b- z  k( m' \7 ?
众所周知,串口通信是MCU最基本的通信方式,对于STM32来说也是如此。本文重点讲述STM32单片机的串口通信,主要包括的内容是:通信基础知识、串口通信原理、USART有关寄存器和自定义编写串口通信函数。$ I) D% D6 A% N4 a9 B
; b6 U; o1 k: v1 O' K

: g- a" @9 s* g7 r4 h一、通信接口背景知识
& j, N& ~  }4 O, A( G1 g. g2 O1. 并行通信和串行通信
& Q5 W0 m& b7 `所谓通信,其实说白了就是处理器与外部设备之间的交流,就像电脑连接键盘、鼠标或打印机之类。计算机领域的通信一般有两种方式,即并行通信和串行通信。这两种方式的优缺点对比如下:
: ]; @+ W2 l; H3 I  u: C# D
- D/ C1 z( a& L' q/ J9 }8 [! j
; R; J) [+ G+ F$ l* V
并行通信
7 r* m0 B' ]/ c* m  B4 r   -传输原理:数据各个位同时传输。
2 w9 }* }1 d- d, _5 Z+ v$ l   -优点:速度快5 W/ T1 |5 Q9 P& T5 o5 Y
   -缺点:占用引脚资源多
) M' M+ g. h& N" f- t% E0 N  O6 b
, _8 K7 U! e- m2 g) G- w

6 n' q& K# C( F/ c串行通信% j# [: c0 c( V$ x3 c! T5 G
   -传输原理:数据按位顺序传输。' [; d* D4 i- R0 A
   -优点:占用引脚资源少
' j% @8 t! y9 ~+ ^. w' {2 K3 ~& T   -缺点:速度相对较慢
' Q8 [* h( D# N" N
% x$ P+ F9 J( _. l8 I; q
( a& f6 h( g6 K
2. 串行通信的分类3 E" X  Y9 s/ E* |" ?
由于本文所讲的串口通信属于串行通信,所以就不对并行通信做过多的讲解了,下面是串行通信的分类,按照数据的传送方向可以分为:- x. P' x' `( ^/ w# t  H# S4 J4 u$ A
: E1 T6 F- g+ w5 j7 {4 E3 b3 W

' C) H3 ]. L$ N3 c- \: J; f单工:数据传输只支持数据在一个方向上传输4 y# H4 S4 A6 G# i+ G
半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;4 n7 L  n( a) e. E/ j# ~: i
全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。
% m+ w: @7 s4 A! I8 k9 O% D$ C
$ c) [% C3 X& \: P7 D' r/ [

/ W% E! [5 u$ _% q6 S+ l; Y为了清晰的表述这三种传输方向上的区别,我们看下图:
# o  c% V& R( V3 s& t$ q* s) U0 m. Z
3 m  d% y' b9 t; F ac264b36384549b9ba1fef9ce2eecce0.png % d  F, D' X  P. X. G1 U) X( e
, C+ e" a( y' S/ a

: \0 ^+ l4 H+ v0 t(a)单工通信        (b)半双工通信        (c)全双工通信
+ T# y- P) H9 b$ d另一种分类方式是根据通信是否有时钟信号来划分的,分为同步通信和异步通信。
2 o6 b3 {  G$ @. H* w0 R同步通信指的是带有时钟同步信号,比如:SPI通信、IIC通信;2 s) j2 X- K( R. S3 b
异步通信指的是不带时钟同步信号比如:UART(通用异步收发器),单总线。
) |) J1 r/ }4 L8 F" j1 O( j$ _. C我们以下面的表格来详细对比串行通信接口
$ b3 h2 h3 y% c6 P1 W4 G( v. x7 Q0 f4 K) ?  C
8 i+ c- F/ m" S& a- y
dbac60db4f8d44cd9aebe6ff7c41dd9e.png
5 e% B1 k) j% ~. W" H) g. }4 E5 I3 ]
二、STM32的串口通信基础
1 D' R7 u. R5 t0 }4 i" V0 G! J1. 串口通信接口9 S+ N5 R- y% O& a0 U
STM32共有两种串口通信接口,分别是:UART通用异步收发器,USART:通用同步异步收发器4 O- b% t% K- v. R- G& ?" G

( r' |: t, O8 Q
0 _6 q6 F. m# T9 ^( g+ q! D1 v, h
对于大容量的STM32F10x系列芯片,包含3各USART和2个UART。UART异步通信的引脚连接方法如下:2 {$ p% @6 j/ m, ?0 o9 @! L

2 q4 V3 q3 W) r1 l/ \
) ]; X# G$ Z2 y0 Y6 ~! L: ^: _' q
ae83c1e6cdcc465c811713789ed680d4.png 5a3d411cdfc34816884a0632aa76d7a5.png
  J, k- u4 b( ?  V* S) f" g  p" t5 F5 c: z
! z1 n1 Q$ Q4 [, I, e. C2 E5 q
! s  m9 l% h; Y' ^, u# I
这里需要注意的是:TX引脚要连接另一个控制器的RX引脚,反之RX亦然。+ p0 q1 Y# Y1 ^* {/ [
% w. c5 n! i$ Z* n* t) F

  j, Z7 g6 w4 S$ ?, P下图是STM32大容量芯片的5个串口对应的引脚号,可以通过中文参考手册查询
& ?: @$ ]9 T" U4 b  `9 l; ^, ~4 U3 w1 x4 Y3 C1 ~
2 Y) c5 d6 z$ O# r: y5 Q
bd0eb7a3a0324fec9d37b41bf66549e3.png
! Q2 O* l+ d; N  |, [: J3 Y& K
3 ~6 P2 v0 p/ @/ g* y* I; v" E
" O2 F4 u$ o# _8 d; G
查阅官方手册,UART异步通信方式的特点如下:! R: J! O3 s8 S7 D4 }7 v
全双工异步通信。4 L& H4 \. j8 U9 ^/ g' p6 v
分数波特率发生器系统,提供精确的波特率。发送和接受共用的可编程波特率,最高可达4.5Mbits/s# G1 b' k  Z0 \, R5 B7 A' d
可编程的数据字长度(8位或者9位);  _, I! \/ ]* {5 r$ }
可配置的停止位(支持1或者2位停止位);
- y& z' H' d1 s: k0 v' O8 }可配置的使用DMA多缓冲器通信。
& k) z7 n, [; Y# a' ^) T单独的发送器和接收器使能位。: [  m7 |/ A9 E
检测标志:① 接受缓冲器  ②发送缓冲器空 ③传输结束标志
$ t% k9 R& n5 Z/ s% J多个带标志的中断源。触发中断。
) u( D; ]$ Z! ~4 o% H其他:校验控制,四个错误检测标志。( k8 o! F; y3 \1 E2 g+ D! R4 q5 E+ {4 \

# c) S2 e7 m2 J2 s

) M. e% p, t! i8 j5 z2. 串口通信框图
' c; t! l! x+ C" ]; |! }* P$ k: A9 i学习STM32单片机的外设,最重要的是要理清楚它的框图,下图就是串口通信的框图:3 H! b# U7 Y- H8 z7 L1 a7 z6 G
/ C9 N, n9 T6 l2 V$ J  D# s5 |
2 D3 I( V- L$ A4 b/ Q0 l
dd78b14eb86e4e77b2a014b9c6b4b78b.png % }* I2 k: V3 T% e, ~4 i5 J

  S% C2 ^5 y) |" C1 c$ F" T
# i/ z  [7 D" J+ ~2 G8 U% ^
从这个框图可以看出,STM32的串口通信是由最下面的波特率控制部分产生波特率,给来自PCLK1/2的时钟做预分频,再经过1/16分频后传给发送/接收其控制,最后分别发送给发送移位寄存器和接收移位寄存器。这两个寄存器分别在发送数据寄存器(TDR)和接收数据寄存器(RDR)的控制下完成和外部之间的数据发送和接收。
0 \: i1 Q8 \- y3 }  a4 Q% {% S- Y) s# t* u% A0 \* R

' K7 c. C5 d) a+ s/ Y. i3. 串口通信相关寄存器# }' g" o' |) V3 a
STM32串口通信的相关寄存器共有3个,分别是:
* o2 ~! u9 k8 J2 u- RUSART_SR状态寄存器  l. E* P: L9 `& R9 P; P
USART_DR数据寄存器: p0 Q3 a7 _' c2 r2 e
USART_BRR波特率寄存器
) U( L* Y8 T8 o0 y
' w* p( ^, G- i% V+ P! K" q
) j+ R% c2 i+ R/ u, `* N; B& {
下面是来自中文参考手册的部分截图介绍:5 v) u/ _+ J: g2 E: e: v
/ E+ M# ^2 @' y2 _( J' U" N

# g' [5 Z* K( J2 u) v f0e2865656ae4eacbec160743e72eb10.png
1 @# z! S+ P1 @9 a, S% b3 @. @& `3 G, n. n# t

! {* [5 R4 E- e 013795b8c49844c5b88516740459945f.png
" t. r# O; B3 A; d. j7 H6 H( v  ~4 J

5 w9 L( i6 B! Q/ _ 2f215c8c96684ff1bfb8f1393e05792d.png ; E; N$ ~0 t+ d/ q$ [# d
" m. I0 M* b: M) V+ e6 l6 X
5 u' B( M- n: s. h" a
5bfea7743ff1400982e0d60669cdf153.png 1 j6 V7 u% `  O, O. d# L$ T  U1 I* u8 l

# f- _* y( n) u" |

$ S5 ?7 k  C0 G+ {+ Z. h  c3 o( T 86c8749d79e54a679d98a5a8bc376faa.png
/ E' i$ W5 z$ u
0 M* u# u& [, [) t
  w4 c$ c. V5 k( E
还有一个寄存器是控制寄存器,用来存放串口的控制和中断相关配置位,这里不做展开了。( M1 f+ w, _2 |, ~

. X- k: H" U6 @- P( h

6 r) k0 _: o! l& p( t' }建议大家在学习基础外设(GPIO、定时器、外部中断、串口通信等)的时候不仅可以熟悉库函数的编写过程,寄存器编程也同样重要,不一定要掌握,理解即可。读者不要被寄存器编程吓住了,其实串口的寄存器相对于GPIO是很少的,配置过程也比较简单。/ l  I9 q( v7 G" z! J

# _: T1 D$ r) M0 a  P6 S: b
6 e# V, r0 Y7 }3 o) C$ O& ^
4. 波特率计算方法
) t: F* Y- V. [% d/ D) W- n1 ?
$ Z: j4 n2 R" a+ N; S$ B# l* O

' l- R# @+ J' ?9 o; s6 U1 X 7e31640e4c1943e4902dfcd07fded844.png 5 S* E1 D+ H; N% U  v9 p& e  x, }

9 d( ]9 q- S, G: n

3 T- ]5 g8 \1 n; b" A: X ce096aec52a5437aab8de43298e90825.png / K9 F# z3 o0 q& N, o* C
2 g) L- i% w  ~) x5 W

0 ?9 h% E% x. u# L1 a) @1 a) R 这是官方文档的信息,波特率预分频器是分数预分频器,为什么小数部分要乘以16呢,大家可以理解位最后的小数是四位,四位二进制的1111正好就是16(15)。
# I& ?& S( g# {, w
8 y. E0 e( _8 P

9 S5 x6 e: n3 f( F% z三、库函数配置
0 v2 g/ h4 c6 h3 P/ f3 ^7 g1. 串口配置一般步骤5 E: e& W4 h7 P- E4 X' m
串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();' V" n4 C! h, a8 k
串口复位:USART_DeInit(); 这一步不是必须的
! c6 u. S4 Z  a; y% J0 P. wGPIO端口模式设置:GPIO_Init(); 模式设置为推挽复用以及浮空输入或者上拉输入(具体可参照中文参考手册)1 Z( c5 f! X; \0 H
串口参数初始化:USART_Init();3 |: y& @2 `$ M$ H
开启中断并且初始化NVIC(如果需要开启中断才需要这个) NVIC_Init();USART_ITConfig();9 M$ K$ b" C# G) W
使能串口:USART_Cmd();3 X# g1 K5 m# f' B5 N8 E, Y
编写中断处理函数:USARTx_IRQHandler();# y, o  F# h0 Z& Z
串口数据收发:void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
5 Y3 s1 J. |: _9 G1 O串口传输状态获取:
3 L; P/ d: Z1 I1 M+ U4 uFlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
& ?- b& |. c/ ?: B# s. `) e0 Q
! c1 i5 G% M* M, O5 b$ Z% Z# C

: T! E  h& K% g; U& Q1 X- h! Xvoid USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
1 K" L4 ?# a. m0 |————————————————
5 H2 z0 m4 ]/ Q% B3 i& q( `2 U. h  ]" y版权声明:KevinFlyn( d7 m/ x& ?; \. N6 T7 G
% Y4 l9 U. l5 z$ E# ^" h+ d
如有侵权请联系删除
0 ?5 }/ U  P) F
- p4 W9 K$ V( V
% L6 a/ j5 R" `5 @1 @7 A3 N
赞 收藏 评论0 发布时间:2023-4-30 17:47

举报

0个回答

所属标签

相似技术帖

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