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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
写在前面/ O, }1 ?; @! Y0 n6 m9 ]
芯片型号:stm32f030c8t67 S8 k$ e2 q4 G/ B$ N1 ^
说明:便宜,用量大
2 ?7 O" j  ?0 e1 o$ J% W4 b要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断
$ q0 B& P# O0 B" i1 |这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断
9 P# g) f6 Z' L) {本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
- p" f8 p! f' u0 C9 ~2 ^' l; y8 _% h5 g  H. m0 i9 P
一、应用
6 _2 z# _/ \$ u& t& T4 g+ }外部定义串口接收回调3 Y4 m$ e+ M; |9 w* j  o
当串口数据接收完成后,在该回调中处理串口数据即可' T. M( f7 H6 x1 d
  1. void Uart_recvCallBack(void *buf, int len)* I' Q3 N. @( e' J
  2. {
    % l3 @# [) k8 `
  3. 2 R- A8 n: u0 d
  4. }
复制代码

! f4 r; f8 ^. u; ?  X外部初始化串口
* u+ S4 N  z' S# ?0 L2 Y( c' V
  1. myUart_initialize(115200,
    : |0 [3 R; o+ |) D5 Q3 @0 F. a( Q
  2.                                         USART_WordLength_8b,
    $ m3 h- w2 E6 D2 Z. \4 z; l
  3.                                         USART_StopBits_1,
    : D9 y5 T' J+ S+ p: g
  4.                                         USART_Parity_No,
    6 b# h  F! f+ L1 R
  5.                                         Uart_recvCallBack);
复制代码
8 K3 r/ y8 G8 G* g! F
二、源码* j  z9 A" _: }- n0 P+ \6 M
myUart.h2 j7 s4 @8 u% x9 ^6 O
  1. #ifndef __myUart_H
    ) _* v2 _+ K8 O
  2. #define        __myUart_H( [% a) n3 T; \3 `

  3. ' J! K* X0 W9 x( D# P
  4. #include "stm32f0xx.h"
    $ g/ O" l2 E2 Y. |- V1 [) K1 n$ I
  5. #include "stm32f0xx_usart.h"/ o; A) h2 ^" `7 Z9 E3 k
  6. #include "stm32f0xx_gpio.h"+ _8 V6 x* e+ \/ ?
  7. #include "stm32f0xx_rcc.h": w2 H$ _! L( F- n+ {
  8. #include "stm32f0xx_misc.h"
    ; s( l4 B* M: G  V, m; I* B

  9. % a) l2 D0 e; h% i' B
  10. #define USART_REC_LEN                          200          //定义最大接收字节数
    & N- R- `! Y1 s5 q" b; d
  11. 1 r% @; D. Y4 B$ l% y$ _
  12. typedef void (*myUart_cb)(void *buf, int len);: ]2 d1 s3 t  X+ Y4 E
  13. * \) J6 J3 ]- u2 I; F
  14. void myUart_initialize(   uint32_t USART_BaudRate,
    : r$ N- N0 t, y7 |* ?" j- F- X
  15.                                                         uint32_t USART_WordLength,0 \: I* _, k6 v" ~# D
  16.                                                         uint32_t USART_StopBits,
    - J$ f5 V  n6 K& O, Z- \/ e
  17.                                                         uint32_t USART_Parity,- N( ?9 i  G' S3 n2 e6 q" i
  18.                                                         myUart_cb cb);
    7 j. ]) a6 F6 H, ]
  19. void myUart_setBaudRate(uint32_t USART_BaudRate);
    ' l5 R9 X' Y3 M5 p5 c* p# I
  20. void myUart_sendByte(uint8_t byte);
    $ \" C' a( L: ^
  21. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);
    * c5 U: P# I5 j7 D
  22. uint8_t myUart_recvByte(void);
    2 l2 u' @+ A+ q. K0 {5 r! T8 m
  23. int fputc(int ch, FILE *f);
    & L2 `/ Z$ `1 v. @0 q/ G5 [4 i) Y
  24. & r1 t0 ]: Q/ K) R8 c6 H3 m
  25. #endif /* __UART_H */
    # _5 n9 ~0 h: E* V0 F7 z
复制代码
4 z: }. |, F: ?: ^. _0 U
myUart.c6 `0 P0 Q% u! I8 I
  1. #include "myUart.h"( @& ]7 `7 g6 r. S  d

  2. ; J) z- x; s( X/ d+ C
  3. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)3 O6 ^) k' k# d9 _! N1 O

  4. / t& n8 R, H6 J0 T0 E; U
  5. uint8_t USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
    $ d0 ^. Q5 _9 n6 a- O3 ^- H
  6. uint16_t USART_RX_count = 0;       //接收状态标记               
    ) V; G' g: a  H; n2 p* _
  7. myUart_cb myUart_callBack;
    4 h  n5 N/ W9 k5 C, m2 [
  8. /* Private functions ---------------------------------------------------------*/
    5 t& l) d8 q& s5 i2 P4 d4 L) f3 P) n$ ^
  9. 6 J6 \$ e9 y% b
  10. USART_InitTypeDef USART_InitStructure;: _; a3 X* W, ~" o. U
  11. ! t. r+ t& E5 S0 \. z) j
  12. void myUart_initialize(   uint32_t USART_BaudRate,# b$ E* G9 A9 V' x: g/ W! o
  13.                                                         uint32_t USART_WordLength,
    & U$ H  h( i( w" h8 p
  14.                                                         uint32_t USART_StopBits,
    - p8 O7 Q2 L' X8 M6 p3 H, D; ^
  15.                                                         uint32_t USART_Parity,4 R( T/ r3 W/ h8 n- V' R- q! ?
  16.                                                         myUart_cb cb)% ^6 C3 r% P" ]- F
  17. {  
    # P% S- m) _, P9 a

  18. 2 \: B  W) s/ U# ]" W
  19.         GPIO_InitTypeDef  GPIO_InitStructure;" o4 W/ y* a2 G. L: l$ X: L
  20.         NVIC_InitTypeDef NVIC_InitStructure;
    * D4 f. ]& \: u" H! E* C

  21. ; w9 K9 D5 R" U$ Q& V
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
    " Q$ q& A. H( A
  23. ( P2 G& c4 ?4 n$ u" f% q& W3 G$ {
  24.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
    3 ?5 u7 e4 h" p, I
  25.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        
    6 F! H3 K8 J0 f% w+ X4 }# a
  26.         /*! P; q( V7 ?+ j4 g1 s$ `
  27.         *  USART1_TX -> PA9 , USART1_RX ->        PA10
    ; p1 l* _  E/ p7 A  h. I& U( r
  28.         */                                
    . ^8 P1 t6 x# R/ g( B* }& w! Q) s
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 
    ( \( T+ g" b( R( P# a
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   [9 [5 x% ]" `& f3 V. z: ~3 O
  31.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    * S" j1 \1 r5 p2 k' T8 H
  32.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;- Y' T# L  c8 J
  33.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    * }( L6 z7 ^$ b  s& T: |
  34.         GPIO_Init(GPIOA, &GPIO_InitStructure);        
    : I& {. p; }) f# \

  35. 7 H( U2 w( V3 |& G- d
  36.         //Usart1 NVIC 配置
    2 j% o' Y6 O) H
  37.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;& U+ |7 \& Y1 p/ `$ R9 e
  38.         NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级3
    $ ?9 O6 m7 o! @
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
    - _# D5 r: `0 v: G5 z
  40.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
    1 X7 {  d! Q/ \1 Q, G; C* R

  41. 5 `, i/ l6 }2 b; E
  42.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率
    3 f+ G. ^2 b; W! f
  43.         USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位( d+ v0 F/ F. \0 C& ^# M7 m
  44.         USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位6 E8 h6 ~) ~% B  z8 F% ~
  45.         USART_InitStructure.USART_Parity = USART_Parity;//设置效验位
    4 I1 N7 h% e7 p& t* Z: R! ?8 m
  46.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制
    - y) l1 e- i( Y8 v3 c* P
  47.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
    " |) S+ b5 W$ k& `) |
  48.         USART_Init(USART1, &USART_InitStructure); //配置入结构体8 V6 y* l  S4 W; t1 n; S
  49. # i) u1 i/ G* z* ^
  50.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
    ( x+ h* y3 W! J7 T. S
  51.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断
    ) [, _  @9 C4 e7 Y$ S. N
  52.         USART_Cmd(USART1, ENABLE);//使能串口1, u  m* q' a7 f

  53. $ J/ B6 K* ~" v, Y! R6 d
  54.         myUart_callBack = cb;
    & @, Y+ R  e3 W# B$ Z! D
  55. }                        1 ?3 R3 _2 h! P; V" q
  56. void myUart_setBaudRate(uint32_t USART_BaudRate)
    3 W: `. {+ h6 j# f6 X1 N
  57. {$ d" [$ D9 n0 E2 K
  58.         USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);! _0 @, v7 x% w; M" l% A8 z, J. Q
  59.         USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);! A) V1 s3 }  \' y
  60.         USART_Cmd(USART1, DISABLE);! k; |1 z" r# s! O3 g
  61. - K/ t5 s9 \% ?. K; Q
  62.         USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率
    / ?. |- T; y5 G
  63.         USART_Init(USART1, &USART_InitStructure); //配置入结构体( ?# f5 k; m3 v) ~, W

  64.   h5 a  l' y: l' _
  65.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
    ! d- b+ \% S* `# g9 g
  66.         USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断
    , W8 F# i( k' N: d# x# ^  f  _
  67.         USART_Cmd(USART1, ENABLE);//使能串口1
    ( _. ]% l4 n& g% p% |+ M
  68. }
    / n  q& F- e  m: h& H# C- M3 s
  69. void myUart_sendByte(uint8_t byte) //发送1字节数据# q/ R3 ?7 \9 {  q
  70. {. U# ~: }( W# F5 P8 s
  71. while(!((USART1->ISR)&(1<<7)));+ G2 s  u  z3 n7 p# i) N' r  r
  72. USART1->TDR=byte;        
    2 N+ u# n$ U. {: c
  73. }               
    + {1 B# C% F6 Y; {/ p6 k

  74. 6 m- k+ }! E2 A6 ?. X5 g2 x: N
  75. void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)
    $ b! p- u1 C' M2 N+ T) \
  76. {
    $ L) g5 C" ]$ Y8 ^
  77.         while(Length != 0)
    8 V: s( d" r, L5 F. p
  78.         {
      E. `) u0 Q+ X% L$ h, K1 [  C
  79.                 while(!((USART1->ISR)&(1<<7)));//等待发送完
    & x* S' S; j. [/ E+ a7 ?
  80.                 USART1->TDR= *Buffer;- [* Z# F. g- {3 _0 `
  81.                 Buffer++;
    0 t6 S6 g9 {% I
  82.                 Length--;% m+ L' t3 _& @# c- Z
  83.         }
    9 s( P) q4 {3 x% {% U& ]; e
  84. }9 X% _' i2 c- W9 d& H$ |

  85. ( [6 z5 t4 a* v1 O4 {7 O" L
  86. uint8_t myUart_recvByte(void)$ S" F3 p- d2 K& {3 _+ [
  87. {        * L& ]/ |( y( Q% h, M
  88.         while(!(USART1->ISR & (1<<5)));//等待接收到数据
    & Q+ I6 [9 A& p1 a
  89.         return(USART1->RDR);                         //读出数据* D( ~- G- G9 n6 t$ z
  90. }9 ~' Q0 q/ d, i/ v' x  }  Z

  91. " [) z6 ~  [! }. L  m& j

  92. . k4 e, q2 L8 f7 c; o& V
  93. PUTCHAR_PROTOTYPE
    ; @( d3 {0 _/ J5 h+ J  w
  94. {
    0 e3 {" g0 d% P: p: H, z, x- t2 m
  95. /* 将Printf内容发往串口 */3 T' s+ X/ k  W
  96.   USART_SendData(USART1,(uint8_t)  ch);
    - A- x9 P1 n" i
  97.   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET), K: y1 W: ~. w- o( q) e
  98.         {}" _. K" s2 u6 T- A3 d1 i& M

  99. 3 R8 C! Y$ A9 {( @, h3 i* H
  100.   return (ch);
    5 d9 v: R8 D6 B; P  e
  101. }
    - [. s  M! P. V* C% T# F

  102. ( d# H* S" M9 e7 f, \, ^" l
  103. void USART1_IRQHandler(void)                        //串口1中断服务程序
    & [$ d0 _4 O, W
  104. {9 i4 e8 g& B1 H
  105.         uint8_t Res;. O4 k* h* r$ f$ n/ H& L7 ?; u$ w& ~  {
  106. # b/ ^/ \" `& W" \- ~8 ]+ ?; e
  107.         if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    $ v; \3 ]+ ?& l1 I8 |2 Y$ W/ Y6 e
  108.         {% g' J' Y2 z2 m. [8 H6 w3 c
  109.                 USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除
      t5 g" I# }: B& T7 k' q; T
  110.                 if (USART_RX_count)$ ^  c! O+ i, {6 S) A1 S3 g
  111.                 {
    7 J( E, J& _. @9 O" k; M
  112.                         if (myUart_callBack)4 W! K* a% b& S: p
  113.                         {
    $ K9 ~3 q& x0 i$ |. M6 U; Q
  114.                                 myUart_callBack(USART_RX_BUF, USART_RX_count);( v1 K' C+ O* K3 N- ]; b0 I
  115.                         }
    / F" Y7 T( X/ W: h. I4 p
  116.                 }+ J8 k/ {4 b, Z/ I2 J# o8 C
  117.                 USART_RX_count = 0;; |3 G" d7 t! G3 p6 V. u. F
  118.         }' y0 `/ S7 d  I" ?3 a
  119.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    3 E2 l' d9 Y/ b. `
  120.         {
    ' X3 [7 [1 I  z) Y8 S8 p* ^
  121.                 USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1);        //读取接收到的数据,自动清除USART_IT_RXNE中断标志
    ) l" S7 L& h' u4 W+ @8 d9 @5 p+ [3 V
  122.                 USART_RX_count ++;
    + q. E! R4 C$ l! D2 X  @
  123.         } * {- w  Z4 M) o
  124. }
    3 N* Q- w! W: @2 D

  125. 4 ]+ A/ ?/ C+ [$ C" [7 z
复制代码

+ ^5 g; A; J, j) J
收藏 评论0 发布时间:2021-11-22 22:03

举报

0个回答

所属标签

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