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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
写在前面& l  q! ^; g0 C" o& k
芯片型号:stm32f030c8t6" W; p- f- C# u5 ^: ~0 M
说明:便宜,用量大
1 K# ]# B! c0 q" J; r要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断& J1 |* K- E3 D6 |+ B
这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断1 y# G$ r4 K4 B, E/ W4 F
本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
6 s4 x8 u8 _# r, j7 [' g
4 _& G7 h  s7 P5 j8 W- P& U一、应用9 h- V$ j) V8 C
外部定义串口接收回调* f4 a& V9 C2 t. k$ J" D9 @3 L
当串口数据接收完成后,在该回调中处理串口数据即可" u2 W- z, }# ^: Z! c
  1. void Uart_recvCallBack(void *buf, int len)& X* L5 z0 H: {% c* l5 @4 i3 p
  2. {
    8 n8 U/ r. P# j3 Z7 [" c+ L

  3. 4 l$ k6 \- n9 b1 S) w
  4. }
复制代码

* B" b. O5 Y' ~4 X+ ~外部初始化串口8 i9 w$ \& D3 Z  `3 }
  1. myUart_initialize(115200,
    1 ~2 ~. e% Z, S0 E$ n. ~. U
  2.                                         USART_WordLength_8b,  l  Q* W( J1 z+ V! i& m
  3.                                         USART_StopBits_1,; C% J# n* L2 B2 t! r8 B  Z2 y
  4.                                         USART_Parity_No,& ~0 H; a6 x7 p
  5.                                         Uart_recvCallBack);
复制代码

/ J  P( R* P( _% L5 E二、源码
9 j' m, P- o7 A8 S; i  e6 Z, {myUart.h
7 A+ ^* U. q) q9 {4 x
  1. #ifndef __myUart_H9 v1 w% O( _5 d) J$ S
  2. #define        __myUart_H
    0 ~! u0 q- H* ~+ p

  3. - v) k6 V! z* l
  4. #include "stm32f0xx.h"
    # O' O% v( m) {
  5. #include "stm32f0xx_usart.h"
      v5 ?* r! \2 {, G+ j' [
  6. #include "stm32f0xx_gpio.h"
    + Q8 g8 S! |& l
  7. #include "stm32f0xx_rcc.h"
    2 C2 y1 q1 N% N9 a( Y5 b9 \7 X
  8. #include "stm32f0xx_misc.h"0 A$ ]0 e) v8 k4 Q8 ?  J/ p0 E) u
  9. 6 g! h! |' J9 o: z: `4 B
  10. #define USART_REC_LEN                          200          //定义最大接收字节数4 Y* G" v( a# s4 J7 p3 x

  11. & K; K" H. ?, O
  12. typedef void (*myUart_cb)(void *buf, int len);3 U) x2 M7 V2 j8 O$ I1 a

  13. 3 h9 v2 g1 _( M  B5 r# u$ r
  14. void myUart_initialize(   uint32_t USART_BaudRate,$ m( ~' Q  d* y# N# A; C" l# w
  15.                                                         uint32_t USART_WordLength,
      H( Q* i- q+ a# N/ O$ C
  16.                                                         uint32_t USART_StopBits,
    0 @& [+ E' _9 J! n2 F- Y
  17.                                                         uint32_t USART_Parity,
    4 S- y' [# m5 k& C
  18.                                                         myUart_cb cb);
    7 b. c7 Y: A( d  u. \
  19. void myUart_setBaudRate(uint32_t USART_BaudRate);
    * H2 M1 H' G' e0 N8 v
  20. void myUart_sendByte(uint8_t byte);: j8 v: m" B- ?5 `$ ?
  21. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);, B$ g! E0 U' f# T& J# H
  22. uint8_t myUart_recvByte(void);& E: u3 c6 P6 Z# }9 ~- c3 g
  23. int fputc(int ch, FILE *f);2 s- F% i) a: k% v" D

  24. - R8 U8 y) h4 `  O- W# o" T" \% t
  25. #endif /* __UART_H */
    2 |2 t8 @; W. f3 y' o8 K( M
复制代码

7 A/ W2 O7 f0 F7 K; x, nmyUart.c0 |. N% b5 |  F* I
  1. #include "myUart.h"
    1 W, d! j* T; r  S# X/ U% g6 J  b

  2. : K0 g; e+ u7 Y; x
  3. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)( q1 ^9 B* ~7 f# X0 m
  4. # e; T* A! k' W
  5. uint8_t USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.' R8 U- W5 q# {2 c4 V
  6. uint16_t USART_RX_count = 0;       //接收状态标记               
    / @4 W( d& y* f! V7 y0 I( \9 _! d
  7. myUart_cb myUart_callBack;# H% R. z( F6 Y/ o. n
  8. /* Private functions ---------------------------------------------------------*/5 t, u& g* ^9 l+ V; W7 d
  9. ( M' x, g# J$ F
  10. USART_InitTypeDef USART_InitStructure;
    5 H! @0 L( k, l2 b: }9 P0 ^
  11. - h5 o# O5 W" ~+ g& Z
  12. void myUart_initialize(   uint32_t USART_BaudRate,6 x% x7 |7 u  B5 r
  13.                                                         uint32_t USART_WordLength,6 D' b2 K4 C2 N* p) w) B5 K6 m
  14.                                                         uint32_t USART_StopBits,
    * z  \' Q: x3 {' z7 x! \
  15.                                                         uint32_t USART_Parity,4 N$ c5 v7 c' C9 M% J- `
  16.                                                         myUart_cb cb)1 ~% P! C* E  W7 @
  17. {  
    $ _% Y6 T5 }+ G7 N; X
  18. , `% m2 e$ ~% C
  19.         GPIO_InitTypeDef  GPIO_InitStructure;
    4 M+ M/ l8 v7 O
  20.         NVIC_InitTypeDef NVIC_InitStructure;
    ; j( t# O6 y( n/ U1 T1 j
  21. ' @4 j0 J7 r5 B2 E( a
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );0 N$ M- D( f* C3 r/ V
  23. % |( P: T3 r% v9 J1 z# V  r
  24.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
    * ~# z4 D0 @% r! ]7 h, r# X1 T% R
  25.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        - L/ x# n3 X# Q6 X
  26.         /*5 _1 `& Q3 |3 v4 P) k
  27.         *  USART1_TX -> PA9 , USART1_RX ->        PA102 C- Z/ }! i3 p
  28.         */                                0 [# k% f0 R6 I$ Z" @
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 & I" I! @8 H5 E7 g* v
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    + s7 W6 J/ I; G* E: S
  31.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;6 u" d1 s' \* F, v2 ?
  32.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;( H5 Q! N! s2 ^6 t( ^. o. o
  33.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ( r8 }2 L5 S( [# Q
  34.         GPIO_Init(GPIOA, &GPIO_InitStructure);        
    + Z3 e& h, M! r. Q  L  S

  35. ) l; d$ w* a% Y
  36.         //Usart1 NVIC 配置
    9 @: h$ ?& c3 s" u
  37.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;3 u1 X3 o6 M* d- A
  38.         NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级3% V; [" E5 a! h* C6 ?
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能- E5 G. n7 x7 i: [( _+ [3 _
  40.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
    0 X+ C( `/ u; J* Z) ~4 Z
  41. ' W4 W2 M. d. j( `! D" d- D
  42.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率8 D# `$ L" g6 {! i- p. @
  43.         USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位
    , N  y9 O3 }6 a; T
  44.         USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位
    / p, @1 s- I9 _' Y7 Z3 @  {+ P# z- c1 [
  45.         USART_InitStructure.USART_Parity = USART_Parity;//设置效验位
    : {: i  E+ D! t/ F% Y$ ~1 C
  46.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制
    - a3 I3 r4 @( E
  47.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式& n$ G# k- Z& c) m; ]
  48.         USART_Init(USART1, &USART_InitStructure); //配置入结构体
    & }5 Z. B1 a* ~5 w, {
  49. % q1 |% v. W4 Y
  50.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
    9 S3 N  {! W5 Q$ f4 h' R
  51.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断6 G, Y) {& g* k5 i7 m4 u4 `
  52.         USART_Cmd(USART1, ENABLE);//使能串口1
    - E9 p% b  y# J+ O% `" s" z) ?

  53. ' }7 s8 z2 y7 w" e- Y$ G
  54.         myUart_callBack = cb;
    % e& \7 P- m0 g9 }6 s) ?
  55. }                        
    8 _+ p7 N3 k' W% n1 z; ^
  56. void myUart_setBaudRate(uint32_t USART_BaudRate)
    2 F% ?2 R' a6 E/ N3 @& f, b; @. @
  57. {
    $ A0 n& M0 n. C- P, _) k
  58.         USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
    ) J. t7 Q2 e, ~
  59.         USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
    5 Y0 I, M; z8 G
  60.         USART_Cmd(USART1, DISABLE);) R7 e$ I8 w+ H$ @  O$ Y
  61. 6 h8 H  N. O! w" e( F
  62.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率# I1 T& @3 K- w
  63.         USART_Init(USART1, &USART_InitStructure); //配置入结构体& F  C( }, _  z; f

  64. 4 D7 J6 _* C0 e* I5 p& g2 x
  65.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
    ) q# l9 S$ y9 I) ]; f) ~
  66.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断
    % w7 ~5 G1 e: e7 A# a  s
  67.         USART_Cmd(USART1, ENABLE);//使能串口13 z3 L# s- Y' f' Y
  68. }
    , B; m0 w' _( l$ v- i
  69. void myUart_sendByte(uint8_t byte) //发送1字节数据
    9 F* _$ _* k& w9 `
  70. {
    & Z& h' j% x2 P2 r+ s
  71. while(!((USART1->ISR)&(1<<7)));
    5 G2 q8 ~. G3 w+ p% W0 N' w. k" {
  72. USART1->TDR=byte;        
    " t  r9 ?  o6 P
  73. }                - P- E- T3 ~9 H8 A6 N5 w, t
  74. 4 s  u" l+ f* A
  75. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)
    1 J3 f( X9 U0 A- F/ L4 w! p) Q
  76. {
    - E- B9 W. F) ^" o& a, _
  77.         while(Length != 0)/ T# E4 a7 f! }8 b
  78.         {
    + A# c0 L8 b# }3 ~! F
  79.                 while(!((USART1->ISR)&(1<<7)));//等待发送完
    + H( n  n' F- @6 ]8 o0 s. R4 }% b0 @
  80.                 USART1->TDR= *Buffer;+ Q2 u$ U7 q$ A5 T
  81.                 Buffer++;
    + o) r" Q+ u8 o+ D$ @7 q0 Y
  82.                 Length--;+ V8 W2 w& I' k7 {8 c
  83.         }
    6 N' e2 t2 {) D1 _, ~2 r
  84. }# P7 T& o2 w% y
  85. : [) Z* a9 `8 L) }" [
  86. uint8_t myUart_recvByte(void)8 r5 B8 Z( U8 G8 Z4 p
  87. {        
    ) n3 q7 O* k$ @; o9 H, \' k
  88.         while(!(USART1->ISR & (1<<5)));//等待接收到数据
    3 T% r3 J  s6 u3 c4 ^
  89.         return(USART1->RDR);                         //读出数据
    ' @; T2 G  I6 u/ v- ?" D
  90. }- Y4 E; m9 L* ~
  91. % \0 _" K: `$ i! `

  92. 8 o; @0 @  `. T* c' R0 R5 G8 h
  93. PUTCHAR_PROTOTYPE , U9 ]' ^( D' v5 n4 R  T" L) ^
  94. {0 z5 [, p% J( ?! h5 t2 ~
  95. /* 将Printf内容发往串口 */
    5 O# \$ Q2 w4 O# |  B# W( e
  96.   USART_SendData(USART1,(uint8_t)  ch);5 Z% \0 c! e( J3 X3 t7 u
  97.   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)% Y. G' L& O  G& y- ^6 b1 p
  98.         {}
    6 |2 X2 y) K  S' q3 ]* S8 B, q

  99. & a3 |: l& w  `6 g9 R) u
  100.   return (ch);* d5 P" w7 {2 B' l' n0 C, V" E
  101. }! v9 C. A# R6 t) f! k, [

  102. 2 _6 u' M  K' a' ?7 ~$ {
  103. void USART1_IRQHandler(void)                        //串口1中断服务程序
    4 w2 P, M8 x, _& \: W0 T
  104. {, v2 a6 ?% o1 e# R8 N; _% c: x9 s
  105.         uint8_t Res;: A4 G3 |7 z8 E5 g
  106. 2 V" ~4 f7 Y: O
  107.         if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)8 R! e3 O1 z! |4 E& V
  108.         {" s; L( T+ z# x1 L) h
  109.                 USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除
    " N  f' ]9 H2 R: l0 ~0 a1 a
  110.                 if (USART_RX_count)
    $ P% {2 @9 t1 v) B3 v+ S
  111.                 {
    ) `2 h5 T- a+ f8 D
  112.                         if (myUart_callBack)
    ; L/ h. e; K1 F7 {0 r- H
  113.                         {- A5 h3 j# d: X$ g! W1 p
  114.                                 myUart_callBack(USART_RX_BUF, USART_RX_count);
    * [4 C/ C; T8 v2 y- M2 F% h2 ^7 O3 P
  115.                         }: a' y9 {  e7 [! Y' G  ?
  116.                 }
    . t/ n+ I" q4 D) a. z) H( R
  117.                 USART_RX_count = 0;
    : R# ]" Y9 \  g+ \' e- `  \7 d* V
  118.         }7 n/ ~& M- H# \* u1 R3 `# J
  119.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    3 _5 }) s6 U- y% q) E8 G% b  w
  120.         {  O) l9 o% J" ~9 }! z5 S3 T
  121.                 USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1);        //读取接收到的数据,自动清除USART_IT_RXNE中断标志! v3 _, P. X) C, G. H* C2 R6 d& P
  122.                 USART_RX_count ++;& }( [4 f$ w2 D$ C& }; P4 r: Q9 Y2 B
  123.         }
    4 [4 z" h& z0 }4 c; U
  124. } ; G7 e& _+ K& y  T! [  _
  125. . E5 T: _6 D. T; A
复制代码
& n5 S8 Y8 ]- P! n
赞 收藏 评论0 发布时间:2021-11-22 22:03

举报

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