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

基于STM32串口通信经验分享

[复制链接]
攻城狮Melo 发布时间:2023-4-30 17:47
前言
6 a# S- U/ h$ L. o+ ?& e众所周知,串口通信是MCU最基本的通信方式,对于STM32来说也是如此。本文重点讲述STM32单片机的串口通信,主要包括的内容是:通信基础知识、串口通信原理、USART有关寄存器和自定义编写串口通信函数。
/ M( m$ N1 x6 s) s* ^- P
8 A* m( B- o4 y: K8 l! g
# C% j$ O* ?  {
一、通信接口背景知识
& M3 }) W$ |* W8 s  z* O! l1. 并行通信和串行通信3 c6 E6 \8 ~; y# ~: H6 l* f
所谓通信,其实说白了就是处理器与外部设备之间的交流,就像电脑连接键盘、鼠标或打印机之类。计算机领域的通信一般有两种方式,即并行通信和串行通信。这两种方式的优缺点对比如下:
% b+ ~- j+ C" z5 m& z& g/ k9 Q/ _( K5 S$ x; ~7 R

; N9 _1 \  z7 G: |* n( L并行通信* v7 v  T- P4 E9 J" H5 P# E- M' b
   -传输原理:数据各个位同时传输。. s% n) S* P" j
   -优点:速度快. M* T% i, m% e+ q5 K& u$ p
   -缺点:占用引脚资源多  r6 n9 A0 Z: t
7 C( I  j  h1 G: a1 U: e# H
* {0 A8 j) O' w: k5 j' K- z! ?' r
串行通信
, o1 Y5 f+ D8 X# s$ S( C1 h   -传输原理:数据按位顺序传输。
1 G2 g( `. d$ j, p1 d7 H5 Q   -优点:占用引脚资源少5 z" n4 ?" ~6 m+ {* o- \9 t
   -缺点:速度相对较慢
& h# i. \8 m: @! A6 h  n6 ]9 y% i0 G. H! h7 f/ @; @* G" X/ F/ U

4 ^2 f  R( G0 H8 C% _. ^2. 串行通信的分类! r' ?$ p$ `# X8 b  r4 Z% [( a/ n
由于本文所讲的串口通信属于串行通信,所以就不对并行通信做过多的讲解了,下面是串行通信的分类,按照数据的传送方向可以分为:8 C' y0 S/ f$ u* D, ?

. w' L0 y2 D$ O& r* O
) ~7 q2 l: w$ `  Q) u9 u3 P9 @; ]
单工:数据传输只支持数据在一个方向上传输$ \/ y2 S; m+ I0 l5 j
半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;; w4 R' j5 h0 C9 m5 f( B
全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。$ }! f8 K0 [: ~7 F) o8 f

, _* v5 v' |8 {; i3 F
0 I& C; {3 F2 @9 U9 N
为了清晰的表述这三种传输方向上的区别,我们看下图:
6 j1 W4 A4 [7 P8 D% c+ @9 L
) X2 G( t! v: |, K9 R; Z ac264b36384549b9ba1fef9ce2eecce0.png 9 R  Z& n2 m% ^& L# l1 R+ E

! Y" C! P3 {/ i2 [5 W/ ~5 T
9 J2 f8 r3 p3 {; D
(a)单工通信        (b)半双工通信        (c)全双工通信4 A* d0 w$ H4 s) q1 _) A8 l
另一种分类方式是根据通信是否有时钟信号来划分的,分为同步通信和异步通信。
! P6 [  g- U/ ]) `* h: {同步通信指的是带有时钟同步信号,比如:SPI通信、IIC通信;$ E2 Y5 s! ?3 o! [0 m! `5 t
异步通信指的是不带时钟同步信号比如:UART(通用异步收发器),单总线。
  P6 d$ w( s$ W* ]5 K我们以下面的表格来详细对比串行通信接口
! M: a' L5 m, E4 l0 ^7 |: o$ b" O& z2 ]. l' Z! ]& c

6 J0 @/ `5 R* j3 P dbac60db4f8d44cd9aebe6ff7c41dd9e.png * D6 j" }# C- ?4 `8 w. y8 T( Y6 g

' n6 Y: X+ D, Z6 Q# H 二、STM32的串口通信基础& a. ?7 }% b4 o0 ?
1. 串口通信接口
' m' ^0 e' d. ?9 D/ sSTM32共有两种串口通信接口,分别是:UART通用异步收发器,USART:通用同步异步收发器( t4 U7 h0 J7 S" a" E
5 `$ j8 ~+ y, O& j6 f7 b8 n
* a$ A3 I( N5 _5 `
对于大容量的STM32F10x系列芯片,包含3各USART和2个UART。UART异步通信的引脚连接方法如下:: D; t. o" Q2 b( }$ `  }" U1 n4 m" j

0 ^+ @" z5 `7 C5 A8 m- v

* S3 Z5 D6 c4 }4 D) g, p& p# y/ w$ u$ k ae83c1e6cdcc465c811713789ed680d4.png 5a3d411cdfc34816884a0632aa76d7a5.png
! n4 k/ n# L# E4 K8 \! X# T( {! A# M* ~& \4 ?

9 b( h6 ~/ B4 J* ^+ V

; ~0 w' h: L7 e7 B/ E; \+ o% T 这里需要注意的是:TX引脚要连接另一个控制器的RX引脚,反之RX亦然。4 C' r+ J7 Y% K8 N; N8 }

- p8 i) ^8 f3 G$ f' a

