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

STM32的串口应用总结

[复制链接]
STMCU-管管 发布时间:2020-11-12 11:24
STM32的串口应用总结
5 P6 U" I; ?4 G" _/ R4 [
首先总结一下串口232,422,4853 ~$ Z) B2 B5 S3 t
, M6 N# d3 J  ^* _" x% V) g% ^% G9 |

/ O* r7 b* O, s串口232:可双向传输,全双工,最大速率20Kbps,负逻辑电平,-15V~-3V逻辑“1”, 3V~ 15V逻辑“0”。
4 s  [  e5 t8 ~3 }0 s* E& r! |& f# n6 o; ~. r( w. H$ V

$ M' V7 ~# k* L. M: v+ r* |串口422:可双向传输,4线全双工,2线单工。4 e+ e; M# t$ s8 u* g

: y7 s$ C2 @! k% c, w
8 _2 W6 S7 q  K
串口485:可双向传输,4线全双工,2线单工,最大速率10Mb/s,差分信号,发送端: 2V~ 6V逻辑“1”,-2V~-6V逻辑“0”,接收端: 200mV逻辑“1”,-200mV逻辑“0”。
3 T: l1 f: U8 V$ z0 r% ]. a  J: |* e9 P
* s* y3 C0 Z3 n/ S  L. e
对于串口的实现有以两个方案:! e/ D( r7 ~/ T
$ }* T' j7 d! ?9 I
3 s) l/ _* x6 O
方案一,和原子的《例说STM32》一样,首先接收,然后处理,没有消息验证处理,这样就会出现消息覆盖,消息出错后死机,无法明确区分命令,无法及时应答握手信号。方案二,借鉴uC/OSII的消息队列,进入中断服务函数之后,关闭中断,接收数据,如果没有数据接收,等待一段时间(时间和波特率有关)后开中断,出中断,然后在对接收到的数据进行处理,下面看代码:  [6 M9 M+ r  j; C1 h

/ O  `: X: c! Q3 [+ _, B

# D+ B$ }9 Q3 H* V# v6 N  `消息队列及其初始化函数:, t8 i8 Z5 q8 I+ B" L5 M' Z  u) Z
31.png
这样就把数据一次性全部存储下来了,剩下的就是对消息缓冲器message_buff[]中的消息进行处理了,这样就解决了消息覆盖,消息出错无法纠正的问题,至于消息怎么处理就是依据不同的需求不同的处理,另外注意,握手信号好用定时器中断。1 Y2 }, W1 q8 ^

