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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
写在前面3 j. q: ~! k: X4 U9 S
芯片型号:stm32f030c8t6
2 A; v# w# F  E# b说明:便宜,用量大# v3 j( y* P+ b( I* @
要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断7 N% K) z' M2 u
这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断
1 C. f& i1 m# @& P8 z  D+ V本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
( Y/ V( ]  G/ |8 _3 R7 n4 b" ~, H3 T5 K: m
一、应用
3 P- Z9 W! G* H& R1 P外部定义串口接收回调
% T+ o6 ]# g7 [7 }* o当串口数据接收完成后,在该回调中处理串口数据即可
7 c, q9 M/ b# @6 G, o9 c# Q; t
  1. void Uart_recvCallBack(void *buf, int len)0 @  S" \4 U7 g
  2. {" J9 w6 A: a# @7 g! [

  3. # ]7 a0 J' @" n! j1 |3 s; P
  4. }
复制代码

! U8 r! W8 ]4 D$ p! D外部初始化串口
0 s8 Z! a8 w7 s7 f1 |
  1. myUart_initialize(115200,# G' ]( i4 c2 i, O7 n: H
  2.                                         USART_WordLength_8b,0 o4 ?3 u- |% C, h% y; r
  3.                                         USART_StopBits_1,
    & W+ B. X. q  A$ t
  4.                                         USART_Parity_No,6 D8 V1 A- F6 J$ m* {# J% ~
  5.                                         Uart_recvCallBack);
复制代码

6 E" V: j7 b6 N( J6 U0 n二、源码; b( _2 {3 j" F7 ]
myUart.h0 }5 i, ], o6 ?$ e9 x) S7 B  q
  1. #ifndef __myUart_H0 V, r2 l6 p7 t/ c# }( n
  2. #define        __myUart_H& M8 z, ?  [& h( R
  3. ; U+ H# d. a' ~
  4. #include "stm32f0xx.h"
    ' e" d% s6 L+ O- o$ D  ]
  5. #include "stm32f0xx_usart.h". w- B) w, n; U6 @! a% s
  6. #include "stm32f0xx_gpio.h"- U& Z0 |  u# O# R0 a& l4 o. H
  7. #include "stm32f0xx_rcc.h"
    $ x+ a' b6 c$ @: y
  8. #include "stm32f0xx_misc.h"6 `/ U! U% |+ @  N4 @3 T+ ?
  9. , i/ g5 Y. K/ Y
  10. #define USART_REC_LEN                          200          //定义最大接收字节数
    8 N% ]6 b6 i6 y8 h% O- F
  11.   O$ u8 S1 N7 \, }
  12. typedef void (*myUart_cb)(void *buf, int len);' m( \; W* O9 [

  13. " d' C% @# R  y. _: n
  14. void myUart_initialize(   uint32_t USART_BaudRate,
    / F  r; w0 v  X3 Y
  15.                                                         uint32_t USART_WordLength,, ]' J* F  z' ]) y- ^
  16.                                                         uint32_t USART_StopBits,# h8 k+ M. E( Q, o& `9 O) ]& y
  17.                                                         uint32_t USART_Parity,
    ; y! d* K' [% F$ e  s
  18.                                                         myUart_cb cb);
    9 }' I4 e  d- Q0 E. ]
  19. void myUart_setBaudRate(uint32_t USART_BaudRate);. i) j. L! G( k2 u* f$ d
  20. void myUart_sendByte(uint8_t byte);
    5 x7 x. [; s. z+ E% z' Z: a2 Y- z4 e3 R
  21. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);. }/ S2 B% o( m
  22. uint8_t myUart_recvByte(void);
    , W9 M( [% H' G+ _) Q# {
  23. int fputc(int ch, FILE *f);
    ! X* C: d: Y! C5 q, H, D9 L
  24. ( Q$ W6 I1 B( y5 q4 s0 ?
  25. #endif /* __UART_H */
    " L! m1 v- m' f3 U" }* w
复制代码
5 Z+ j- ^$ y" g5 I
myUart.c
8 }" m0 t1 [) x
  1. #include "myUart.h"% `: v; P- S" B$ h
  2. 5 A  F3 ?# M' D! s! \  v( M9 s- S
  3. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    ; A: Z' u8 Y0 t
  4. 0 _6 ?' _9 m. N+ H) t3 f
  5. uint8_t USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.  ~7 q$ o+ D; s- L
  6. uint16_t USART_RX_count = 0;       //接收状态标记                + K- g8 j/ u2 x0 n2 @
  7. myUart_cb myUart_callBack;
    9 J7 R  e8 d; B/ |% u3 E
  8. /* Private functions ---------------------------------------------------------*/& h# y8 p0 N4 y  n8 E" B1 F

  9. % y7 Z2 ]! w9 l( S
  10. USART_InitTypeDef USART_InitStructure;
    - L/ L9 Y5 A& D4 L* d

  11. 0 N: \# c. B9 Q! u; _" w5 N
  12. void myUart_initialize(   uint32_t USART_BaudRate,) H0 D( J9 b+ r. m  [! C
  13.                                                         uint32_t USART_WordLength,
    5 u1 |! u5 p( ~
  14.                                                         uint32_t USART_StopBits,$ g2 ]) O& T5 y5 H2 m) ]
  15.                                                         uint32_t USART_Parity,8 h  b+ [. p  v
  16.                                                         myUart_cb cb)
    # n$ {" o6 S% |) n: s
  17. {  
    $ p! z: z- v9 K$ Q

  18. 2 z% y/ M- s8 C& f. C8 A5 d8 Z
  19.         GPIO_InitTypeDef  GPIO_InitStructure;. X# U& U5 l' k4 U/ w1 g2 @! b/ y6 ?
  20.         NVIC_InitTypeDef NVIC_InitStructure;9 m! d" ?) S. m! d
  21. ! Q) @; W! x7 r' f: m
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
    9 F8 u. x) h4 E5 q& F) n

  23. : \" y8 l0 i2 i0 d" O; I" L6 J
  24.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
    6 C6 ^  d3 ^+ o, p3 I6 b6 N& o/ v- U
  25.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        : [5 Y/ U7 x4 O: b, p2 o" J4 v6 d! \
  26.         /*
      [4 d8 p3 b# K" z( b# N
  27.         *  USART1_TX -> PA9 , USART1_RX ->        PA107 p# [  Q6 ^2 R  @& |
  28.         */                                
    # n) Z9 l9 Z4 ~6 W0 N. z2 |
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 ! t2 }( m1 d7 c; M( b( c, }6 |
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; / O0 i% v' c& e. E  m) f
  31.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      o  B' w' ?  x: I) T# j
  32.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    : ?- Z0 m+ ]0 E1 K# {
  33.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      w% q3 N' O/ \% @1 Q- p
  34.         GPIO_Init(GPIOA, &GPIO_InitStructure);        - d$ n! O3 j# I& s

  35. 0 s9 V" |2 Y1 g) a- h2 e7 ]2 x
  36.         //Usart1 NVIC 配置
    ! y+ \; M7 Z8 o- a. F( x" w- n5 A
  37.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;; A+ l. t! e+ k# c
  38.         NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级3
    4 t7 X" ^) ]+ J9 u! j( v3 l
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
    $ h" y6 f! s# r# g& c
  40.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
    7 F( I% o7 s1 k& }3 l
  41. 1 z7 n9 B* X6 y
  42.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率/ |, c% n% l$ d+ B& i( K5 J
  43.         USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位- d/ p+ [/ |1 A: J* _
  44.         USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位, j% B1 w/ @; w; h7 L
  45.         USART_InitStructure.USART_Parity = USART_Parity;//设置效验位
    + ]0 Q, E. M# N$ {
  46.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制5 ?- d+ _) R7 _7 [# e' Y$ D
  47.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式# n9 @1 b$ |! [, N4 W4 I2 N1 P
  48.         USART_Init(USART1, &USART_InitStructure); //配置入结构体2 L( L' o$ k  S1 M4 f5 K
  49. + N! ^& J- b8 U
  50.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
    ! _' p6 K3 P* e2 g
  51.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断
    4 x6 t! U  y. b7 f0 r" J
  52.         USART_Cmd(USART1, ENABLE);//使能串口1( q5 o+ I0 y5 C+ k  e* b0 k, \

  53. 4 M7 b/ [) K# g6 h6 i
  54.         myUart_callBack = cb;; ~0 ]9 P+ C" K' J0 t# I& V2 v
  55. }                        
    ( I% F! U& I! g) [- I
  56. void myUart_setBaudRate(uint32_t USART_BaudRate)
    # @  g' T5 u( l7 r5 I, Z8 ?
  57. {: J& _7 b( w, e) W% Z% L$ R
  58.         USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);1 e+ j' W: S& T3 |2 }# j3 Y- z
  59.         USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);1 Q; @8 D* }! S# y; k" }
  60.         USART_Cmd(USART1, DISABLE);' T/ a; V+ y0 R* F

  61. $ i4 V+ N% p- t2 O& z
  62.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率& t) V* `, C& w8 N: t9 |$ {2 S
  63.         USART_Init(USART1, &USART_InitStructure); //配置入结构体  @# G& y4 q! k; f7 d

  64. 0 j# o# {6 a* c' t$ W; l
  65.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断9 y4 ~; m: X6 d8 U# m, b, m8 [' a
  66.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断
    . f0 q( e, s; \
  67.         USART_Cmd(USART1, ENABLE);//使能串口12 U+ Z, G& {2 f
  68. }
    2 m+ H3 E: J6 w# J
  69. void myUart_sendByte(uint8_t byte) //发送1字节数据
    * j8 ]; D! x% N6 P! T' n2 s+ o
  70. {- h+ _8 N$ |) y& f8 h1 e1 C' H
  71. while(!((USART1->ISR)&(1<<7)));
    5 t0 c6 G& }: N* A  }, e
  72. USART1->TDR=byte;        + o, @* g6 y+ e/ y$ V# z5 O
  73. }                - v. D8 M6 ]* F5 N
  74. $ W  w! s4 K( y, D4 {. |# {3 g- Z: Z
  75. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)
    # p3 M4 N6 f* m1 R& u
  76. {
    2 c, u' T" j* f! P
  77.         while(Length != 0)
    % u3 d4 i* k; O' A- o
  78.         {( E! }2 p4 ?9 {- g
  79.                 while(!((USART1->ISR)&(1<<7)));//等待发送完
    / ~. j3 \9 k- r2 l3 I6 ~0 v8 h
  80.                 USART1->TDR= *Buffer;; @- |" M# [! l. L& @
  81.                 Buffer++;
    " u% U) d2 i5 S3 f$ B8 Y
  82.                 Length--;2 S+ s! v& j, r; s. \
  83.         }
    & {' M2 ~7 X9 i! h; D8 @& x5 v8 |
  84. }
    $ v7 z9 o! J$ e: Y1 X* j

  85. 2 e, Z+ H* q, L8 w0 Q& b
  86. uint8_t myUart_recvByte(void)5 y/ D& P& {  g) [& K- f$ O
  87. {        ; t8 g7 @- [9 o+ f) m/ Q
  88.         while(!(USART1->ISR & (1<<5)));//等待接收到数据
    ; r8 g  o7 _) F. U% s; {8 L* P
  89.         return(USART1->RDR);                         //读出数据; k( A0 J* E8 v" r9 v
  90. }
    ! }- C0 M2 O* Q& L- A' a  @% \
  91. - {& H6 h' c- e6 \" Y

  92. ! a; [( f8 C! P" @, b$ K3 m' s
  93. PUTCHAR_PROTOTYPE
    5 g9 b; F& `/ F8 l$ {
  94. {5 V5 V$ _/ x8 L6 ~, H
  95. /* 将Printf内容发往串口 */* Y6 }1 M+ |8 R" R; @# k0 E
  96.   USART_SendData(USART1,(uint8_t)  ch);
      S  W. Z; [0 {6 c, Y! ~: ?! [
  97.   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)1 N4 a( d$ m! b8 T4 Q/ V
  98.         {}
    3 w( b) Q- m) g* m- T2 C5 T
  99. ) \' N% I9 T6 m4 L2 x- X
  100.   return (ch);+ q& ~  s  X1 ?" O5 j; {
  101. }2 n4 }0 o  i4 E4 e2 @( G8 v$ `+ W( m, B

  102. 1 D0 _. n; l2 K2 g1 _! c5 W
  103. void USART1_IRQHandler(void)                        //串口1中断服务程序
    ' U; i' O9 f1 a7 N8 M
  104. {; ^: _: T" a0 g2 L) [
  105.         uint8_t Res;) Z4 O+ H9 ]& ?, l

  106. ( D; U3 U; F$ k1 S4 q6 }
  107.         if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    $ G3 p. @; W( ~& F" X+ X
  108.         {  F0 g/ ]0 ^4 }' t" Q6 q9 X
  109.                 USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除. E7 Y4 k, C( H1 m! b. `
  110.                 if (USART_RX_count)
    : f$ }' I% u# j" w9 q; ~# ]
  111.                 {
    4 a; ]& n7 ~* \( D! H
  112.                         if (myUart_callBack)
    ( U" l. a: s2 F  d: c$ \
  113.                         {
    5 F( K( |/ n# z$ d
  114.                                 myUart_callBack(USART_RX_BUF, USART_RX_count);
    ! H! `  A2 @4 a9 e
  115.                         }
    2 X$ u/ U: N% K
  116.                 }
    0 C$ z+ ^9 x- \" T5 |
  117.                 USART_RX_count = 0;9 \( B' G3 f* r
  118.         }
    , Y( l& s% x, A
  119.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    , o1 e0 m) m5 k0 [2 Y3 S
  120.         {8 I9 L  |) P6 G. s8 g
  121.                 USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1);        //读取接收到的数据,自动清除USART_IT_RXNE中断标志' ?4 H2 a) s+ [7 x" b8 l; ]
  122.                 USART_RX_count ++;9 Q1 m  U$ h' Y! U5 X2 p- S
  123.         } ( T# D, j# B, A
  124. } ) G. A: W& `4 [" F) c6 B0 n

  125. 1 a$ q* S' B( X
复制代码

. ?' a& |+ g3 H1 \. C8 E
收藏 评论0 发布时间:2021-11-22 22:03

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版