请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
攻城狮Melo 发布时间:2022-11-8 22:08
通过串口与上位机通信是经常用到的调试方法。
0 j/ h8 M: v: P6 O9 E( r* {3 F1 @4 C, W* s, N9 N" U
STM32上外设USART引脚配置
- y: s/ B2 C% h4 J8 V+ f8 vTX(默认PA9):复用推挽输出8 q, S( l- u/ h
RX(默认PA10):浮空输入或上拉输入
) ^) Q3 }% X; e' Y) o7 ], s* U2 {
在写代码前需要检查硬件是否满足要求,使用串口通信时一般需要安装CH340驱动或者CP210x等,这取决于你的电平转换芯片是什么。' T& m( a1 _" V( Z- V$ K' p
, t9 I" e9 B7 F& q
串口设置的步骤一般为:
1 O& X- ~0 I/ T% K/ D' E. D" E" B6 W" w/ R' }1.使能串口时钟,使能GPIO时钟;
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA);
复制代码

1 @. l- G, G* v% C, x2 H% u需要同时打开GPIO和外设时钟。  u: O& X2 F6 O
2. 设置GPIO端口模式;
& e* a5 C; j9 c; C1 R0 p1 d7 S+ o9 J5 k3 t9 X, M. Z# A" t- P
  1. GPIO_InitTypeDef   GPIO_InitStructure;
    2 g5 J% P5 I; `1 V* ?
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    # T9 z1 T! j4 X( ^! [0 I4 F) y3 \! l
  3. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    # S) I* C  @# E; n& Y+ u0 j. u
  4. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    : {3 N) P: v8 K4 h
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);) z1 E; k( P3 O- }' P2 W( r
  6. , S% }4 E1 J- B( i% w
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    . z6 _! p0 z. p" L% H% e4 `' s9 x% j
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    : }, ]1 q8 M3 U
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);
复制代码
- y+ g. |5 @9 e& o7 j6 W3 r
PA9:复用推挽模式   PA10:浮空输入
, b: g2 n! e4 p1 h2 F# A$ Z
% D9 L' l7 @' q: A& L# Y7 A3. 初始化串口参数;
) k2 `2 N/ b9 g6 ?. G$ {2 e2 m" p' g; N) \5 ?( I
  1. USART_InitTypeDef USART_InitStructure;: |3 C0 l% t6 H1 O& v% X. c
  2. USART_InitStructure.USART_BaudRate = 115200; //设置波特率;
    ; e( y7 ~- c/ C$ K9 J7 O' h
  3. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
    2 U( w1 Y3 l6 b  Q
  4. USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止位. r( X7 [! b  H3 r! ]* M
  5. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位/ g8 D9 h* H5 P
  6. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制  P0 w& G7 n9 P( M) ?
  7. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式6 [  o, R8 C' k" A
  8. USART_Init(USART1, &USART_InitStructure); //初始化串口
复制代码

- K! k& j* n2 v. O/ ?4. 开启中断并初始化NVIC(如果需要开启中断才需要这个步骤);
* Z# e# L) u, I$ Z2 i( t, T  s3 Y7 A4 |' j5 M1 K, `
  1. NVIC_Init(&NVIC_InitStructure);0 F" a* k5 _$ ]! Z* t7 S; t
  2. USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
    ) O. w+ Z- S3 w- Q4 W
  3. USART_ITConfig(USART1, USART_IT_TXE,ENABLE);
复制代码

" |; B  C3 \8 o) t* p. jRXNE是“准备好读取到的数据”事件标志,TXE是“发送数据寄存器为空”事件标志。
6 Z; ]- n; M3 ?1 q5. 使能串口;
8 R* Z& C6 p5 i
! ^2 z. M4 l+ C3 V! a4 l: S
  1. USART_Cmd(USART1, ENABLE);
