找回密码
 注册
关于网站域名变更的通知
查看: 725|回复: 2
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机双机串口通信原理图,proteus仿真以及程序( M# S2 U* S% W! B8 h! b& v

+ T2 D4 c2 p, q9 H% M9 |
1 D# C2 z# i2 h. z
, B+ z5 \/ ~  {6 I; n) ?; J给大家分享一个51单片机双机通信,用串口实现,有单片机主机程序和丛机程序的源代码。
. u* g! q3 p  {. q6 D( [
下面是proteus仿真原理图:) A" v: ~2 U& W1 w

4 ]: R/ V; |/ l6 r8 F% E; j* B7 J/ n

, O3 b% L; {3 w3 U6 A. I$ P; x9 K主机程序:5 I3 h: V: i0 n6 I- K8 p- O
#include<reg51.h>! W4 N* M, N, h
unsigned char i=1;
, d5 _% c! A0 l/ I% F; U+ t  }" i; r/ ]unsigned char ACK=1;% g! j9 x6 l3 K+ ^; [1 I
void delay()                               //延时函数2 j5 D9 m" s- x
{
" c) K2 \% I7 E* q   unsigned char i,j;4 N7 E% ~4 o; l4 m* y# x! u/ ]
   for(i=255;i>0;i--), B+ L5 _  c6 Z. x3 w- K1 C  |
   for(j=100;j>0;j--){}- h3 t0 o' F' t, y' Z
}% y7 s' ~( C5 a$ w  b3 |1 [9 }9 ]
unsigned char kbscan()          //键盘扫描函数: g, ?  u+ A* U
{; d6 b' j  _4 v/ E1 M
   unsigned char sccode,recode;  //定义行、列- k) w  Q0 y/ K# L( e! Q
   P1=0xf0;                       //高四位作为输入先写1
/ H  e. ~' M/ Y) y! `) d4 G   if((P1&0xf0)!=0xf0)                          //判断是否按键按下
2 \& I( C; T9 v) f- @9 ]& \/ I      {                                                
; |; {% X: J6 w2 e7 @            delay();                                  //延时消抖
- h' L9 k9 p0 A7 k  T                if((P1&0xf0)!=0xf0)                  //再次判断判断有没有按键按下
: d, U0 n! E6 {, z                  {* F0 g8 J# J/ @, W; F
                    sccode=0xfe;# C( m6 t, a" F
                    while((sccode&0x10)!=0)
, c9 I5 t% D; a' l( _2 O                         {1 F0 I. V3 k3 \2 D" O+ T
                          P1=sccode;! Z# C. m2 N7 c! P0 x
                          if((P1&0xf0)!=0xf0) //判断当前行是否有按键按下/ j8 ]& J- w6 \& i# M1 s
                           {
! t% E. h; R  a( [8 G# l                            recode=P1&0xf0;   //保留高四位输入值
" P5 c# t7 ]( G  o$ v                                sccode=sccode&0x0f; //保留第低四位的值: R: H7 H6 M4 V+ U0 D0 b& y) S
                                return(recode+sccode);
7 t: D! h" l2 `" ~. V6 A2 j                           }" N8 q4 `3 `# r$ D. d; y: f
                           else$ _/ a3 y0 h. o$ \9 C5 V/ M9 P! N
                            sccode=(sccode<<1)|0x01;& E6 c, }* D% Y5 _$ j5 H
                         }
  |& [2 Q7 V. c" h$ h+ Y                  }
/ |5 b! s. R. V          }
; m! A) d7 F" [          return 0;
$ y6 G" U3 [$ M2 h: B; Q9 @6 M  `}0 @- w& j. Z4 ^' m; T
send()interrupt 4      //串行口通信中断
- Z2 }1 R; T6 P( U7 N! o0 y{) K+ V$ ?9 [. E6 b+ I2 I
  if(TI==1&&ACK==1): d3 W$ G+ W7 v* }
  { 3 w2 X- a( G/ \& a* {
    TI=0;
4 b# Z. C6 o9 h    if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)                        //有按键按下,需要修改波特率. c! H: J; Q7 e, X0 `8 t
    {
7 A: h" b0 i/ x          ACK=0;  X( J/ a, m. J+ W8 \
          SBUF=i;                //发送数据! W$ H& r: d1 H' Y/ a
        }
) |$ r0 j' t9 I: J/ `7 f8 U6 ^1 X    else if(i==11)                         //循环发送,发了十一个字符后重新发1 r* M/ @4 Q( m5 J: l+ H, A1 J
        {! f; q" l& v6 l1 \
       i=1;
6 d' d! [0 ]% d/ P) z/ v           SBUF=1;
0 y3 s# N7 v1 Q" L: w/ R        }
( m9 v) J% _$ o        else
$ {5 N" B1 }3 r* N) T        {! B6 @5 R6 C! n% J3 N
      i++;
5 X" }* l. L7 y      SBUF=i;                     //发送数据* D1 K+ T6 t( u& n# H. @
    }0 E2 L$ l% B8 h$ n) J7 z) i; d
  }
) f* n9 T, P( {6 Q  else if(RI==1)                         //接收回应的信号5 z- d0 x$ I3 E2 w# `5 I' R
    {
. \. {! W  O2 q5 e. f5 h$ {% p           RI=0;7 Y0 m8 h/ M4 |" K- v# H* m2 b
           ACK=SBUF;                         //接收回应信号 修改初值 触发串口通信中断8 N, [! m2 a2 S, }
           TI=1;
* \  Q0 D" n9 o8 t0 N           TH1=TL1=i;
) V: C0 @7 o1 f           i=1;; T+ R5 Q3 e7 G4 R6 ?
        }
& [7 [/ R. Y2 Q2 ^1 y}8 A# W: D) P1 s9 I! K' P
void main()! g: @9 w2 H1 a0 j5 C! P3 U
{
* }( i4 w0 s/ M  TMOD=0x20;
* `8 o6 ?0 n/ P) [  TH1=0x00;TL1=0x00;   //置初值
$ ?) R6 s* G3 A  TR1=1;EA=1;ES=1;    //使T1开始工作;开总中断、串行中断' t. E5 ^3 {7 C3 r
  SCON=0x50;          //使T1工作在工作方式1- Y3 z0 S6 K. n( L% b
  SBUF=i;  
9 D6 T7 X& _- ?/ o% ]% E  while(1)
7 n. V& b/ M* ]% ?) v; `) K  {$ K2 ]; D% p# i3 F2 s# m/ @7 [
    while(kbscan())
6 l! H; S1 {( u/ e& t! C           {
, D) ]+ y& _" Q8 c/ i            switch(kbscan())                                        //不同的按键对应不同的波特率8 ?3 k5 @2 m" n6 P# ^
                {
1 F& S( R( w5 u- c( Q0 D            case 0xeb:i=0x00;break;
8 [& I5 e, N& M; G                case 0xdb:i=0x22;break;
4 S) {9 s, c2 M/ p5 s4 s                case 0xbb:i=0x44;break;
% q) q  U$ p# S                case 0xed:i=0x66;break;" y  Z$ J# K3 I6 y3 g9 P9 {! W
                case 0xdd:i=0x88;break;3 e. F# x2 N; p$ m! E1 V
                case 0xbd:i=0xaa;break;
* R' g+ c+ D4 _" o                case 0xee:i=0xcc;break;: w/ s+ L/ P4 w! k' J8 d
                case 0xde:i=0xdd;break;
. V: B6 b: v- X1 D5 e3 @                case 0xbe:i=0xee;break;: d: [5 J+ n+ ^' s
          }9 [! |, j* S2 S: [1 E
        }
6 u3 n1 O+ z* E- I; U  }6 M7 y6 p3 t/ B* s% m4 M6 [6 ^
}
0 |' M8 B) J% g: e9 l, T  M( q* Y4 E
丛机程序:" G8 t% i; {2 Q/ T. r! J
#include<reg51.h>
0 t5 _: S4 S! l) _4 f" B: O#define LCD_DATA P0
' Y. N2 B' m5 F  T; U" p& tsbit LCD_BUSY=LCD_DATA^7;
# \5 L' w" h. F, asbit LCD_RW=P3^3;
$ ~9 g2 E5 B' F0 K6 ~& gsbit LCD_RS=P3^2;
$ g8 h4 H, B7 }sbit LCD_EN=P3^4;
9 t/ I. v% e1 ?3 jsbit P20=P2^0;/ p! {! b9 ^0 k1 o8 B$ P0 f. b
sbit P21=P2^1;
' }* \: E8 B: e5 Wsbit P22=P2^2;
' q- k' {; j( ?- w+ E$ Nsbit P23=P2^3;, U3 E6 p# |/ d
sbit P24=P2^4;
8 y0 ~% `$ s7 X7 C5 y0 F+ fsbit P25=P2^5;; I3 u' f$ G2 ]3 p  H
sbit P26=P2^6;* b* ]+ _& M; J$ I. ~
sbit P27=P2^7;
1 ~0 x( c; o# w# I' ]: msbit P30=P3^0;
+ B8 }; S+ ^" w) v& T: q2 _( Tsbit P31=P3^1;. R5 V! m7 p8 ^0 |9 R6 I/ W
sbit P32=P3^2;6 ~( Z+ o+ v+ l9 }  i8 a" M8 C1 |
sbit P33=P3^3;: n9 u5 i' T. b9 U6 L
sbit P34=P3^4;- O: b" n! O6 j4 V1 i! x
sbit P35=P3^5;
8 `8 B0 r! u7 v; r8 S" z4 p& K7 Ksbit P36=P3^6;
# q9 G  E2 R3 M$ X- ]0 \5 [sbit P37=P3^7;; q2 M6 F+ e5 r" A( i
unsigned char i=0;* C# W% B. v3 h/ I# V1 d
void LCD_check_busy(void)        //检测LCD状态
7 P. z2 L( U6 z1 J{
7 e/ g% e5 v# L% |# D, z  while(1)/ @5 W1 h, ~, D& @
  {$ i$ i5 P; g' I. x
   
5 ~; `$ w: w* u0 I& K: R   LCD_RS=0;: W) J* K- T* R. X2 x* S& F" L
   LCD_RW=1;
& k* x* v: h: i( M8 i; [   LCD_EN=0;0 ~. ^5 d( I* A
   LCD_DATA=0xff;5 `$ o& b( f5 [3 W
   LCD_EN=1;
4 A7 k  g' C, t; t1 k   if(!LCD_BUSY)break;7 F+ q4 W6 \; ?
   LCD_EN=0;8 u+ D$ X' h6 c  q: W
  }+ G3 T% a' [6 ]- {6 C4 F/ {
}9 T/ U$ J9 j1 ]. `
void LCD_cls(void)  //LCD清屏# Y9 S% x; G& p& e. c; L
{
2 c) M3 M: l8 g1 I/ n( n7 U: r8 v; |  LCD_check_busy();
& m' m, y% b( [2 Z, d  LCD_EN=0;/ x) |9 n' n2 c0 P0 G% l9 N: @
  LCD_RS=0;
+ `, r* K, S. l! T1 q" E/ |  LCD_RW=0;
- s: v5 Y: Q( B+ s, f' W& ]9 z  LCD_DATA=0x01;0 i' s! T0 V# x1 W5 V) m
  LCD_EN=1;
/ P2 t/ h3 ^; m! t  LCD_EN=0;1 ?2 V! A1 G/ C5 M1 a$ l
}8 J) J. T# x; E% D( \$ l. }
void LCD_write_instruction(unsigned char LCD_instruction)//写指令到LCD# A; \- i! o; ^" V; C: x% A6 f
{) Z3 I0 x2 E. C, P& h! D
LCD_check_busy();( A3 a  G+ w, a  f7 n' V
LCD_EN=0;
! _7 o7 J% h1 C" V* e( }5 L7 r LCD_RS=0;
' J4 R+ f, T! k. f2 B, s5 ~7 ]) Q LCD_RW=0;
  v3 B2 q0 t, K5 d1 W LCD_DATA=LCD_instruction;
0 j  Y% s4 Z3 l& N9 h LCD_EN=1;
8 `& v: t2 X0 Z8 I LCD_EN=0;
% `/ Z7 p( I  K# u, b0 u2 A}
. ~3 Q" B" r7 W. lvoid LCD_write_data(unsigned char LCD_data)//输出一个字节数据到LCD
, W: v! f* f) w" B{
! G  }1 S9 U& [; W  LCD_check_busy();) u! P* b4 Q  v. p1 ~# k
  LCD_EN=0;$ t5 O3 F# B5 Z+ R5 M" U- Q( a. t
  LCD_RS=1;
5 Z2 {2 a$ _( _( J& d3 d  LCD_RW=0;) ~0 X8 n' S( q7 L; ?; A4 Q
  LCD_DATA=LCD_data;2 _: E& y9 X! u9 T, u3 r/ J% D
  LCD_EN=1;5 j8 [; A. s: }  N/ V/ Z! p
  LCD_EN=0;  m4 j8 B* N" w' V. B" P
}: ?8 P7 t  U! G# D- K% Y9 l# D
void LCD_initial()* a$ ?) {3 ?7 Z% T; ]
{
9 D( p% P& o$ c- ^1 a& r2 ^% z( D' {   LCD_write_instruction(0x38);          //两行显示/ m. `  ~7 b( G2 X
   LCD_write_instruction(0x0C);                 //显示开$ U5 m% }; n, B8 _9 V# H
   LCD_write_instruction(0x06);             //光标加1/ ~; Z' [- n7 h- o: W+ E  Z: n, _2 D
   LCD_write_instruction(0x01);                  //清屏. B' z. Y" I( O, G" x& x2 {
}6 j! {. h! S' f4 B" _
re() interrupt 4                                   //串行口通信中断! G, p( ~$ F; E9 ?: g
{
3 U0 V; k$ r+ l  if(RI==1)1 c  }1 Q! x# j/ G/ g* a
  {
2 U' P9 |$ {( z6 A+ s2 l+ b; e    RI=0;
7 g6 q. `2 n6 G) ^    i=SBUF;                                                   // 接收数据
9 `, E) Z0 ^/ o( j# M: l    if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)
( B, \" }8 V9 x: U. w    {3 N8 ]2 k4 {& b: d/ S. }
          SBUF=1;                                           //接收发过来 要修改的初值$ u, X: W5 j' t0 L
        ) n8 V% q& x# _
    }/ X9 \6 n8 C/ D
    else                                                   //接收正常通信的数据, c/ M; H+ L! a9 V- Z. Q
    {% ^2 q- y2 F, W
      LCD_write_instruction(0x80+i);
( n. O; d$ i5 y3 s) o) O      LCD_write_data('0'+i);
4 t, {7 Y0 O+ E* p      if(i==11)LCD_initial();
" l( Y' j2 A1 |0 ]9 l9 i    }
6 @6 I- t+ C& ~  }9 ~7 Z, @* E7 C# c, J
  else if(TI==1)* b1 W6 P. X+ a/ S( |! C3 P' U
  { % U5 P1 H; I, K$ R
    TI=0;
3 e, W: w: p% i1 G$ u$ G1 M        TH1=i;TL1=i;                                 //发送确认信号后 修改初值
+ |1 D& }/ h9 o  }0 g+ z7 a' c3 U8 b9 C3 a3 Y
}, P2 Y/ }( ]4 a
void main()
) N, w; e( w: A. Y  j- \* B  V{
! o/ `- ^2 a4 A  V+ J  TMOD=0x20;! l, G- E4 L3 ^8 y7 ~9 A( y
  TH1=0x00;TL1=0x00;   //置初值8 y( h+ v; H8 d0 y8 E
  TR1=1;EA=1;ES=1;    //使T1开始工作;开总中断、串行中断0 |9 e( X( }8 j
  SCON=0x50;          //使T1工作在工作方式1
# h8 t; h5 n4 s9 g8 N…………限于本文篇幅 余下代码请从论坛下载附件…………  f" X! @1 n: K/ d# s( ^
游客,如果您要查看本帖隐藏内容请回复
' s; P& Z# t, [, W  r

0 W+ ]+ T1 n) D& ?8 {( g
  • 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-8-16 08:01 , Processed in 0.125000 second(s), 26 queries , Gzip On.

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

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

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