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

【经验分享】STM32F103:I/O口模拟串口通信UART----延时法

[复制链接]
STMCU小助手 发布时间:2022-5-3 22:12
一、串口传输协议) m" y( h- Z+ W6 C) i6 V8 d
1. 传输方式

6 \/ K1 Y4 V( w! j# m串口通信的数据由发送设备通过自身的TXD接口传输到接收设备得RXD接口, 一个字符一个字符地传输,每个字符一位一位地传输,并且传输一个字符时,总是以“起始位”开始,以“停止位”结束,字符之间没有固定的时间间隔要求。! `. U1 ^: r5 L0 r9 r# C
0 b( i& u0 |# u
每一个字符的前面都有一位起始位(低电平),字符本身由8位数据位组成,接着字符后面是一位校验位(检验位可以是奇校验、偶校验或无校验位),最后是一位或一位半或二位停止位,停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。具体如下图所示。# K, B7 N+ x( X9 E* Y

3 U9 n! c! X9 }# G% L5 r实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率设置。. E& S5 ?* |# u
) h+ o0 B/ Z0 [+ Q8 z$ ^
20210617204832571.png 5 D( v/ A8 }8 L& ^7 U6 M( b8 V1 P: |

1 M; t; d- |; E! ^波特率
: h  k* F. v7 C+ ^. O  i波特率:每秒钟传输的数据位数(bit)。+ W! P( e& _2 ?  Q
波特率的单位是每秒比特数(bps),串口典型的传输波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps等。
8 \* E" F+ V  U1 f' F5 C8 V; ^以波特率9600bps为例:1秒钟传输9600位(bit)数据,所以传输1位(bit)数据需要1000000us/9600=104us。
7 H* S8 Z) }# q7 C2 o; m
' f& O, P! q) a, G) B6 O空闲位
/ ^. I1 d% t# `空闲位:处于逻辑“1”状态,高电平,每个字符之间都会有一段空闲位,表示当前线路上没有数据传输。2 p5 y( i# h7 P* N
4 [% [4 s  p! y9 C! {% u
起始位
! g# ~1 K( H1 _  W% m起始位:处于逻辑”0”状态,低电平,表示数据传输的开始。' \* t& w9 m- n" N+ z& b6 [

, @' d% }! d7 F数据位7 c3 E( F* f% A% ?: V; z  _
数据位:一般是8位数据位(低位在前,高位在后),传输有效数据。
9 [! _% A# p( K5 q$ V# ~
: Z. V' @3 {0 K3 z6 c9 i校验位
: l! [2 ^3 Y4 ^, V$ I( ]: p2 s校验位:校验方法有奇校验(odd)、偶校验(even)以及无(noparity),用来校验数据传送的正确性。9 c9 ]( }$ Y/ m9 }' E
$ F: y/ r" H' Y' V* F# n
停止位7 {8 z3 q' k2 l9 E8 ^
停止位:一个字符数据的结束标志,可以是1位、1.5位、2位的高电平,表示数据传输的结束。5 o% R) S( q- B0 b& Z

6 H4 ?- f# c4 `: ^/ v7 j二、I/O口模拟串口通信----延时法4 V& X2 j( I, J/ x5 `; L1 d
这次以波特率9600bps,1位起始位,8位数据位,无校验位,1位停止位的传输方式为例,实现模拟串口通信。
. w' E6 `' ?8 z& t" N0 ]具体程序如下:
: r( a! M2 f7 R1 F/ ]3 T
5 x# t3 L' H+ ^7 N# Q: G, Y& B! MUart1sim.c$ W. w8 n4 i1 M- g/ _5 I/ Y
  1. #include "Uart1sim.h"        
    6 Q! c5 U( W; p
  2. #include "delay.h"! k, Z  ^4 v+ T" ?

  3. ' e. H* h# l7 F2 W" P
  4. void Uart1sim_GPIO_Config(void)        //模拟串口引脚配置初始化: x) M$ A5 [/ h7 n- i
  5. {
    , o  [! r6 W$ W" w/ g6 s( Y+ ]
  6.   GPIO_InitTypeDef GPIO_InitStructure;5 ^8 |- Q" W1 O! c% R' h& ^. z0 R1 l
  7.   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PD端口时钟 - u) h/ a/ p$ Q9 B  r
  8.         
    & @4 }/ S, D% Z5 F# b
  9.         //UART1SIM_TX   PB.5* J; \( w2 s) Q; s, {, n, e1 |% v
  10.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;        ) Z( _6 N, r' i/ u) c8 n
  11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出   
    : S: G& a5 d; R8 T
  12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    . x! v8 Q4 R; ~( V0 M
  13.   GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PD端口
    9 ]/ n7 R9 D" _4 f% q
  14.   GPIO_ResetBits(GPIOB, GPIO_Pin_5);         
    : M+ {% q6 \1 T+ [( g
  15.         //UART1SIM_RX   PB.6! [. h! q6 g1 u7 z5 Y
  16.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    6 S- X: p; q; g  L
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    ( e$ W$ X: M" J) R9 `: n; b& x7 H
  18.   GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PA109 h/ p5 V. j; ]$ O
  19. }7 W7 O+ ]+ E/ e' o0 q, Q

  20. / _% G+ e, t+ Q4 m
  21. /*) ~! M$ z# [3 s( t, V
  22.         功能:模拟串口发送
    9 M4 S% O) U+ v# Q" Q
  23.         参数:data---要发送的数据
    ; h2 ]! ^  v& j: m; I
  24. */3 d3 u8 Z1 z: r/ D
  25. void Uart1sim_Txout(u8 data)                //模拟串口发送
      k3 \  a& i" t6 n" A4 S6 x# ]2 v
  26. {
    ! ?, e2 `& f# B. C& V
  27.           unsigned char i;0 X# v* v# h- g1 g% q
  28.           UART1SIM_TX(1);//空闲---高电平
    1 k9 w( J+ L5 s& X* F0 {9 s
  29.           delay_us(RATE9600); " E3 U3 }! @# q% K" l+ W
  30.           UART1SIM_TX(0);//起始位---低电平* L  D9 z; B0 X- n  ]# W8 y+ r: n
  31.           delay_us(RATE9600); 3 t, j9 w% O7 E! O/ J, J3 F
  32.           for(i=0x01;i!=0;i<<=1)//8位数据位
    + v4 s; `" i  X$ [9 P
  33.           {  J: s- R3 ~, I% }; x. J
  34.                 if(i&data) UART1SIM_TX(1);/ {$ v( I+ I& D. v8 f  ?9 `
  35.                 else       UART1SIM_TX(0);
    + p7 e  u- E; g" e
  36.                 delay_us(RATE9600); . f: x& a" D) l3 k. Z- a
  37.           }7 k' Q% O& G# [) Y$ B
  38.           UART1SIM_TX(1);//停止位---高电平1 ^# Y7 h, [- F
  39.           delay_us(RATE9600);
    # M) Y7 @2 U8 g4 r' Z' A% k
  40. }
    1 S$ Q9 r4 M2 J. Q# ?
  41. . o# b; d- q' C: K# b
  42. /*
    : N  s# M( q  |* U- \
  43.         功能:模拟串口接收
    ; S- }& v# J; `1 M) Y/ T* [6 f, O
  44.         参数:*data存储接收到数据的地址
    3 _: z7 m+ F7 b% q
  45.         返回值:1---接收,0---未接收
    5 _+ }8 p- S3 u8 d9 c
  46. */6 o. s( w' P. M. H* i8 x
  47. u8 Uart1sim_Rxout(u8* data)                //模拟串口接收9 J7 M9 J( F5 |3 a
  48. {  d& Q- {$ ]4 @( g2 F6 O
  49.         unsigned char i=0,Rxdata;+ K) Y2 U3 C* P
  50.         if(UART1SIM_RX==0)//起始位: L. Q9 o4 J, A) c% t
  51.         {
    4 N3 ^0 R2 M1 p4 [: K
  52.                 delay_us(RATE9600);# l3 f2 Q4 q1 s+ S# K; R
  53.                 for(i=0x01;i!=0;i<<=1)3 G, S5 `  ~6 w5 Q. v, C
  54.                 {2 n2 g& C/ h7 W+ F( ?3 n8 V
  55.                         if(UART1SIM_RX==1)         Rxdata|=i;
    % Q3 E2 J' b7 X/ H' X- J1 _2 f
  56.                         else                               Rxdata&=~i;
    / ~& {, W0 x, ~
  57.                         delay_us(RATE9600);
    ' C) p, X$ M  ?# W! S! ~
  58.                 }
    ' z! B; P4 z9 B4 r6 v# J
  59.                 *data=Rxdata;& j1 r) A% P  [# w5 R: X
  60.                 return 1;1 H2 \( i  u- c& ?; O
  61.          }
    + Y& z- P; Z, k9 A2 _0 d- k
  62.          return 0;
    $ z; n1 y" ~8 x, F, p7 |9 a! r0 V
  63. }
复制代码
+ `3 [! l5 L8 j1 y
Uart1sim.h8 @" ]+ x* C8 ^/ ^
  1. #ifndef __UART1SIM_H
    8 T7 i" F2 ~9 Z$ z: ~2 s  o
  2. #define __UART1SIM_H# t( i) x2 J* Z5 F/ W6 N

  3. 0 ]; z* f/ j% G: G: u2 R* X5 J- u& B
  4. #include "stm32f10x.h"
    ( f  [# e- r1 V( `5 r, E4 o$ w

  5. ) \6 g* t* l' v
  6. #define RATE9600 (1000000/9600)   //1s=1000ms=1000000us
    9 {, T' ~! j/ Z  V# q7 i
  7. : n/ Q- b$ Z: S& j% W. w1 M
  8. #define UART1SIM_RX          GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
    5 r8 A! T* V) w4 ?
  9. #define UART1SIM_TX(a)        if (a)        \) O1 g4 t* j! h" R$ r( E! G! N
  10.                                                 GPIO_SetBits(GPIOB,GPIO_Pin_5);\
      B& d- N# O8 m# T
  11.                                                 else    \$ n( U6 s. M! J0 q$ z2 R- }' [) J* B
  12.                                                 GPIO_ResetBits(GPIOB,GPIO_Pin_5)/ y- Y& s" \. Y- h. L! Y
  13.                                                                                 
    ' v2 Z9 w; D8 e& S( n
  14. void Uart1sim_GPIO_Config(void)        ;' B& w  u3 c8 r2 Y3 B# I0 C
  15. void Uart1sim_Txout(u8 data);
    + V; J. k! y' c1 g/ Q+ ?
  16. u8 Uart1sim_Rxout(u8* data);               
    ! p; z3 Z5 h& n0 U2 E: Z

  17. ! z, u0 I. L* Y2 ~
  18. #endif
复制代码

& j* X# q1 u, @: ]" M- Y6 k. I注意1: 利用延时的方法模拟串口通信,有一些弊端,当程序的中断时间过长的时候,收发都会有影响。2 g4 `6 P3 B' v5 x$ f' ~
注意2: 由于接收是引脚的低电平检测触发,当程序的运行周期过长的时候,有可能出现接收不到的现象。
1 d' H5 q1 y5 k/ ~; O4 g& l; J5 K( S& g' u! C+ b6 F

0 T. v  x5 {% o1 |7 U8 Z
赞 收藏 1 评论0 发布时间:2022-5-3 22:12

举报

0个回答

所属标签

相似技术帖

官网相关资源

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