请选择 进入手机版 | 继续访问电脑版

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

STM32学习笔记——USART串口使用

[复制链接]
STMCU小助手 发布时间:2022-8-16 21:48
USART串口概况8 D+ n  m% s2 Y# F: H
在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互联网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。还可以使用DMA方式,实现高速数据通信。
3 u4 w  g$ S9 C  w' `7 Q0 n常用的帧结构为:1位起始位+8位数据位+1位奇偶校验位(可选)+1位停止位。如下图:9 l$ U) O% S( E! \/ c! R

& v$ H. W; N; v INL$RHU~MD4U_9)][DCJ}LO.png 9 K6 ~/ B+ R, y
. X  e5 K4 H, p1 _5 s+ R& f
USART特点: [$ f& ^- N( ^
全双工异步通信;
$ h( v4 P/ o( k/ f1 S/ g分数波特率发生器系统,提供精确的波特率。发送和接受共用的可编程波特率,最高可达4.5Mbits/s" s. Q' r$ Z+ f' L+ m( C6 X+ k, A
可编程的数据字长度(8位或者9位); 可配置的停止位(支持1或者2位停止位). u  |7 w) k# B% V5 L' O8 ]* C! N% v
可配置的使用DMA多缓冲器通信;1 g% s8 I! r; ?" N: H0 K. t3 m1 P% r
单独的发送器和接收器使能位2 _6 ~3 X; L8 j9 B/ q& Q/ z) k3 p4 h
检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志; 多个带标志的中断源,触发中断;其他:校验控制,四个错误检测标志。

- V" o' p1 a# cUSART配置的一般步骤
( q* l4 v( {/ k- l串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
4 S; j. j, F9 h串口复位:USART_DeInit(); 这一步不是必须的
. R- [  r+ ~/ c" p, ~  M) ~GPIO端口模式设置:GPIO_Init();
. k+ _5 s3 \) V$ [* ~/ W0 `) n串口参数初始化:USART_Init();8 L7 O  y8 O2 h: [5 F' N
开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤:NVIC_Init();USART_ITConfig();3 ^7 ?3 P6 Y6 Z. d0 Q* P- S
使能串口:USART_Cmd();
5 U  I0 e# c( E" m编写中断处理函数:USARTx_IRQHandler();
6 B  m* d& ~! u& Z4 j8 S8 h串口数据收发:void USART_SendData();//发送数据到串口,
) ?4 V$ d" |& E( t' _1 duint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据串口传输状态获取:
, o# f  A# w: C* u1 v# e
  1. USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);" l/ \* g' _0 L9 ]( u
  2. void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
复制代码
) C, ^, |* w- l0 B8 b9 w
USART的理解
3 A5 d  L- C! e1 C( P2 K/ H主要使用 USART_SendData() 该函数发送消息到串口,然后使用USART_ReceiveData()来接收发送的消息;而同时调用该函数的时候,会自动跳转到USARTx_IRQHandler() 中,而在相应的串口中断函数中,对传入的消息的字节数进行判断选择,以及挨个输出。
2 g6 @) x% G" Q4 F( T/ ~' ?+ C

5 ^7 w  L+ _4 [! ^
  1. void USART1_IRQHandler(void)                        //串口1中断服务程序* X8 R3 K: o5 S  ^. b7 i4 e. W, l
  2.         {% R$ \; K( t# J3 {! }1 g1 B
  3.         u8 Res;1 S+ @% s, K5 H; q5 p3 V# T
  4.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    ; c5 ^2 p& G8 L, y/ w* q
  5.                 {
    , d' W! |0 g( ?9 w4 O
  6.                 Res =USART_ReceiveData(USART1);        //读取接收到的数据
    : d, {; T, ?) S7 s- q# T
  7.                 % k  A; e) a/ w0 t3 D% ~' e" h
  8.                 if((USART_RX_STA&0x8000)==0)//接收未完成
    ' n& C; _/ j/ I0 T! _0 @) i$ }
  9.                         {
    6 J( R9 m3 X5 R5 E+ ^, _
  10.                         if(USART_RX_STA&0x4000)//接收到了0x0d. L5 ~* }+ k$ t" E% G' u3 ^+ q
  11.                                 {
    * H1 `: ?/ d- M8 q" j# K2 K7 I
  12.                                 if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    : l' x  P( g! {: u7 C
  13.                                 else USART_RX_STA|=0x8000;        //接收完成了
    1 X* q7 _# a$ M
  14.                                 }
    ' a5 I, u4 q4 P1 K
  15.                         else //还没收到0X0D
    ( c9 g7 b; r- T2 D  f" m3 A
  16.                                 {        
      Z; A( ?* l+ ?+ u
  17.                                 if(Res==0x0d)USART_RX_STA|=0x4000;
    - L( E1 q6 O' @3 z9 V; l
  18.                                 else
    7 Q; T) V0 v3 H  d
  19.                                         {
    % m( }: G+ V( b# U
  20.                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
    " f8 W% k% i( j- d  C3 s# j
  21.                                         USART_RX_STA++;! [( F% a4 f4 N+ G9 m6 V& m8 w  b
  22.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收          . Y6 Z5 |7 Z4 J( O! X4 y; I
  23.                                         }                 - a7 _. H( C8 y
  24.                                 }
    ' `3 x8 R& r2 a/ w( [
  25.                         }                    
    3 G! s  W& m4 U& f, a# Z( ?
  26.      }
    7 k6 N( q2 u! {, a9 W  H
复制代码

' j# Y/ @: Y, y) K( a" H" ^这里拿正点原子的代码来进行分析7 M' _$ v  L1 L" w. I8 m
在void USART1_IRQHandler(void) 的串口1中断函数中,先是定义了Res这个变量来储存USART_ReceiveData() 接受到的消息。7 \. ^1 i' m  Z- m
8 S: `6 n& k, s
最重要的过程,就是在这段函数中,还使用了USART_RX_STA(在先前就定义好了的变量,主要用于储存串口接收到的数据形式,16位的数据格式,[0:13]用于储存数据长度,[14]用于标记是否接收到0x4000,[15]用于标记是否接收到0x8000), ^% F% \8 }' x6 P, D& Q; p
$ J6 T9 D( b, o5 I" f% e. ?, O
同时,串口接收中断服务函数要考虑到了所接收到的数据长度远大于**[0:13]位所能存放的位置,此时直接将USART_RX_STA**的第15位直接标记为1,即表示此次接收完成。
  1.                                 USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
    1 |' F- ^5 H- q! l
  2.                                 USART_RX_STA++;      
复制代码
. q. r1 e7 R  E# S0 O0 Z6 h. U
正常情况下,通过USART_RX_STA该变量不断++来改变USART_RX_BUF(先前定义用于接收数据的数组);而USART_RX_STA&0X3FFF此段代码的作用是为了判断大小究竟为多少的数组能够完全接收全部的消息,而且该代码是会因为后面这行代码 USART_RX_STA不断叠加,直至超出最大值。$ _/ A3 n6 k% |9 s- i$ l/ X
至此,中断函数的分析大概分析得差不多了,至于前面的配置串口GPIO和使能的操作就不累述了。/ M' M& M1 K9 Y( T
以及后面的使用Usart串口配合其他的外设的相关操作和调试。
" C& K% q0 K: N/ f1 S: l* a: T$ w  b" k
! d$ q" d. F# H( j

. m2 |; q9 i& W! Q& U2 |5 K" e5 }  j. O
收藏 评论0 发布时间:2022-8-16 21:48

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版