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

STM32 串口通信UART代码实现——基于STM32F103C8T6

[复制链接]
攻城狮Melo 发布时间:2022-11-8 22:08
通过串口与上位机通信是经常用到的调试方法。
) s$ ]0 x4 f5 i, e) g& z9 f, ^( w# }. _) L- J( ^6 ?
STM32上外设USART引脚配置
; K; C+ V' [  \6 Q+ a0 |1 [TX(默认PA9):复用推挽输出
- n, I% R3 }9 |3 P6 [RX(默认PA10):浮空输入或上拉输入- R8 t. U" p% Z2 W8 Y' b
8 V+ _/ p& M' F4 R0 w+ @
在写代码前需要检查硬件是否满足要求,使用串口通信时一般需要安装CH340驱动或者CP210x等,这取决于你的电平转换芯片是什么。3 X& g5 p8 q  @# B

( p( f0 _5 x: M串口设置的步骤一般为:
: v4 H9 F% R6 r1.使能串口时钟,使能GPIO时钟;
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA);
复制代码

5 C( U/ \9 r, r0 k需要同时打开GPIO和外设时钟。0 d$ Y( y1 Y9 c1 A9 z! X
2. 设置GPIO端口模式;. ]1 w4 k) G: P( w) S

$ r# p# S) v+ u" N
  1. GPIO_InitTypeDef   GPIO_InitStructure;, v" n/ I2 |2 n2 C, n0 {" Y
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;. T8 @0 F, ~  F
  3. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    # M8 B  M) D& X7 X; R
  4. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    6 J9 o- f) U2 O& [0 G; F3 [9 @
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);
    5 z) x. ^8 _) i' z6 ^' w% D' ?

  6. ! t. U% X% ~# `6 k( {( K2 F- w
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    ! Y# @- j3 j6 N
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 7 a3 P1 K3 L/ ]/ @. M
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);
复制代码

% {4 {: C) e# K7 ~- ~& M3 \PA9:复用推挽模式   PA10:浮空输入1 O, V& {! }$ {" e8 p$ q/ |+ |

' O# I( t' l; E( \% a9 H! o# ^3. 初始化串口参数;; z( k6 _1 r; V) [6 O; i/ M

: H4 @# `# X/ a
  1. USART_InitTypeDef USART_InitStructure;
    & t/ J) Y. ]& n* h. x  h
  2. USART_InitStructure.USART_BaudRate = 115200; //设置波特率;
    9 P& K, a1 e8 e) w6 Q4 x
  3. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式& }. e/ J" T% N* n) ]
  4. USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止位+ U6 j* @& e* D. l& F
  5. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
      F; b& j; ^+ [6 Y2 c) R
  6. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
    4 S$ b6 {" M) ^  {: X9 l) |9 R
  7. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式+ e9 E/ x2 t! ?0 O3 q9 e% j: _) N. y
  8. USART_Init(USART1, &USART_InitStructure); //初始化串口
