找回密码
 注册
查看: 685|回复: 2
打印 上一主题 下一主题

单片机双机串口通信原理图,proteus仿真以及程序

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-1-8 13:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
单片机双机串口通信原理图,proteus仿真以及程序- \- @. s; D4 D& D
5 g. A2 j5 f. F% S. L
0 W! J/ Q( k1 _: d/ o# w. E
3 g6 l/ C1 F% d4 k4 H& u
给大家分享一个51单片机双机通信,用串口实现,有单片机主机程序和丛机程序的源代码。
3 j) H/ _( ~  f. d0 x& T
下面是proteus仿真原理图:
* G2 m2 G2 i  u- k4 V0 h 6 }8 ~5 Z/ N2 x2 M8 n$ w
  I, a- Z; l$ O' ~) W

3 ?7 n& _5 R! C) N; `主机程序:
6 C& ^4 d8 |& o" R0 X* \#include<reg51.h>
. P8 \( @; c" Xunsigned char i=1;
' A! K8 A3 B/ `! x( K: w+ funsigned char ACK=1;
/ i) e- ^9 ]; g  Xvoid delay()                               //延时函数
2 \4 W1 J; i! `8 g# C. ~' f# n$ p9 h{7 X  y! @6 V- I* K
   unsigned char i,j;
" y( v. N5 B* m4 l9 N' z   for(i=255;i>0;i--)
+ R0 M% M1 R. Q0 D7 k   for(j=100;j>0;j--){}
) B' n. y" z0 d+ F; u% P}7 b/ \9 c- _- S; I$ @2 G( _
unsigned char kbscan()          //键盘扫描函数+ X" U- Z- b2 [7 r) T) O
{: r+ C7 H- C, F% h
   unsigned char sccode,recode;  //定义行、列
- e/ g! o1 r3 t# `% U8 m) E# o0 ?! c   P1=0xf0;                       //高四位作为输入先写1
! w% \5 T+ n/ \" S   if((P1&0xf0)!=0xf0)                          //判断是否按键按下/ [# \( Z) N5 z! G9 w/ I
      {                                                
3 B9 C2 _1 l$ I1 b3 |3 [0 M            delay();                                  //延时消抖
) K; L; ]  Z" ?5 O! b* a0 d                if((P1&0xf0)!=0xf0)                  //再次判断判断有没有按键按下8 ~; {' R- `+ L; U( V
                  {
% N) ?" j/ e- X! U0 ^                    sccode=0xfe;! ]! h* Z4 s3 H, R, ~$ D: }
                    while((sccode&0x10)!=0)8 Z7 O4 V( T$ b/ O% ]
                         {
+ N" V" Q8 |. s0 P5 m5 @4 Y2 t                          P1=sccode;$ s3 P2 g  ^9 s/ M7 f
                          if((P1&0xf0)!=0xf0) //判断当前行是否有按键按下" H+ ^* a0 Y4 ~% _, s& }
                           {
$ r% ?: z9 \  y/ ?, L9 `                            recode=P1&0xf0;   //保留高四位输入值
+ S% ]3 Q, M, F* B                                sccode=sccode&0x0f; //保留第低四位的值5 T' e, I& v4 e
                                return(recode+sccode);8 S& O+ @6 W+ }
                           }3 h$ Y# T4 g5 u- N( Q% G
                           else4 \% x5 N( m: f4 q% n
                            sccode=(sccode<<1)|0x01;( \, e. @9 a1 j; R2 n$ k% ]
                         }
; M3 t0 w) v3 P7 }' D$ R                  }
8 g0 l/ A! R+ ^$ s          }
" s$ M7 O5 p, j$ T          return 0;" T+ d# D2 U" U  c  T
}
' J* F4 M7 n% K6 xsend()interrupt 4      //串行口通信中断, R# j- T. X8 U' x8 |  v' O
{; J% i; `) _- d( U
  if(TI==1&&ACK==1)
7 ?! u5 K  @0 ~4 c+ x  { . U( r. \- G- \7 f# h/ ?( S
    TI=0;3 H" b0 ]. |( d
    if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)                        //有按键按下,需要修改波特率
* `* a, _3 |9 s  y0 l3 X1 K    {
6 V" O& J! ]9 w; W, u/ h6 {' ]) |          ACK=0;0 S) C" ]3 @4 @. Y) u" G
          SBUF=i;                //发送数据/ H+ t0 B* ^2 D
        }
1 f1 ^! E3 k7 O4 Z: T4 d5 s    else if(i==11)                         //循环发送,发了十一个字符后重新发
  u$ H$ x7 j2 ~+ V& h        {5 y5 j& c( X5 F+ I  }+ |: a( E: z
       i=1;
2 a7 O5 s( q' M           SBUF=1;6 j8 s5 Y8 [* O6 V4 O, T- i
        }; _( h- W1 m! ^
        else
# c" U% w0 r3 x6 [        {& t2 B6 N& b7 y( K3 n
      i++;- z/ M/ j* Z8 f( q# u
      SBUF=i;                     //发送数据
& i" ]# ~8 W3 |/ @. F3 x) p* L2 w    }
. I+ ]9 j& ~; i/ ?  }
! P. \0 Q7 ?) P7 U9 |  else if(RI==1)                         //接收回应的信号+ Q- a' n& V8 X; T' a" x+ C: `
    {, r3 C* I, E9 x" M0 y# z
           RI=0;
8 k3 A# \1 [4 v  U9 |! G, l+ V& \           ACK=SBUF;                         //接收回应信号 修改初值 触发串口通信中断
8 `# z: O  l5 I# C9 i8 r           TI=1;2 `& H8 ?. n& j' \+ A1 X6 I- W
           TH1=TL1=i;
. V. U+ ^! m5 p& \, v# X           i=1;
$ u+ B: Q5 b9 k$ w        }
1 [. L4 n% ]! v" `! Y7 _5 [  P}
9 E3 z, Z! w! Z- P. ~1 Ivoid main()
, l& b5 N7 `9 P{
- o9 ?  N; F3 E6 P4 s: l# O8 ~  F  TMOD=0x20;
! h' i7 Z  [" V- t. i) b! U, c: Q  TH1=0x00;TL1=0x00;   //置初值
7 m; w5 J7 j- [  A+ {  TR1=1;EA=1;ES=1;    //使T1开始工作;开总中断、串行中断! Q3 P  q1 n* X
  SCON=0x50;          //使T1工作在工作方式1, \/ p+ X  Y- o& ]; U6 k1 b; L
  SBUF=i;    x" R: `" W$ K2 E: w+ {/ ^- C0 T
  while(1)- Q2 P* q2 x0 |( U* v
  {
" u2 x2 {# d/ [: Y" P/ j    while(kbscan())8 M# [0 t1 i% H2 V0 i
           {
; W8 t, E/ }0 n) ~            switch(kbscan())                                        //不同的按键对应不同的波特率4 |7 s# }& v/ W6 L) U2 Q6 \
                {2 O6 b/ f( \" `
            case 0xeb:i=0x00;break;
. d; R( C( V! H# n% S4 q                case 0xdb:i=0x22;break;
, G0 E/ i! b5 _, V5 R. h& ^                case 0xbb:i=0x44;break;
% J( P( {3 U( G5 ~6 `" R                case 0xed:i=0x66;break;
% q( d2 ^" J. W4 A                case 0xdd:i=0x88;break;
' D5 Z% r) ]* o5 [7 E                case 0xbd:i=0xaa;break;
2 D2 U1 v9 w% [+ \$ t7 ~+ }6 S5 T                case 0xee:i=0xcc;break;
% H' H  M2 t7 e                case 0xde:i=0xdd;break;& z4 D3 h+ {/ V/ ?
                case 0xbe:i=0xee;break;5 Z% K6 V. I) [; L" g, g
          }
9 v% l  A, p. U) i+ I8 K        }
$ U! r5 ^: G. V  }
" C) Z0 y0 E8 I7 C' i( W}3 o  c( {0 A6 V+ G9 \6 x

! W) ]' O3 @$ Z5 t3 j丛机程序:
. W5 e  X1 y+ ?8 ~1 e, p* M4 L#include<reg51.h>2 \- m' Y% l* B
#define LCD_DATA P0: X7 S2 A% n6 L0 G. t% Y- i
sbit LCD_BUSY=LCD_DATA^7;
. Q$ m& [) S: v0 a2 K$ J7 ysbit LCD_RW=P3^3;
0 n5 i' S6 ~& q* i, K2 `sbit LCD_RS=P3^2;4 g4 A+ \. ]1 c- V
sbit LCD_EN=P3^4;
' v, ^5 m( }  O1 \sbit P20=P2^0;" e1 K% J, f4 O4 [7 D" n6 L
sbit P21=P2^1;5 f2 s! W8 J* n( \! c0 P
sbit P22=P2^2;
) y5 X; m- M( r& K5 N1 xsbit P23=P2^3;* h1 m* P4 ]% F" p" j% s
sbit P24=P2^4;
& d* ^1 y) ?- H/ Csbit P25=P2^5;
. r# Z' S6 r6 Y% c1 C& W5 xsbit P26=P2^6;; Z8 g7 l7 i4 b( \
sbit P27=P2^7;% y+ e6 a1 Q' q) }4 u2 `
sbit P30=P3^0;, W0 A+ k0 u  _0 W) R/ m
sbit P31=P3^1;3 u' o* Y, {8 e
sbit P32=P3^2;& z6 ]3 k3 l  Q
sbit P33=P3^3;
( Y. i/ V2 n% K: h, L( K8 Wsbit P34=P3^4;
, H1 e- {, ^; ~/ K6 }8 |sbit P35=P3^5;
4 z7 e/ H3 @  M1 R- g6 [2 Dsbit P36=P3^6;
" |7 H$ e4 z2 _6 ysbit P37=P3^7;( G% }; v0 X! U; ^# e% V
unsigned char i=0;
5 `. w3 _- n' o& d- @' w- C7 ]% yvoid LCD_check_busy(void)        //检测LCD状态! R. t* A# C  g3 s0 o
{. O4 m2 _* ]1 n3 y9 P3 v; g
  while(1)6 C2 y+ }7 {$ Q1 \
  {
  K2 \# |) x' n0 V: L   3 ~2 o+ c. R# v( d$ o
   LCD_RS=0;
* g; W5 P" W, Z/ I   LCD_RW=1;
5 _% Z1 J! x2 \) ], H, L# O9 Y   LCD_EN=0;  ]) S, @0 D) p& N; {
   LCD_DATA=0xff;
0 O6 _' ]5 r9 U! j- y   LCD_EN=1;
* u* N5 k; ]6 `  P/ F   if(!LCD_BUSY)break;
1 o& W+ [: f# S, T1 N   LCD_EN=0;" r2 }0 b' }' E9 w
  }# r6 I5 Y7 N: `1 k9 n
}
  z6 ^! M) `, ~7 J9 J  Nvoid LCD_cls(void)  //LCD清屏
! b! W  D4 I7 R9 f) W( s{
; Q  Y: D0 D  Q2 I+ F0 t) _  LCD_check_busy();
) o+ K! e' A) a  LCD_EN=0;
# J, R5 i% t* t- \3 R  LCD_RS=0;2 f& U3 u7 |; t) W6 T+ a* P! k7 ]
  LCD_RW=0;' t: `( o/ V/ r: U
  LCD_DATA=0x01;
! c) f! V9 @& i. `$ v8 N  LCD_EN=1;
( \# N+ v. y) g$ k6 P! f  LCD_EN=0;
6 P5 B+ n" k7 v7 m; B% G$ ]}
8 N: c: o0 ?( `7 zvoid LCD_write_instruction(unsigned char LCD_instruction)//写指令到LCD* B* o6 Z: t- |2 M! h
{) M+ b% G: v7 w" u
LCD_check_busy();
+ |6 N5 x  V1 }# ~ LCD_EN=0;
5 [! n! m7 a9 n9 T LCD_RS=0;
3 p6 ]0 S5 [7 {9 F LCD_RW=0;2 I+ O- u2 y# @3 h
LCD_DATA=LCD_instruction;' z' `% k: n. i+ j$ N% q
LCD_EN=1;
/ y( F' d0 N4 e% Y LCD_EN=0;
; {6 Z. g  Z0 t. `; ?4 E}
5 ]; M- L2 s& N; ]; m+ [void LCD_write_data(unsigned char LCD_data)//输出一个字节数据到LCD
  A5 @( r* C0 B. U2 M: i! q{# _0 j  c! F+ N) W& f' L( J; Q5 ?
  LCD_check_busy();' W" `0 J+ t  ~) q: u
  LCD_EN=0;
7 f, u7 r2 Z: v% @1 c  LCD_RS=1;4 N, K: ]* S% F: r) Q
  LCD_RW=0;. [; v* d$ Z* {
  LCD_DATA=LCD_data;
& T. {. |. v# }  LCD_EN=1;( M- z. l% @" b$ m# X$ c7 B
  LCD_EN=0;
7 m/ e% ~% X5 i}
7 h, R* a9 H8 N  bvoid LCD_initial()2 S( U! f2 V; |6 o+ F- T' u
{
4 F! j; y2 w3 D. q: i) k; o   LCD_write_instruction(0x38);          //两行显示
& x5 P$ j1 }4 y   LCD_write_instruction(0x0C);                 //显示开
5 S  X7 g8 ^2 N4 c' X6 L& r% L1 F, o  n   LCD_write_instruction(0x06);             //光标加1
: r! C% G# U! Y- O& r$ ^2 V   LCD_write_instruction(0x01);                  //清屏0 a0 K2 p1 y3 v; R1 [! U
}
- W3 l, L: L6 ?) V6 Wre() interrupt 4                                   //串行口通信中断
3 j- \1 h) q# s7 V3 V{  F! A# j7 q* Y& x9 g; B; U
  if(RI==1)
( I% g  k. @3 ^5 i/ M! H0 L  {
) W8 T' ?* g6 x& f+ Y! @- j- h    RI=0;
3 w! `# _3 Q6 i    i=SBUF;                                                   // 接收数据! M0 G+ U1 e+ H
    if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)! `) c2 J7 C' ]0 ~
    {/ f' K9 W) ?) e/ D0 t2 g
          SBUF=1;                                           //接收发过来 要修改的初值
" |/ C3 k1 w/ t5 s        
1 l8 w# |( F8 Y$ L; J/ \    }9 m2 N5 W% k& w& ]
    else                                                   //接收正常通信的数据- X5 a6 r9 M$ m' Q& W
    {0 V" p; G% T# Q: `7 f5 s, d/ C
      LCD_write_instruction(0x80+i);% _8 P+ e& t7 ^
      LCD_write_data('0'+i); ' s' p' W' z4 b' y, ?6 |
      if(i==11)LCD_initial();
. Y& Q( Q/ O' h& T  H4 _. ^. @1 }    }
- U) M' {3 u$ k" W3 O* Q. p" a  }
- a; R( e. h' C; P/ {' B  else if(TI==1). X2 L* ~' R+ `
  {
" |5 I/ z  |. f& R    TI=0;
, c" A. f( s4 n9 W/ ?& |        TH1=i;TL1=i;                                 //发送确认信号后 修改初值: P+ G9 J" |; R% I" G+ u
  }; y* `; Q3 k( {8 R5 y( ^
}
. a, T! [7 U# r& `+ S" k; Y  _void main()
% j7 j6 s% E6 K1 @" O5 A6 P( z{
0 i* ~% E5 w! }  TMOD=0x20;4 p! M# H8 H5 D9 H4 G
  TH1=0x00;TL1=0x00;   //置初值
4 s9 Z+ m# {/ W- N/ Y5 a  TR1=1;EA=1;ES=1;    //使T1开始工作;开总中断、串行中断1 ~8 c1 i) @8 e& D' f* ^/ y0 O
  SCON=0x50;          //使T1工作在工作方式1
  b# J- H, H* b" B8 R3 ~…………限于本文篇幅 余下代码请从论坛下载附件…………! G9 p4 s2 W8 J% e# }+ ]
游客,如果您要查看本帖隐藏内容请回复
4 T; M% R* G# p: T

3 G# X5 G8 t+ @
  • TA的每日心情
    开心
    2019-11-20 15:05
  • 签到天数: 2 天

    [LV.1]初来乍到

    2#
    发表于 2019-1-8 15:51 | 只看该作者
    好东东,学习一下

    该用户从未签到

    3#
    发表于 2019-3-1 17:19 | 只看该作者
    看看楼主的原理图和代码
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-5-12 07:22 , Processed in 0.093750 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表