复制代码
2 R2 {$ N0 S# G4 h* Z; W( e( O" s
6. 编写中断处理函数;
; @8 {. ?8 X4 f2 J% `% F+ E4 q
$ m3 s/ ]1 @, v' J- `4 f+ B
  1. void USART1_IRQHandler(void)" p- o0 Z  u/ N
  2. {5 |# h* D/ u0 O+ z6 A
  3.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)- t0 {# r- x* u3 t  T
  4.     {8 J- a, ^4 @# Z* ?+ w" Z, `
  5.         //编写处理程序
    , D5 k9 H( `' S0 q0 S$ q
  6.     }
    7 [* x: H, y8 ^9 T! _& L/ }, R
  7. }
复制代码
' K& m  }, r6 n6 c" _& _5 B
可以根据特定的中断事件,比如判断是否发生串口发送完成中断(如代码所示)。9 L; X3 T. N' n4 p

2 j# s9 F! ?/ O7. 发送接收数据。+ m; ]0 L8 W' D5 j7 g* l

  S' S- E1 n2 z/ o  T5 c. t0 W# N利用发送数据函数USART_SendData(USARTx,ch);  可以发送一个字节到串口,并利用USART_GetFlagStatus() 读取发送数据寄存器的状态来 等待发送寄存器将数据成功发送。- I0 t7 L: O" }' t2 x/ a

9 A: Z1 G7 O  t' M. @! k% w; b% x
  1. void USART1_IRQHandler(void)
    * S9 ^/ W/ @, H- [7 {* g2 L% ~1 h
  2. {3 e% W' t5 t, E: d
  3.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)3 L! p5 a% v6 s( {3 o% M
  4.     {$ J8 W* M3 _6 E  c
  5.         /* 发送一个字节数据到USART */
    6 L0 n: ?, O  |3 O8 }2 O1 ]# s
  6.         USART_SendData(USART1,ch); . r% Q, C5 r4 f% \6 v! _
  7.         /* 等待发送数据寄存器为空 */
    % d$ O$ z7 {! h4 e0 T
  8.         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);7 F/ C4 s1 i# d8 S1 L3 N
  9.     }) U) X' L# E' q' A3 \
  10. }
复制代码
0 O  a6 ^0 }1 k0 s( h# ?, T$ X
接收数据利用函数USART_ReceiveData();  从DR寄存器读取接收到的数据;在中断处理函数中通过if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)判断是否是接收中断,如果是,则读取串口接收到的数据:Result=USART_ReceiveData(USART1);2 o& c( o- D/ g, l* f- v/ z

$ P( }0 q' t3 ~5 S& C0 j, H
  1. void USART1_IRQHandler(void)" Z$ U: r. S4 C% t* G
  2. {
    ; B: ^$ ~# f6 ?5 M
  3.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)" r7 d3 s- C3 l8 f  K3 x5 X, o
  4.     {7 k6 P; e2 t; u
  5.         Result = USART_ReceiveData(USART1,ch); 6 {0 ]. E7 Q, O- l" S( M
  6.         while (USART_GetFlagStatus(USART1, USART_IT_RXNE) == RESET);' x4 f2 I/ W& `# x3 I( i
  7.     }& v; v3 j- H4 V9 ?! J
  8. }
复制代码

! t6 w& Z: p% g# a: k6 ]根据USART_SendData(USARTx,ch);和USART_ReceiveData();两个函数,每次发送或接收一个字节数据,以此为基础,可编写一次发送或接收一个字符串的函数,但这样还是不够方便,为了能像C语言那样使用printf语句输出,需要重定向printf函数发送字符串。$ ]8 U7 d' `5 E# ], k8 s/ {$ B
printf()函数实际上是一个宏,最终调用的是 fputc()这个函数来执行输出的,所以如果重新定义了这个函数,就能使函数向串口输出。6 ^( S7 `2 M+ j( t2 K# V8 z
7 v& ^) r: e: e3 E
  1. /* 重定向printf函数 */: t/ f( O3 D  n8 y
  2. int fputc(int ch, FILE *f) ) N1 a* P1 k. W2 S2 E7 n% c
  3. {
    - o& K: a- l8 @  Z4 W  w4 t! _
  4.      USART_SendData(USART1, (uint8_t) ch);- X& K0 i$ P+ k6 |  k: L# |& I
  5.      /* 等待发送完毕 */
    , }/ j2 i* N3 ~" _/ O, e
  6.      while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    3 F# g3 F2 O9 G' j! t( e2 m
  7.      return ch;8 L* C3 F) E6 c4 N4 q
  8. }
复制代码
  M/ T6 ]7 J+ Y! c+ @& ~
同时也可以重定向scanf()函数接收字符串:) \; n& t6 ]) P
1 L4 y9 @9 p0 D/ }+ {
  1. int fgetc(FILE *f)
    $ d/ ?: h- U3 i. A% T$ t) a
  2. {
    7 E! [9 O0 j: |% y
  3.    /* 等待串口输入数据 */
    ( I& z' ]: ^$ f$ l
  4.    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    : P" H" T, M* s7 q
  5.    return (int)USART_ReceiveData(USART1);
    - x, q: M! Y7 a( N0 R' p
  6. }
复制代码
" R1 d3 I4 u& a. N# x+ M
————————————————  q) D" T( r2 X. h# Q
版权声明:云缙% G0 P/ n8 y! C/ ^$ \

# ^8 [* G5 t) h, }. b# ]! i  a- R, h: \: }6 T! a
收藏 评论0 发布时间:2022-11-8 22:08

举报

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