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

【经验分享】STM32F0系列开发之串口的使用

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
写在前面  S/ o& L! c  E+ f( k
芯片型号:stm32f030c8t6
7 t# M/ h5 A% q1 Z说明:便宜,用量大1 |0 l" b  d, t8 R8 P2 w9 W
要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断1 y9 ^& \* r9 C8 ?
这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断& n4 A0 n7 e+ m3 V1 ]( b
本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
$ S; y; x7 a! |) f8 }' l% V- o* g) `+ g' [- j: q; e
一、应用6 h1 @, J% q7 V" X6 C9 e; p
外部定义串口接收回调2 h7 `4 Z2 H! T! g5 i4 u5 x
当串口数据接收完成后,在该回调中处理串口数据即可
$ S/ G8 W8 o9 S& t- k
  1. void Uart_recvCallBack(void *buf, int len)- A7 t7 c' S+ G3 G6 {. w5 `, m( m
  2. {' \& `# M' u7 g0 X4 m

  3. + E9 X2 r" A6 ?- Q
  4. }
复制代码
; n, @6 y% F2 q8 g
外部初始化串口
, c4 y- I" c; D6 _$ [  u" G. q' }, G
  1. myUart_initialize(115200,
    8 P. H3 Z3 o" b7 Z! J. @  V
  2.                                         USART_WordLength_8b,& }8 m) \0 n& X$ D
  3.                                         USART_StopBits_1,
    % x  d4 s3 m" E# M  d
  4.                                         USART_Parity_No,0 N' @% R. y8 l; e; H& G
  5.                                         Uart_recvCallBack);
复制代码

