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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
写在前面
% d; M8 c4 o7 w! F$ S- ?9 b& o芯片型号:stm32f030c8t6+ _6 \( F* x* x! L" s0 I" J0 w
说明:便宜,用量大2 p- P) D7 r8 L) ]1 }# ~$ t% R1 I. G) R
要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断" E8 c. ^' D! Z/ H- H
这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断4 `$ y+ y: x: W* a9 b
本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
: U, @" \1 p' P: p8 N9 w" j) J+ ^( z/ p% N
一、应用
' O( y  }7 K* c+ @外部定义串口接收回调& L! I* @2 j) E$ H7 @' }
当串口数据接收完成后,在该回调中处理串口数据即可: H; B+ l, T% |) a' }5 O9 e7 K
  1. void Uart_recvCallBack(void *buf, int len)
    8 g( ^: T- K% g! o! f4 G
  2. {3 ?* t3 s: j0 l8 \

  3. $ c2 M- d: b* P$ b+ y2 ]
  4. }
复制代码
5 ]3 d& a2 ~$ I  Q# O' ?3 ^
外部初始化串口* I% N2 C) d, }! u+ O5 u( r! T
  1. myUart_initialize(115200,% h8 p+ f8 Z5 E4 e
  2.                                         USART_WordLength_8b,. y& i# y* h: v3 ^% I
  3.                                         USART_StopBits_1,6 b" {3 S# e$ n* W4 H/ [7 c
  4.                                         USART_Parity_No,
    0 a5 a7 J( C$ h+ M: V# N7 C
  5.                                         Uart_recvCallBack);
复制代码

% k: T/ F  v" F. n二、源码7 M% F( N, S" b4 g9 B
myUart.h
* `& Z/ q  D( K4 h1 \1 h
  1. #ifndef __myUart_H
    4 U4 E8 F/ }& i- @% q% J* s/ A
  2. #define        __myUart_H# a9 C8 m% r# `1 x& Y
  3. * ]) N- V. j6 L! t
  4. #include "stm32f0xx.h"; F2 l. k6 s. f% Z" \/ C' |
  5. #include "stm32f0xx_usart.h", a/ l$ R7 {, U: j9 R( Y
  6. #include "stm32f0xx_gpio.h"8 s. b% e' n3 b/ R
  7. #include "stm32f0xx_rcc.h"
    + ?6 M6 {- b5 q, d" h
  8. #include "stm32f0xx_misc.h"
    1 e: [0 t% f1 d0 k8 |

  9.   [+ Q. f% V# \2 s
  10. #define USART_REC_LEN                          200          //定义最大接收字节数
    ' |0 F3 t( n# U% e7 ]# |7 x

  11. 9 n! V% Z4 p, i
  12. typedef void (*myUart_cb)(void *buf, int len);$ ?6 D) F+ V! p) q$ o5 `9 c
  13. 9 V( [* s" m2 X/ r: r
  14. void myUart_initialize(   uint32_t USART_BaudRate,
    3 H6 W6 K1 s5 {) i5 I5 Q4 F
  15.                                                         uint32_t USART_WordLength,. k  Z: A$ K! W( Y( i1 \
  16.                                                         uint32_t USART_StopBits,
    1 q  {0 N0 d1 b7 F( [/ Y
  17.                                                         uint32_t USART_Parity,
    ! ^2 q$ ?  b5 `8 z. H0 L
  18.                                                         myUart_cb cb);
    2 u/ N- X. R9 c/ o* y
  19. void myUart_setBaudRate(uint32_t USART_BaudRate);/ q* T# t' e+ M& D6 [# \+ ~
  20. void myUart_sendByte(uint8_t byte);- \2 a" ?/ l% L+ C& G1 L7 j7 D
  21. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);# J) c5 K8 p* s; w5 _, X( {: ~2 ]7 ^
  22. uint8_t myUart_recvByte(void);4 _9 t1 h; B) B! v! l
  23. int fputc(int ch, FILE *f);+ J8 r3 i  p# g" A

  24. ! Y6 o" t3 H# o
  25. #endif /* __UART_H */% C8 l. Z! {9 r8 L