. b( `" \' s+ s7 f. c9 H: c! Y5 T& o下图是STM32大容量芯片的5个串口对应的引脚号,可以通过中文参考手册查询0 F: e$ }/ U4 Q/ n1 a) b* \* Q

) ^7 a6 a& x2 T/ n

( ^4 i. F" t: Y0 b) E bd0eb7a3a0324fec9d37b41bf66549e3.png 8 x+ C" i8 f2 r- x% z

+ o  q& z5 d5 j+ Y

9 w* E. \; ~" @* ~2 \( W 查阅官方手册,UART异步通信方式的特点如下:
" e, e) d% {" L  r0 @全双工异步通信。
1 Q7 T/ |1 ?* B) K+ E分数波特率发生器系统,提供精确的波特率。发送和接受共用的可编程波特率,最高可达4.5Mbits/s
# |9 Y- Q& p$ x. ]8 _2 q: v可编程的数据字长度(8位或者9位);
. T( [  U5 P: j$ x$ R9 L可配置的停止位(支持1或者2位停止位);, x# ^! w# `9 M
可配置的使用DMA多缓冲器通信。
, K1 Z) \) b  E. e: r单独的发送器和接收器使能位。9 H* w9 c6 z# j+ P
检测标志:① 接受缓冲器  ②发送缓冲器空 ③传输结束标志# W+ H3 C! d( A
多个带标志的中断源。触发中断。
7 N1 {& I. y. g- P% s% ]% |9 e( W其他:校验控制,四个错误检测标志。
% W5 T0 F# z5 V  Z$ t
+ d  [- b6 l4 `0 H0 k; F

( Q6 D* ?& O# F/ D' @* j2. 串口通信框图4 G) V) l0 K  X' W
学习STM32单片机的外设,最重要的是要理清楚它的框图,下图就是串口通信的框图:0 _2 w& @1 S- d. ~2 s, [

& P+ Z, C8 R0 B  ~

( F2 X$ F7 Z( G dd78b14eb86e4e77b2a014b9c6b4b78b.png
9 s/ N; r. K/ s( I5 Y+ Q* z; ]( m

3 r2 J4 i9 m0 ^& t) c! `# v' b 从这个框图可以看出,STM32的串口通信是由最下面的波特率控制部分产生波特率,给来自PCLK1/2的时钟做预分频,再经过1/16分频后传给发送/接收其控制,最后分别发送给发送移位寄存器和接收移位寄存器。这两个寄存器分别在发送数据寄存器(TDR)和接收数据寄存器(RDR)的控制下完成和外部之间的数据发送和接收。8 _1 r8 I- ?4 x  h) D

0 i- u3 v0 Q4 k8 P

& k" `) z0 E2 e3. 串口通信相关寄存器+ g* S1 n2 s$ J, r8 ~* Q7 O
STM32串口通信的相关寄存器共有3个,分别是:
8 ~! B: x8 U( x- }2 X' \; ~USART_SR状态寄存器
& Z) R# Y* ]( C" ~* x, Q, iUSART_DR数据寄存器7 ~! S/ R* g- f( [* {" I6 k
USART_BRR波特率寄存器, i+ d7 C& {& H0 e( V+ D. O

  h! N4 p  \4 Q9 r* U) {

/ h" |+ [) W  {下面是来自中文参考手册的部分截图介绍:: ]% J5 q) \0 y& Y& \4 ]1 }
- R, U% O) V  n5 n

* v, O" ?, m; g' m% I f0e2865656ae4eacbec160743e72eb10.png
0 u( d7 Q/ W$ s4 R+ N1 U( P0 ~1 q* i7 Z1 Z7 V! q+ _

2 a, w% [9 A4 g! X( n 013795b8c49844c5b88516740459945f.png
2 [1 r. }4 n3 h& c+ b# b8 r
7 o/ O( h: O% |: t1 H* c  Y

+ H' N7 n. v7 ?  r3 H0 o 2f215c8c96684ff1bfb8f1393e05792d.png
" U% f- q$ v- @3 G/ p/ k" l7 e
* i. p" ~, h$ D) k% A4 J. @* D

' X! T' w0 l" H5 j( p! s# M6 Z 5bfea7743ff1400982e0d60669cdf153.png
* `* v" M; L9 }3 O2 g0 W. Y  z) G! n! I  k/ r' Z
  x( T! D* y. F8 y
86c8749d79e54a679d98a5a8bc376faa.png
, L4 z* J& k) a5 A, m( i8 |3 R0 q& k& f
# S6 E0 k$ T" y+ z
8 z  N: [' G* S; a! _
还有一个寄存器是控制寄存器,用来存放串口的控制和中断相关配置位,这里不做展开了。$ E  ?0 M9 c) U) o* u6 o
* H: S% [4 ~, m2 Q* Y- c+ }

2 w8 X# d8 q# R建议大家在学习基础外设(GPIO、定时器、外部中断、串口通信等)的时候不仅可以熟悉库函数的编写过程,寄存器编程也同样重要,不一定要掌握,理解即可。读者不要被寄存器编程吓住了,其实串口的寄存器相对于GPIO是很少的,配置过程也比较简单。
6 O, w; T' q: r
% r6 S5 g3 e% [3 U$ P
: N9 |" @( U# _" D: @0 J7 P9 c
4. 波特率计算方法3 X7 F$ ^1 x6 a  C6 g* d

. ^3 B2 U, h, a

3 @: l# _& l% }( i' `) x8 @8 ~, T 7e31640e4c1943e4902dfcd07fded844.png
' M' ^9 G' m/ h2 ~7 m* ^( `# [( e: S

3 _% k( P2 `0 g: X, E ce096aec52a5437aab8de43298e90825.png   J# e1 E/ W% t2 S3 ?
/ ^4 r8 ^+ }1 k9 b5 ^

5 G4 |+ J9 l# I  z9 L 这是官方文档的信息,波特率预分频器是分数预分频器,为什么小数部分要乘以16呢,大家可以理解位最后的小数是四位,四位二进制的1111正好就是16(15)。
6 D& l/ ^+ K: {! X+ g$ c$ R4 n2 G# n
& Q2 \- ~& A! t: u7 F: }% v  V0 P

8 y0 R+ F* m5 S. q7 @三、库函数配置7 G* a1 A8 x' B0 p4 ~; b5 @
1. 串口配置一般步骤, t' |9 t# s. r1 F
串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
- f% H1 }. U9 ~, S0 Q, s5 f串口复位:USART_DeInit(); 这一步不是必须的
3 c, O1 c" D2 |% k: jGPIO端口模式设置:GPIO_Init(); 模式设置为推挽复用以及浮空输入或者上拉输入(具体可参照中文参考手册)
4 o- z( C+ h# Y6 C2 j& z% g& s8 O串口参数初始化:USART_Init();
$ P! {( S' b9 v# E开启中断并且初始化NVIC(如果需要开启中断才需要这个) NVIC_Init();USART_ITConfig();
; u1 O/ x! W$ u' E使能串口:USART_Cmd();
; M/ s% M1 _8 O- i" a编写中断处理函数:USARTx_IRQHandler();
% J9 p  F* J! R9 q$ H  {4 e串口数据收发:void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据7 _+ J" M7 N  l; B6 p
串口传输状态获取:
# f3 x8 \3 h& t+ Z. r$ iFlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
3 E  G0 }; V. F: J
4 w  y6 Q& t7 ^0 J8 T6 b; S, \

$ t, P4 m. Q$ `8 |; k6 xvoid USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
( ^  d* a6 I1 p; Z) h8 m4 _2 v3 H% q9 i————————————————
, n+ Y' m9 P6 O  C- ^, c( R8 [  u版权声明:KevinFlyn
% c- a: a- c- @; K* D% O7 Y  A" a( B- V) q+ R
如有侵权请联系删除
" Q2 E# N# A3 c' l" W3 a
3 q8 ^4 X$ m# J( U3 _: _! }- R/ x  M5 I' }& \
赞 收藏 评论0 发布时间:2023-4-30 17:47

举报

0个回答

所属标签

相似技术帖

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