. g) N4 B$ O& Y& |* Z, [- C6 W
" i0 P/ u5 i2 R- H. o7 K; f
## STM32的IO口基本操作 ##
32.png
1.初始化结构体: X* [2 ]' X" k/ K

$ Q+ E) ]7 T% t! j8 {

5 z) q6 u/ x+ Y! ^' k: O先来看下GPIO_InitTypeDef这个结构体,源代码如下: c$ G9 X  \" A4 d6 n' Z  U
33.png
结构体中包含了GPIO_Pin,GPIO_Speed和GPIO_Mode信息,3 [9 [5 ^# ~" f: n2 ?8 V
GPIO_Pin在stm32f10x_gpio.h中有宏定义3 p9 q  c5 V% K' t
34.png
刚好对应16个端口。5 y/ {& K" ^' y8 G: A
GPIO_Speed是一个枚举类型的结构体,在stm32f10x_gpio.h中有宏定义:
. ?  J1 B) Z; g
35.png
当STM32的GPIO端口设置为输出模式时,有三种速度可以选择:2MHz、10MHz和50MHz,这个速度是指I/O口驱动电路的速度,是用来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。
1 ^" @9 H6 [4 \/ a' a, d2 \) ~# }% F3 N! v9 V2 x7 w% _

' y4 R. R1 f. f8 I0 U高频的驱动电路,噪声也高,当你不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。
- }5 ^: V: X" z' d7 l" g# c
4 E; V" l# ?& _/ R5 K+ I3 _+ |2 h
  B% x. F. X& `8 j( B8 s& c# R  \
当然如果你要输出较高频率的信号,但却选用了较低频率的驱动模块,你很可能会得到失真的输出信号。  t% j; i2 _% L4 L2 ^3 f3 Z
/ U, X7 W, K7 Z* q/ x
: L6 N' j/ E; r7 D) w) j0 E/ _% v
关键是,GPIO的引脚速度跟应用匹配。
2 J1 I, l; \( p. y3 h( F; y0 W7 N4 q. E. R+ K$ t
9 _* K# I: O6 F9 M. z% \
比如对于串口,假如最大波特率只需115.2k,那么用2M的GPIO的引脚速度就够了,既省电也噪声小。
( N5 s) o7 V1 }* ~
# |% B8 P8 a( W" W. d$ d! c

# B$ l7 N0 P) b- N+ ]. |对于I2C接口,假如使用400k波特率,若想把余量留大些,那么用2M的GPIO的引脚速度或许不够,这时可以选用10M的GPIO引脚速度。
2 v$ p4 _8 G, _$ L. S, D6 ?8 ~2 ]9 n+ j& \* @$ y6 I. k" \
) C0 r8 U1 a6 A# W2 o
对于SPI接口,假如使用18M或9M波特率,用10M的GPIO的引脚速度显然不够了,需要选用50M的GPIO的引脚速度。
3 Y% p1 u" |; M3 E- B
- r' q, e0 X0 q$ `( u( G. v
$ P2 V$ B" x% o
GPIO_Mode也是一个枚举类型的结构体:
1 t# I" P1 G: @  \2 V+ u8 @( Z
36.png
2.设置系统时钟1 E' E" E  s1 q  `: A# H
0 z% U" T4 m$ z* S. t7 u
3 L/ g. c. @8 [4 D7 y3 e
在使用端口前必须要开启外设时钟,在开启外设时钟前我们首先要配置好系统时钟,系统时钟的设置主要在库函数SystemInit()中完成,在启动文件startup_stm32f10x_md.s中有如下一段代码:
% \& |: f% U! Q1 ?
37.png
在调用main函数之前首先要调用SystemInit()函数,这个函数定义在system_stm32f10x.c中,函数原型为
$ {5 M( z) e# T5 Q) e# c. R
38.png
该函数的主要功能是将配置时钟相关的寄存器都复位为默认值,并调用' A, y0 \, i" Z2 i! B1 A* d
SetSysClock(void)函数,
/ q) I& _" ^/ [2 V# d
39.png
对于SYSCLK_FREQ的宏定义在system_stm32f10x.c文件开头已经给出,默认的系统时钟为72M,当然前提条件是外接8M晶振。
5 Z5 F  w+ \+ F$ K
40.png
3.开启外设时钟
- p0 p* o$ Z3 R  }+ R- C3 p, t
" c& N7 {1 l$ `* u% _
  m" H1 r6 L* K' r1 L, f- [
开启或者关闭外设时钟主要由以下函数设置
5 Q% d0 b7 X; `; i
41.png
不同的外设调用不同的函数,如果使用了io的引脚复用功能除了开启io功能时钟还需要开启复用功能时钟,例如GPIOC的Pin4还可以作为ADC1的输入引脚,当它作为ADC1来使用时,除了开启GPIOC的时钟外,还要开启ADC1的时钟, {; {: m3 S& p! j2 o+ L- l& I9 G' Y
42.png
其他操作函数参看库函数使用手册。9 l$ s+ C0 z& o- Y- h4 o. Z+ f

  _) v0 Z8 J& u9 ^( v2 ~  R
赞 收藏 1 评论0 发布时间:2020-11-12 11:24

举报

0个回答

所属标签

相似技术帖

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