复制代码
. a9 u8 Z' Z. q
myUart.c7 C8 x1 T$ k/ B! Z
  1. #include "myUart.h"/ ]0 n, F# i2 b4 [8 N; b% `* F

  2. / V0 g+ Z$ f. x
  3. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)! `7 V/ x6 {; Z" j7 k' y9 k
  4. 9 r% @7 r' `- v4 k7 F
  5. uint8_t USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.1 g! l- ^0 `/ V4 p, v$ n5 q
  6. uint16_t USART_RX_count = 0;       //接收状态标记               
      R* X; {8 h' Y3 w! b7 {
  7. myUart_cb myUart_callBack;* q5 h# C2 l2 {) J5 u1 g
  8. /* Private functions ---------------------------------------------------------*/. s9 ]& N. S9 U5 K2 s% s4 f1 `* y( y

  9. 1 \% M2 j; y+ `/ w: a
  10. USART_InitTypeDef USART_InitStructure;; W9 L8 y, B1 v
  11. $ H0 q# ^6 O& x4 o! i: ~" Z5 ]2 D
  12. void myUart_initialize(   uint32_t USART_BaudRate,4 B1 E! [3 j- G, n6 e/ J& K
  13.                                                         uint32_t USART_WordLength,
      p' L/ T/ t& E2 ?) }2 \2 o
  14.                                                         uint32_t USART_StopBits,  Q* F0 P7 b. e* e, K7 F
  15.                                                         uint32_t USART_Parity,% ?' d2 [% {3 X2 j7 D; V9 Q7 l
  16.                                                         myUart_cb cb)) D' j# }7 T" B& h
  17. {  ) S' w. J2 `, d! l+ }. u. J

  18. 0 Q9 E5 ]) u0 g' W
  19.         GPIO_InitTypeDef  GPIO_InitStructure;
    , `; p7 s) q! z  o& J
  20.         NVIC_InitTypeDef NVIC_InitStructure;
    ) x) I% O* j) W0 I7 I

  21. ' U% i8 C8 Y+ Y1 e+ X
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
    * S. G9 V; D4 _, U

  23. / m: ?. o* X' a
  24.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);( f, V- r6 B% L" [1 y
  25.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        0 X, _: M. W+ x3 z# P5 I
  26.         /*% r# {- r0 p! z* g) t0 m
  27.         *  USART1_TX -> PA9 , USART1_RX ->        PA10
    6 _0 w. s# Z* `2 ^! Y8 Z
  28.         */                                6 ?# M9 h* P$ u# a
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 2 W7 |2 f' s" I, Y5 B/ t; p
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    . I( A- }- @# w  ]4 L6 J- ~
  31.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    # H; t7 x" f/ T- ^' A8 K
  32.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    9 k: b; n& v8 W* S- f" V: B
  33.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ! p* F) r( M- T6 ]0 j$ f0 P5 F
  34.         GPIO_Init(GPIOA, &GPIO_InitStructure);        2 k! q% a8 F8 U  u
  35. ! U8 F# _6 s# z
  36.         //Usart1 NVIC 配置
    8 W) f3 Y! s5 w" O" C: [
  37.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    ; s- n+ l4 J- Q! @. e  e' w/ o
  38.         NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级32 _: j" b5 R- J% T/ R7 H) N
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能' O- y. c  e8 _0 G+ _
  40.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器) I1 B5 G7 r& y  i5 w: L
  41. ! X( _& G$ G! Y/ @+ |
  42.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率) E8 ?; U4 A  ]3 C8 M9 |' m# n
  43.         USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位4 G2 ^2 q4 o( n! w8 w8 ^
  44.         USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位. a) A$ ]. r) D! Z
  45.         USART_InitStructure.USART_Parity = USART_Parity;//设置效验位2 M. Y* }+ l7 a9 T" O
  46.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制* Y" u! k& I4 C3 B
  47.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
    6 N9 v8 M8 w; o5 X+ S; g
  48.         USART_Init(USART1, &USART_InitStructure); //配置入结构体- W4 |. m. W5 D/ A3 ]! r
  49. ( a9 s8 Q" g+ X3 A" l( u
  50.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断7 @' H1 }6 M7 E& E7 i! i
  51.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断0 o7 ]( @" |+ z% m; \+ x
  52.         USART_Cmd(USART1, ENABLE);//使能串口1
    ! v5 d/ Y% ^3 e0 F% z* R
  53. 6 S' j; l" e0 A1 U
  54.         myUart_callBack = cb;/ n4 E9 l: V) B& \
  55. }                        * O, T- ]4 f) Q. T! Y, M0 i
  56. void myUart_setBaudRate(uint32_t USART_BaudRate)9 n# t; R. J; t5 V5 L' ?
  57. {) h$ d8 m3 V7 d2 v
  58.         USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);2 a' O2 f# I. c* ]5 D4 C2 g  l# Q
  59.         USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);. `% C- h) j0 `" l
  60.         USART_Cmd(USART1, DISABLE);
    1 Z, {( Y# X; ?
  61.   B4 l& Q1 n9 H$ \% K" O5 n; {% i; T
  62.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率% Z1 b+ Y& m) M! h2 h
  63.         USART_Init(USART1, &USART_InitStructure); //配置入结构体0 l) P  z& u6 N
  64. $ d/ }: N) H3 |- k
  65.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断' W, O3 Z) O0 i' l4 P  U9 U
  66.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断
    ( o; w. e: f1 p6 v2 o8 K$ ?
  67.         USART_Cmd(USART1, ENABLE);//使能串口11 ]* W1 M6 F" _4 K! S. V  f/ @
  68. }
    + E% ^0 H/ w9 J7 n6 d* [. q2 j
  69. void myUart_sendByte(uint8_t byte) //发送1字节数据
    & x# {* ?6 o- ^- ~
  70. {
    , z. P7 A8 @0 i) y3 o
  71. while(!((USART1->ISR)&(1<<7)));
    * b: [% h; G0 B! y( C9 {* P8 g
  72. USART1->TDR=byte;        6 B- {' Y) _9 P# r
  73. }               
    * c; O1 E- ~2 u  n. R' L# y
  74. - }- e  k2 u: s/ k. U
  75. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)
    0 j# N: y8 W' F* \! L9 N- E
  76. {) }4 G# b% j3 U- w% T! B. N
  77.         while(Length != 0)* s1 T+ @4 y" p% m' A4 C$ C
  78.         {! Y. N* Y* s& h
  79.                 while(!((USART1->ISR)&(1<<7)));//等待发送完
    6 Z. y1 I8 {% R* M, {- m8 e2 N0 `
  80.                 USART1->TDR= *Buffer;& T+ a; D# b$ b6 A$ ]0 O
  81.                 Buffer++;9 Q/ o4 H) I4 c: k$ W9 B
  82.                 Length--;
    9 @' ^5 O9 n) G( l4 c: Q
  83.         }# x) X( _- t/ I6 m
  84. }' t4 T/ J( Z; a- D8 _2 |+ v- t+ e
  85. " a/ W: o+ T, P# I1 B
  86. uint8_t myUart_recvByte(void)
    # \, @4 K+ i/ }: T" ^
  87. {        # F; D8 z7 `' l$ [- G8 D- \
  88.         while(!(USART1->ISR & (1<<5)));//等待接收到数据
    ) _2 {) b0 l+ s5 K( C& Y
  89.         return(USART1->RDR);                         //读出数据
      }$ W  u6 ^9 j
  90. }, {' H$ `; t( _. w: _6 q. @! @

  91. . t$ E+ A1 Q" r7 e
  92. 8 P2 e  }' x, x& V- n+ R4 o
  93. PUTCHAR_PROTOTYPE 5 Y. l4 R! S2 D2 {5 E* p
  94. {
    ( J1 A  h& z. s3 i
  95. /* 将Printf内容发往串口 */' ^9 b6 a+ n; X4 R. E7 m
  96.   USART_SendData(USART1,(uint8_t)  ch);
    : @( u4 F" n) T
  97.   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)6 N) E4 `( n1 B4 T8 f* h0 l
  98.         {}
    : a: e6 _8 i9 h

  99. 7 n" I# z; c: A6 M  d2 D
  100.   return (ch);' k! z7 z) w  P* S9 k
  101. }
      \. ?( k. r/ v3 H9 b' Z! z

  102. & R' x& I! |1 C: ]
  103. void USART1_IRQHandler(void)                        //串口1中断服务程序
    9 q0 H9 w$ ^) ~! A( V4 O5 v
  104. {
    2 s- l- G3 J2 }0 J# Z
  105.         uint8_t Res;5 y" b% M! |/ b* J% }2 s
  106. 2 y! d6 n7 B  G9 K6 B6 r
  107.         if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET), }+ u% k; I! a" S, N, W& f
  108.         {; U2 ~0 ~, Q8 P* i
  109.                 USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除- o. K! C1 c, Y, o0 i' t( P0 i
  110.                 if (USART_RX_count)  c8 }4 y% `. P$ e: ]  q( N
  111.                 {
    % ~0 S! c- j4 ^6 `
  112.                         if (myUart_callBack)
      q: K0 G1 ?) R( a: E4 d0 D
  113.                         {
      z% y0 r% h! n4 a2 f
  114.                                 myUart_callBack(USART_RX_BUF, USART_RX_count);# i0 `5 P7 j1 d! [
  115.                         }
    ' f) q' Z& [5 t+ y- r! I- \6 N
  116.                 }
    9 a- Q: M0 s7 r. ]1 a# X* h
  117.                 USART_RX_count = 0;
    . Y- l4 }8 Q' K2 v0 F+ I& [, w
  118.         }
    5 D* B3 L" E* [$ ~6 e3 e1 Q
  119.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    , u0 P6 F9 J5 w6 n. t7 m
  120.         {7 o8 J. g# A, ]1 C8 b; a
  121.                 USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1);        //读取接收到的数据,自动清除USART_IT_RXNE中断标志0 B- V; F& @$ v3 Z3 |0 g
  122.                 USART_RX_count ++;/ C+ ?  |% M6 W4 W0 Z; `- D+ Y
  123.         }
    - n! ?# P" t+ Z  h/ T
  124. }
    . O3 m& P* o5 d8 j
  125. # _+ ~8 j% j7 E2 L9 x4 x0 H
复制代码

8 i+ }5 `' _% j
收藏 评论0 发布时间:2021-11-22 22:03

举报

0个回答

所属标签

相似分享

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