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

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

[复制链接]
攻城狮Melo 发布时间:2022-11-8 22:08
通过串口与上位机通信是经常用到的调试方法。  _! M+ Q$ M7 a

& ?7 \2 y: d$ z6 M, B7 {STM32上外设USART引脚配置( r; a# G, O2 B7 _2 y5 ?
TX(默认PA9):复用推挽输出8 _- W6 H6 A/ T3 K
RX(默认PA10):浮空输入或上拉输入  a3 Q2 d; |2 [# x0 A% g2 c

" T: Z+ V- L& E" G3 C' B在写代码前需要检查硬件是否满足要求,使用串口通信时一般需要安装CH340驱动或者CP210x等,这取决于你的电平转换芯片是什么。. w5 {, B3 |/ P2 s$ B- E
9 z* c/ T& Q" z* p
串口设置的步骤一般为:
7 A2 d8 J# x* F% g& ~& X0 p1.使能串口时钟,使能GPIO时钟;
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA);
复制代码
9 S$ x* v( G: l: w
需要同时打开GPIO和外设时钟。: I% K  G" L" o3 h! b
2. 设置GPIO端口模式;
) L2 e3 C5 l& G6 K3 C; r2 y0 t! f5 U* v6 i6 y8 S8 s1 ~
  1. GPIO_InitTypeDef   GPIO_InitStructure;# A+ a- i, C% T0 I
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;/ M+ c7 K# N$ V* X' B' A- j7 g
  3. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 1 {6 R, J; Y2 e- t2 _* v
  4. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    9 Q  C" y& m6 d: Y" v' t
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);
    ( O4 `9 h" o- L0 n9 Q5 |

  6. 7 E; j: ?! X% U! I2 s, v
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    5 G9 L: y$ x& _- r1 Z' |  F
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 0 d; ~% H) b+ i3 F& }. |% [
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);
复制代码

. `2 ^8 E2 c" J) TPA9:复用推挽模式   PA10:浮空输入
& @' X' f1 \5 A+ Q0 ]1 ~1 q1 k2 d" M# ?
3. 初始化串口参数;# R! U5 n4 C) b6 b2 H8 F: `0 E
( v5 P5 U) S6 m/ K  P2 i+ Q9 j& s8 |
  1. USART_InitTypeDef USART_InitStructure;" d3 q; P+ S+ v" v
  2. USART_InitStructure.USART_BaudRate = 115200; //设置波特率;9 B! q6 e: L. {% @  ?
  3. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
    7 j0 Z. Y# X/ y- X; c% C1 w( b* a5 ]$ g
  4. USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止位
    9 s5 |# C4 U" G' ~" t% [) w9 u8 O4 P
  5. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位# L! v0 ~# U# r! r" ^; A, v% P, j
  6. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制0 V6 C# Z0 E/ l9 [! F0 O
  7. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式* @9 y5 X: \7 t7 u( f
  8. USART_Init(USART1, &USART_InitStructure); //初始化串口
复制代码
( R  Y- `) v) E7 R( d
4. 开启中断并初始化NVIC(如果需要开启中断才需要这个步骤);
0 `2 `" i: ^8 ?, O
- t6 e* G) x9 |( l
  1. NVIC_Init(&NVIC_InitStructure);
    + Q) K1 O% j, c+ E5 o
  2. USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
    ) D  j. |& L( E* P3 Y5 F
  3. USART_ITConfig(USART1, USART_IT_TXE,ENABLE);
复制代码

) l$ W' `0 r2 V# XRXNE是“准备好读取到的数据”事件标志,TXE是“发送数据寄存器为空”事件标志。
& I4 ?& d9 U5 }6 O$ v* h6 h9 _5. 使能串口;
% l/ B7 H* ]  ^! K& q0 h, s9 _! J9 q% `2 [- f6 z
  1. USART_Cmd(USART1, ENABLE);
复制代码
, |  k: u5 u/ J; ]! P2 z: V" h3 j: H
6. 编写中断处理函数;
7 v- h8 h# S$ f6 L+ M  L0 L( x8 b+ D. W0 }" R; l5 }: E
  1. void USART1_IRQHandler(void)0 A7 N' T. \7 Z8 J
  2. {' A  T4 R: n# J( z' a; }& m- Q6 A
  3.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
    . \, X7 x' `! |- a
  4.     {
    % o  e, o% x! W
  5.         //编写处理程序
    5 V$ p6 ?/ u& r/ W7 x
  6.     }% j6 P( h# L# F  U7 q4 e
  7. }
复制代码
, v2 A1 R; C, k* f, [) t% y
可以根据特定的中断事件,比如判断是否发生串口发送完成中断(如代码所示)。2 E5 ]* Q/ J" a$ z- K; ?3 a
, y! a5 `. J! V, g% K/ Y
7. 发送接收数据。
. q) j3 n, f2 j9 r' S) {/ U% R1 D1 ^
利用发送数据函数USART_SendData(USARTx,ch);  可以发送一个字节到串口,并利用USART_GetFlagStatus() 读取发送数据寄存器的状态来 等待发送寄存器将数据成功发送。$ L, w7 g7 ]/ B, S( x7 J/ o- b

  H3 k- H+ s6 x% ~/ P8 Z* B8 E: h
  1. void USART1_IRQHandler(void)
    & k2 D8 t5 s' a" ^$ C7 Q0 A! X( @
  2. {  G- Q) k7 o' r# J
  3.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
    $ n; @4 o. w! P* W5 R: v1 J% S
  4.     {
    ! F" ]! n4 T" S, d
  5.         /* 发送一个字节数据到USART */
    . {, n- v% w5 [, |' X
  6.         USART_SendData(USART1,ch);
    $ \7 i2 g# L! k4 U
  7.         /* 等待发送数据寄存器为空 */
    0 f0 ~, ^* J7 u
  8.         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    ) M2 v, ^' j; Z6 I5 I# J
  9.     }% m+ |$ f$ U: x) L
  10. }
复制代码
- P7 c* z/ ~0 ]  B5 V2 Z
接收数据利用函数USART_ReceiveData();  从DR寄存器读取接收到的数据;在中断处理函数中通过if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)判断是否是接收中断,如果是,则读取串口接收到的数据:Result=USART_ReceiveData(USART1);
/ x! z6 o6 v3 z# r: |5 P" Z( c! a# \( r  M
  1. void USART1_IRQHandler(void)
    4 f7 T: r& |6 P% t/ B
  2. {
    % S% Q) u9 l, ~8 c; R  y2 m0 D
  3.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    ) C! c9 F- W# Y$ ?0 R8 p& t, i% q
  4.     {
    5 ]. q' ^8 y& S5 v) A' G" ]- f' V
  5.         Result = USART_ReceiveData(USART1,ch);
    2 h/ B! y( D- A# h8 U+ Z7 S3 C
  6.         while (USART_GetFlagStatus(USART1, USART_IT_RXNE) == RESET);/ w; ^+ z: V" u0 i: V5 t
  7.     }$ x; G5 L% k) D0 F" G0 z+ X
  8. }
复制代码
3 j8 {- w: c( v4 }& S1 I$ u
根据USART_SendData(USARTx,ch);和USART_ReceiveData();两个函数,每次发送或接收一个字节数据,以此为基础,可编写一次发送或接收一个字符串的函数,但这样还是不够方便,为了能像C语言那样使用printf语句输出,需要重定向printf函数发送字符串。% O- L; w: S- e0 c) c/ N5 ]' {
printf()函数实际上是一个宏,最终调用的是 fputc()这个函数来执行输出的,所以如果重新定义了这个函数,就能使函数向串口输出。# o/ w4 a3 X2 g; ^
1 G: h( q+ w0 k+ g5 S
  1. /* 重定向printf函数 */
    ; T& w" @1 z, x7 D& U( F- |) ]
  2. int fputc(int ch, FILE *f) . M. Q+ {" r, J0 Q0 j; W. M! n( Q
  3. {
    ( e4 C& \- K( P; Y4 S
  4.      USART_SendData(USART1, (uint8_t) ch);! O! T# T9 J9 q1 D
  5.      /* 等待发送完毕 */
    / f, |: d% O: E3 f+ F
  6.      while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    4 c( j2 q& n- [6 c  f
  7.      return ch;
    * b9 K; H3 k: k9 H
  8. }
复制代码
6 i$ F& V& ^2 O8 @9 w* u" n
同时也可以重定向scanf()函数接收字符串:% P6 ~; H& n& g/ z6 B
' l5 C' C% a* S% f
  1. int fgetc(FILE *f) 4 k! {, ]1 I2 r8 S
  2. { ! a) R* B; @4 f) O: b
  3.    /* 等待串口输入数据 */& a$ V( E0 t& \$ {" s0 G
  4.    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);3 f- P4 L5 H! x* n3 P
  5.    return (int)USART_ReceiveData(USART1);
    6 F" U* P" q9 B, M& ?# q1 Q7 ]
  6. }
复制代码
( \+ D' u9 m* h. N
————————————————
9 E, r; M4 m2 I% f" w3 F5 Z' r( g版权声明:云缙
: ~, v$ E4 |: h: E
+ b' [, Z! p% [( F( H) m5 |) ~% R
收藏 评论0 发布时间:2022-11-8 22:08

举报

0个回答

所属标签

相似分享

官网相关资源

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