复制代码
) ^" `9 g, s& m# [' D" F
4. 开启中断并初始化NVIC(如果需要开启中断才需要这个步骤);
, ]+ X, c4 v9 q9 Q6 r1 Y8 P/ @6 F
! p2 b8 s* [* P* O$ [
  1. NVIC_Init(&NVIC_InitStructure);
    * q2 v4 ]- z2 C1 h0 A; _9 o" e9 |# L
  2. USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
    ) }( G& z. ^. r- Y
  3. USART_ITConfig(USART1, USART_IT_TXE,ENABLE);
复制代码
5 Q: z$ x( Y  B" C
RXNE是“准备好读取到的数据”事件标志,TXE是“发送数据寄存器为空”事件标志。
/ Z6 y( ~, e2 Z- a9 V5. 使能串口;
; O4 F1 O( i! y: C/ x$ D- S/ w, `2 u
  m6 N9 X" W1 H
  1. USART_Cmd(USART1, ENABLE);
复制代码

' X9 h1 V% L/ ?4 q, k, V2 O6 E6. 编写中断处理函数;) F& w' t7 @8 W' a1 `* [% C: d. g! `
4 e5 T* g% q2 [) {* g6 u' V
  1. void USART1_IRQHandler(void)$ c# a) X/ R& M- _- U9 ^7 p8 C
  2. {
    3 Z4 s  ?1 q% x5 o. d: I* c7 m. u; @. P
  3.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)% q# r% E5 [2 C% u$ F% \8 q
  4.     {8 h4 t5 W* e+ w
  5.         //编写处理程序
    1 Q/ A+ X$ y! O
  6.     }
    " r8 Y" C; A% R% z4 v
  7. }
复制代码
, c# y7 N9 b# l3 d! P
可以根据特定的中断事件,比如判断是否发生串口发送完成中断(如代码所示)。2 D! W* H8 ~, q) w- A0 ~% t# `
: f" {4 x' c& Q2 X: T4 w" K
7. 发送接收数据。$ i. N: a6 D4 w2 o7 |
; F! l6 ~( X. }. f
利用发送数据函数USART_SendData(USARTx,ch);  可以发送一个字节到串口,并利用USART_GetFlagStatus() 读取发送数据寄存器的状态来 等待发送寄存器将数据成功发送。* L# d8 J+ {8 V+ U% t1 s8 H- f/ L
7 H/ O, s& Z" S/ |8 O
  1. void USART1_IRQHandler(void). D) l! N6 T( `' u, K
  2. {
    . T  B( w" l0 Y1 b* M# e+ z: k
  3.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
    ) P) v( i/ `, D6 U  N) p
  4.     {9 i& w6 y% f- {$ D. y; ^
  5.         /* 发送一个字节数据到USART */ 9 H: Q, ^" o* y8 d4 v/ k" U$ d
  6.         USART_SendData(USART1,ch);
    ) D6 I2 [5 q  w7 v
  7.         /* 等待发送数据寄存器为空 */
      ^& A' {# f; B2 M) _" J: Q
  8.         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);. q1 X( o8 @3 {5 d$ n
  9.     }
    + p* h) x' a* \! z! ]
  10. }
复制代码

" C# Z# i/ A( d) {8 ]0 R接收数据利用函数USART_ReceiveData();  从DR寄存器读取接收到的数据;在中断处理函数中通过if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)判断是否是接收中断,如果是,则读取串口接收到的数据:Result=USART_ReceiveData(USART1);
. W2 n, Z" S4 P( }9 I* c) e; l: a
  1. void USART1_IRQHandler(void)
    9 \7 u: P" a; x. G1 V
  2. {) O1 H( s3 [9 Y$ ~/ \7 @) _5 v6 K
  3.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET), G' ~3 Z' T; K0 s
  4.     {9 ]- }3 G  I/ k
  5.         Result = USART_ReceiveData(USART1,ch); 7 k2 _) c7 G: ?6 L, @
  6.         while (USART_GetFlagStatus(USART1, USART_IT_RXNE) == RESET);
    8 c- V# E0 h7 {. h& S2 o
  7.     }
    % w3 D3 ?* s- d
  8. }
复制代码
0 }, T* Z7 i6 X+ n8 z* _; k, s
根据USART_SendData(USARTx,ch);和USART_ReceiveData();两个函数,每次发送或接收一个字节数据,以此为基础,可编写一次发送或接收一个字符串的函数,但这样还是不够方便,为了能像C语言那样使用printf语句输出,需要重定向printf函数发送字符串。
( N7 {1 _8 T: t# z( Nprintf()函数实际上是一个宏,最终调用的是 fputc()这个函数来执行输出的,所以如果重新定义了这个函数,就能使函数向串口输出。
0 u0 Q" l  ^$ S; y4 q! p0 q' M& w6 U  ]% M. v* d- J5 E- E
  1. /* 重定向printf函数 */) O  o% }+ ^# @2 t' a% g; S9 P
  2. int fputc(int ch, FILE *f)
    " o& e- u( {# B' r
  3. {
    8 |6 K& ]# ^) M: D
  4.      USART_SendData(USART1, (uint8_t) ch);
    # X3 k' e* t6 ?
  5.      /* 等待发送完毕 */ . ~$ p3 q$ @1 {. O# C6 M/ }
  6.      while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    # I$ H0 U- j/ |/ r+ W
  7.      return ch;
    + O, B& o$ T0 v* u5 h* A4 |$ u& Z
  8. }
复制代码

9 R2 S+ @6 \, c% e$ r同时也可以重定向scanf()函数接收字符串:
2 y& X' P+ D( N
  {' m' e% B1 _7 W3 R/ @6 Z2 n6 z: l
  1. int fgetc(FILE *f)
    2 n5 f* ~; U2 a
  2. { 2 Z/ E( Z+ W* m9 h* [8 U$ V* i
  3.    /* 等待串口输入数据 */+ U' k3 `/ I, ]* m: e  ?
  4.    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);' i* F# ^' E& v7 D
  5.    return (int)USART_ReceiveData(USART1); ! J  L' i  H$ }) @
  6. }
复制代码

9 U  Z6 i1 s8 k! G6 C, P) D6 j————————————————+ q8 s8 `& @) G' _& `
版权声明:云缙
0 N8 X! h6 n9 w6 E+ \2 {; m5 x9 ?& ]7 M1 S' \3 C  b" L- q
/ E9 o" S& y! Z% K7 v
收藏 评论0 发布时间:2022-11-8 22:08

举报

0个回答

所属标签

相似分享

官网相关资源

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