8 M  R* w9 z+ M! o# ^二、源码
" T# j* E% M& N" [; G# s8 WmyUart.h
6 F5 m& u9 C& K9 l+ b1 b
  1. #ifndef __myUart_H+ j: H2 E" s5 S. u
  2. #define        __myUart_H
    - T: x2 r5 v# R- V( A3 @

  3. * n  i2 A: {  m
  4. #include "stm32f0xx.h"8 M$ A1 x4 ^6 C) F& \0 N! f+ z
  5. #include "stm32f0xx_usart.h"5 X- r! ?/ p  S2 A
  6. #include "stm32f0xx_gpio.h"
    6 @* B: r* g/ `& r" P! }- P
  7. #include "stm32f0xx_rcc.h"
    ! H- L7 u- X7 f9 n6 n
  8. #include "stm32f0xx_misc.h"
    * m* |- Q3 q0 Z
  9. 2 ^/ F8 ?& Q8 K7 m5 S6 Z
  10. #define USART_REC_LEN                          200          //定义最大接收字节数
    ; {- w. z6 t7 P6 C1 c& U
  11. 1 }* N- K# j0 n# m3 M; s. L& \$ u
  12. typedef void (*myUart_cb)(void *buf, int len);
    2 G0 T$ ~( o/ T9 B

  13. 0 @4 ]5 m/ S  S, }
  14. void myUart_initialize(   uint32_t USART_BaudRate,$ S/ T( \! a5 w6 a) L
  15.                                                         uint32_t USART_WordLength,) M$ _, x: h9 \
  16.                                                         uint32_t USART_StopBits,
    ; f3 N* f* Z$ i8 C* c
  17.                                                         uint32_t USART_Parity,
    2 v5 M1 y: @) {) D$ b/ W; C
  18.                                                         myUart_cb cb);. M+ G" u. L3 E4 q% l1 ?5 D4 _; e" D! A
  19. void myUart_setBaudRate(uint32_t USART_BaudRate);: w& \4 }4 Y; y3 g/ e
  20. void myUart_sendByte(uint8_t byte);2 {8 Q+ e/ r  g9 T/ Z$ v& Z
  21. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);
    $ u: K. k6 v& E
  22. uint8_t myUart_recvByte(void);
    # k) i4 ?. _) y) t7 N
  23. int fputc(int ch, FILE *f);& A' {- L& x7 `
  24. ) @, S7 t2 J1 j4 U: d: c, \7 |
  25. #endif /* __UART_H */
    * q6 h+ C+ j& Q+ K* q4 T8 d. {; D
复制代码

1 c9 C$ }4 }, a1 |  vmyUart.c
/ w, P  M( A8 N+ \; O
  1. #include "myUart.h"6 {$ C1 ?4 R2 C
  2. 2 `, H0 D3 ]. @* y7 \
  3. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)' s4 I: {+ D- P+ a& V# t$ l

  4. ) J! q1 x7 b! O1 z
  5. uint8_t USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
    $ U) l: X3 X4 ^5 k, r2 B
  6. uint16_t USART_RX_count = 0;       //接收状态标记               
    " x" F. O5 X2 y# k- `: g6 a4 Y
  7. myUart_cb myUart_callBack;
    - {( o& L; Q* y6 m' ^
  8. /* Private functions ---------------------------------------------------------*/
    : }: Y9 z/ [6 x, a- l3 E- t9 U7 y

  9. 1 A# I9 g' V8 J* y( z
  10. USART_InitTypeDef USART_InitStructure;& j5 F& T$ N+ \- E; J
  11. # @% r' q! x* y' {5 M! w: i; N8 N
  12. void myUart_initialize(   uint32_t USART_BaudRate,
    0 Y8 H) d8 ~0 y6 ^
  13.                                                         uint32_t USART_WordLength,
    * E# o- Z2 G  t6 o+ I* e* u
  14.                                                         uint32_t USART_StopBits,
    * a- P# x  p% N
  15.                                                         uint32_t USART_Parity,
    2 d( `9 U, d8 b8 e0 S$ I: d
  16.                                                         myUart_cb cb)2 k$ R& X0 J) v# Q, A' I/ [
  17. {  
    3 T7 q* ~; Q2 x) n7 T7 a5 T
  18. - ?$ ^: H6 c8 W0 H$ `5 y
  19.         GPIO_InitTypeDef  GPIO_InitStructure;# x* O2 b! a& n) H$ t: x0 r- Z
  20.         NVIC_InitTypeDef NVIC_InitStructure;4 J$ R7 Z0 @. _' Z+ t/ y

  21. - B4 p; c; {2 w$ _4 A/ e
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
    , j& q6 v+ m. A5 `4 }: V6 g, w

  23. 0 Z, W: H6 l- e
  24.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
    " F& O6 |: b, b& e) o& r
  25.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        
    1 o8 \5 V9 i. `* Q& j1 n  Z9 Q2 y
  26.         /*
    6 |# |& t, y$ }* z* k* G
  27.         *  USART1_TX -> PA9 , USART1_RX ->        PA106 o4 H* _8 z. A# S7 A& |/ ~6 J: P
  28.         */                                * c9 a5 ^; D4 p
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 6 T* `+ _4 c) Y: p/ D1 a
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    + l0 R# z; p* |& o7 J' `# h
  31.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    5 a0 E4 v, F) z# |% ~% `7 U( @- Q' Q
  32.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;( F  U8 S( p8 y; A
  33.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    2 f1 I9 L9 R7 q! Y5 V- X
  34.         GPIO_Init(GPIOA, &GPIO_InitStructure);        / Q8 M# E9 ~+ y

  35. # q& I6 ?4 E8 O
  36.         //Usart1 NVIC 配置
    % D! x0 ?8 M: e' g" v5 [( ?
  37.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;. c  z: ^- e+ q, H7 z
  38.         NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级3
    / w) v4 G. V- F0 D0 _
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能7 c/ {/ T' M* U: v5 q
  40.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
    4 r, R+ g5 w4 m7 _' F

  41. , K& ?3 [5 U. g; m4 H% }2 b9 Y
  42.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率* b, t! ~, |  h+ J- t
  43.         USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位& Q3 R5 y- ?, o
  44.         USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位
    ; I" i. @0 `+ y' z: ]1 r
  45.         USART_InitStructure.USART_Parity = USART_Parity;//设置效验位
    ) Z/ c, X, S7 T4 \7 Z% [
  46.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制
    , w. b( z/ P9 s7 R
  47.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
    + x" J9 U+ e9 _
  48.         USART_Init(USART1, &USART_InitStructure); //配置入结构体* K5 ]/ L" t4 ?% n) V6 G

  49. % [$ n  Q& U1 A; |  |  b' N+ f
  50.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断. c) R7 M9 @( o* E: \
  51.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断
    3 m. |. y" g9 }, g$ p- s( N2 u
  52.         USART_Cmd(USART1, ENABLE);//使能串口1' B% ^$ U. H- g8 }( O2 u

  53. * _. K% ~, a6 ~
  54.         myUart_callBack = cb;1 Q, x8 E# X  X! u, O3 u
  55. }                        
    3 a' B: a/ H9 C1 w: N
  56. void myUart_setBaudRate(uint32_t USART_BaudRate)6 I6 c4 |% u8 Q/ D; e& s- Z4 I# D
  57. {
    ' G, r  X4 \1 m
  58.         USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);& \& r/ y1 Y; w+ k; l/ y6 c9 O
  59.         USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
    - g* ?9 j/ L9 S/ E" |5 y7 V3 T
  60.         USART_Cmd(USART1, DISABLE);
    $ M4 U! d* n# K2 T: P: n7 \5 a

  61. 7 A. _8 d$ u+ f
  62.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率. R4 {4 x2 F& X3 x
  63.         USART_Init(USART1, &USART_InitStructure); //配置入结构体
    ! L7 u6 [9 D, T! Z
  64. + q) [5 @5 x2 l( ^4 L# c) }) e
  65.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
    8 g+ {7 O) e% o$ V
  66.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断
    , H& i7 Q, _- E/ z+ ~/ a
  67.         USART_Cmd(USART1, ENABLE);//使能串口1
    $ d+ U) s! O2 J! ^$ g! j# C' B
  68. }' s% _8 l" ?. G, Z; ]  g5 s' L& W
  69. void myUart_sendByte(uint8_t byte) //发送1字节数据" {3 ~$ [  `7 b1 g! q& r
  70. {
    ( `1 S! _- s/ }% K& d
  71. while(!((USART1->ISR)&(1<<7)));( M; a2 f9 {* k# H, o9 C" G* R
  72. USART1->TDR=byte;        
    % E2 i- {# I  L' p
  73. }                1 T* g5 ]7 C! b: h8 l2 b7 S# y1 z8 ]

  74. # u( c1 Q/ l2 \1 H4 _: i( u
  75. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)8 Z$ a- I9 F- z; d/ c
  76. {5 T/ K$ ?! P* t9 N' F& M( g
  77.         while(Length != 0)
    ' @, I& I/ x" Y6 }
  78.         {
    # E4 v+ w1 @! f5 A, d: [% C- Q
  79.                 while(!((USART1->ISR)&(1<<7)));//等待发送完
    ! h& ~# J3 C. i
  80.                 USART1->TDR= *Buffer;
    * H! d6 r! {/ ]- G* F4 F3 h
  81.                 Buffer++;
    # a9 ]% V* h( _9 J
  82.                 Length--;
    " l9 a- b- r8 |5 v3 J2 @
  83.         }1 `" O* t6 P% y3 w* ]3 E* h! ~' ~
  84. }# u, R9 x5 V- E7 w7 ]6 @. K/ r
  85. , z2 U! r, |4 P6 c4 C" a
  86. uint8_t myUart_recvByte(void)
    % [4 r( P) H) B2 ^& N1 \
  87. {        ( K' f- m6 K" |$ R! u) S
  88.         while(!(USART1->ISR & (1<<5)));//等待接收到数据  A) w  Z, ~$ _7 R9 l/ {; {+ A) W
  89.         return(USART1->RDR);                         //读出数据
    , {5 d9 G/ l1 C8 C- v9 C" X# K+ q' D
  90. }4 A- j/ c* |! f4 k! f8 A' l& w- K  e
  91. 5 Y! R% R- L0 S2 `% c7 U/ }
  92. , `4 d- {5 _/ b* P$ V
  93. PUTCHAR_PROTOTYPE ! K- V. ~5 k& J$ ?" y1 s
  94. {
    8 J) v- j# ?* i1 B2 O4 ]
  95. /* 将Printf内容发往串口 */
    5 C6 R: ^! v- W  R5 `
  96.   USART_SendData(USART1,(uint8_t)  ch);8 ?6 K  B2 W# m- Q4 ~( u+ h5 K, h
  97.   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    # I; L3 r% f0 x1 e4 ]$ g* q
  98.         {}
    6 c  ?$ a( Y$ u: j
  99. ' X& a' A# T: r6 w
  100.   return (ch);* ~9 P( @% ?% A; N* U8 Q
  101. }1 P2 i. i1 r6 t3 _# J
  102. " F4 L& Y8 v( t; t7 J1 Y. @
  103. void USART1_IRQHandler(void)                        //串口1中断服务程序7 i9 u" t& n2 ^5 t! ?, D' l
  104. {1 h( X5 z& Q8 T# E" I( x* W
  105.         uint8_t Res;
    " z+ z9 R* E  z( L6 c- l& P. U
  106. 6 X7 p" `  w4 k( _9 i4 Z
  107.         if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    & o3 J3 O$ |: D6 f8 m+ H( G$ Z
  108.         {
      S6 m$ u: R1 P8 \
  109.                 USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除, o4 [9 T4 v) z2 i& B3 M
  110.                 if (USART_RX_count)0 W: ^4 V. @# U9 L' W
  111.                 {
    8 P& r  J! y: O  W: _% e
  112.                         if (myUart_callBack). V3 E" P+ ^  U
  113.                         {
    5 W7 \) j" c! X$ `( ?
  114.                                 myUart_callBack(USART_RX_BUF, USART_RX_count);
    + {2 H2 d; |0 P" z
  115.                         }
    ) p7 V. O& v/ _. @
  116.                 }' J7 e7 d/ O6 T/ `: A  q1 w9 d
  117.                 USART_RX_count = 0;/ S9 c# A0 u, E
  118.         }
    # H, W* W- L) e# W5 k  k, ]
  119.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    ( K0 g% Q  D' ]6 r0 B
  120.         {& c7 o. K+ H; _2 g5 M
  121.                 USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1);        //读取接收到的数据,自动清除USART_IT_RXNE中断标志, |( V- {$ l! v3 x* v
  122.                 USART_RX_count ++;
    " P+ I5 d) ], q
  123.         }
    / p6 W. \% f1 Q$ s( o/ d* |, y
  124. }
    ' ~$ E! X! B- @7 b; B, y
  125. 8 S0 @/ ?& F. ]
复制代码

/ ^" ?5 ?: Q$ ~7 Q2 I6 K
赞 收藏 评论0 发布时间:2021-11-22 22:03

举报

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