51单片机 | 串口通信实验(模拟串口通信/多机通信实例)
51单片机原理及应用(陈海宴)第七章实验
————————————————————————————————————————————
实验7.4:RS232串口应用实例
设计要求:
通过串口发送接收数据(串口工作方式1)
实现思路:
- 定时器设置
-
串口设置
- 工作方式
- 波特率
- 开启定时/计数器
-
串口执行
- 接收数据
- 发送数据
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
实现代码:
- 1 #include <reg51.h>
- 2 main()
- 3 {
- 4 TMOD = 0x20;
- 5 SM0 = 0;
- 6 SM1 = 1;
- 7 REN = 1;
- 8 PCON = 0;
- 9 TH1 = 0xFD; //253=256-(1*11.0592*10^6)/(384*9600)
- 10 TL1 = 0xFD;
- 11 TR1 = 1;
- 12 P1 = SBUF;
- 13 while(!RI);
- 14 RI = 0;
- 15 SBUF = P1;
- 16 while(!TI);
- 17 TI = 0;
- 18 }
————————————————————————————————————————————
实验7.5:MAX487多机通信应用实例
设计要求:
在主从3个单片机中进行双机通信,当从机显示的数字和主机相同,则表示该主机和从机正在通信。按下主机按键切换当前对象。
实现思路:
-
主机端
在主机中设置定时器和串口参数,并一直保持发送数据的状态。
通过MAX487芯片将3个单片机连接,并通过设置/RE、DE管脚控制单片机输入输出状态。
需要按下主机按键时检测按键状态,切换当前对象,设置中断,并标记此时状态是从机1或从机2。
//中断发生时按照中断优先级,主机先执行cort++并发送信息,主机中断结束后才进入从机中断。
如果是从机1,输出状态下发送对应数字,输入状态下设置单片机通信(非多机通信)接收并显示对应数字,重置输出状态。从机2同理。
-
从机端
设置与主机相同的串口参数和定时器和默认显示值。允许接收中断
当按键被按下,判断主机要通信的是否是自己,是则显示对应数字并向主机发送数字,否则重置状态。
执行流程:(多机通信模式)
- 主机
- 从机
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
实现代码:SM2=1,多机通信模式!
-
主机
- 1 #include <reg51.h>
- 2 #include <intrins.h>
- 3 unsigned char cort = 0;
- 4 sbit P3_5 = P3 ^ 5;
- 5 key_serial() interrupt 0 using 1
- 6 {
- 7 ++cort;
- 8 if (cort == 3)
- 9 cort = 1;
- 10 }
- 11 void main()
- 12 {
- 13 P2 = 0xff;
- 14 TMOD = 0x20;
- 15 TH1 = 0xFD;
- 16 TL1 = 0xFD;
- 17 PCON = 0x00;
- 18 TR1 = 1;
- 19 SCON = 0xF8;
- 20 EA = 1;
- 21 EX0 = 1;
- 22 IT0 = 1;
- 23 P3_5 = 1;
- 24 while(1)
- 25 {
- 26 if (cort == 1)
- 27 {
- 28 SBUF = 0x01;
- 29 while(TI != 1);
- 30 TI = 0;
- 31 P3_5 = 0;
- 32 RB8 = 1;
- 33 while(RI != 1);
- 34 RI = 0;
- 35 P2 = SBUF;
- 36 P3_5 = 1;
- 37 }
- 38 if(cort == 2)
- 39 {
- 40 SBUF = 0x02;
- 41 while(TI != 1);
- 42 TI = 0;
- 43 P3_5 = 0;
- 44 RB8 = 1;
- 45 while(RI != 1);
- 46 RI = 0;
- 47 P2 = SBUF;
- 48 SM2 = 1;
- 49 P3_5 = 1;
- 50 }
- 51
- 52 }
- 53 }
-
从机1
- 1 #include <reg51.h>
- 2 #include <intrins.h>
- 3 sbit P3_5 = P3 ^ 5;
- 4 void serial(void) interrupt 4 using 1
- 5 {
- 6 ES = 0;
- 7 RI = 0;
- 8 if (SBUF == 0x01)
- 9 {
- 10 P3_5 = 1;
- 11 RI = 0;
- 12 TB8 = 1;
- 13 P1 = 0x10;
- 14 SBUF = 0x10;
- 15 while(!TI);
- 16 TI = 0;
- 17 }
- 18 else P1 = 0;
- 19 P3_5 = 0;
- 20 ES = 1;
- 21 }
- 22 void main()
- 23 {
- 24 P1 = 0x00;
- 25 TMOD = 0x20;
- 26 TH1 = 0xFD;
- 27 TL1 = 0xFD;
- 28 PCON = 0x00;
- 29 TR1 = 1;
- 30 SCON = 0xF0;
- 31 EA = 1;
- 32 ES = 1;
- 33 P3_5 = 0;
- 34 while(1)
- 35 _nop_();
- 36 }
-
从机2
- 1 #include <reg51.h>
- 2 #include <intrins.h>
- 3 sbit P3_5 = P3 ^ 5;
- 4 void serial() interrupt 4 using 1
- 5 {
- 6 ES = 0;
- 7 RI = 0;
- 8 if (SBUF == 0x02)
- 9 {
- 10 P3_5 = 1;
- 11 RI = 0;
- 12 TB8 = 1;
- 13 P1 = 0x20;
- 14 SBUF = 0x20;
- 15 while(!TI);
- 16 TI = 0;
- 17 }
- 18 else P1 = 0;
- 19 P3_5 = 0;
- 20 ES = 1;
- 21 }
- 22 void main()
- 23 {
- 24 P1 = 0x00;
- 25 TMOD = 0x20;
- 26 TH1 = 0xFD;
- 27 TL1 = 0xFD;
- 28 PCON = 0x00;
- 29 TR1 = 1;
- 30 SCON = 0xF0;
- 31 EA = 1;
- 32 ES = 1;
- 33 P3_5 = 0;
- 34 while(1)
- 35 _nop_();
- 36 }
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
实现代码:SM2=0,单机通信模式!
-
主机
- 1 #include <reg52.h>
- 2 unsigned char cort = 0;
- 3 sbit P3_5 = P3 ^ 5;
- 4 void key_serial() interrupt 0 using 1
- 5 {
- 6 ++cort;
- 7 }
- 8 void main()
- 9 {
- 10 P2 = 0x0f;
- 11 TMOD = 0x20;
- 12 TH1 = 0xFD;
- 13 TL1 = 0xFD;
- 14 PCON = 0x00;
- 15 TR1 = 1;
- 16 SCON = 0xD0;
- 17 EA = 1;
- 18 EX0 = 1;
- 19 IT0 = 1;
- 20 P3_5 = 1;
- 21 while(1)
- 22 {
- 23 if (cort == 1)
- 24 {
- 25 SBUF = 0x01;
- 26 while(!TI);
- 27 TI = 0;
- 28 P3_5 = 0;
- 29 while(!RI);
- 30 RI = 0;
- 31 P2 = SBUF;
- 32 P3_5 = 1;
- 33 }
- 34 if(cort == 2)
- 35 {
- 36 SBUF = 0x02;
- 37 while(!TI);
- 38 TI = 0;
- 39 P3_5 = 0;
- 40 while(!RI);
- 41 RI = 0;
- 42 P2 = SBUF;
- 43 P3_5 = 1;
- 44 }
- 45 if (cort == 3)
- 46 cort = 1;
- 47 }
- 48 }
-
从机1
- 1 #include <reg51.h>
- 2 #include <intrins.h>
- 3 sbit P3_5 = P3 ^ 5;
- 4 void serial(void) interrupt 4 using 1
- 5 {
- 6 ES = 0;
- 7 RI = 0;
- 8 P2 = SBUF;
- 9 if (SBUF == 0x01)
- 10 {
- 11 P3_5 = 1;
- 12 P1 = 0x10;
- 13 SBUF = 0x30;
- 14 while(!TI);
- 15 TI = 0;
- 16 }
- 17 else P1 = 0;
- 18 P3_5 = 0;
- 19 ES = 1;
- 20 }
- 21 void main()
- 22 {
- 23 P1 = 0x00;
- 24 TMOD = 0x20;
- 25 TH1 = 0xFD;
- 26 TL1 = 0xFD;
- 27 PCON = 0x00;
- 28 TR1 = 1;
- 29 SCON = 0xD0;
- 30 EA = 1;
- 31 ES = 1;
- 32 P3_5 = 0;
- 33 while(1)
- 34 _nop_();
- 35 }
- 从机2:略
————————————————————————————————————————————
关于该实验在多机通信和单机通信下不同情况的讨论
-
在单机通信模式下,SM2 == 0,
初始化:SCON = D0;
发送完毕:TI=0;
接收完毕:RI=0;
中断触发条件:RI=0且SM2=0,RI置位
此情况下,发送和接收信息结束后需要对RI和TI手动置为0即可。
-
在多机通信模式下,SM2在0和1之间调整
初始化:主机:SCON = F8;从机:SCON = F0;
中断触发条件:接收到的第九位RB9==1,RI置位(如果RB8=0,RI就会等于0,就不能进入接收中断,自然丢失信息了。)
-
51单片机原理及应用(陈海宴)书P129案例是在主机发送状态下使用多机通信,接收状态下使用单机通信,在理解上容易出现错误,过程分析及代码如下:
实现代码:
-
主机:
- 1 #include <reg51.h>
- 2 #include <intrins.h>
- 3 unsigned char cort = 0;
- 4 sbit P3_5 = P3 ^ 5;
- 5 key_serial() interrupt 0 using 1
- 6 {
- 7 ++cort;
- 8 }
- 9 void main()
- 10 {
- 11 P2 = 0xff;
- 12 TMOD = 0x20;
- 13 TH1 = 0xFD;
- 14 TL1 = 0xFD;
- 15 PCON = 0x00;
- 16 TR1 = 1;
- 17 SCON = 0xF8;
- 18 EA = 1;
- 19 EX0 = 1;
- 20 IT0 = 1;
- 21 P3_5 = 1;
- 22 while(1)
- 23 {
- 24 if (cort == 1)
- 25 {
- 26 SBUF = 0x01;
- 27 while(TI != 1);
- 28 TI = 0;
- 29 P3_5 = 0;
- 30 SM2 = 0;
- 31 while(RI != 1);
- 32 RI = 0;
- 33 P2 = SBUF;
- 34 SM2 = 1;
- 35 P3_5 = 1;
- 36 }
- 37 if(cort == 2)
- 38 {
- 39 SBUF = 0x02;
- 40 while(TI != 1);
- 41 TI = 0;
- 42 P3_5 = 0;
- 43 SM2 = 0;
- 44 while(RI != 1);
- 45 RI = 0;
- 46 P2 = SBUF;
- 47 SM2 = 1;
- 48 P3_5 = 1;
- 49 }
- 50 if (cort == 3)
- 51 cort = 1;
- 52 SM2 = 1;
- 53 }
- 54 }
-
从机1:
- 1 #include <reg51.h>
- 2 #include <intrins.h>
- 3 sbit P3_5 = P3 ^ 5;
- 4 void serial(void) interrupt 4 using 1
- 5 {
- 6 ES = 0;
- 7 RI = 0;
- 8 if (SBUF == 0x01)
- 9 {
- 10 P3_5 = 1;
- 11 SM2 = 0;
- 12 P1 = 0x10;
- 13 SBUF = 0x10;
- 14 while(!TI);
- 15 TI = 0;
- 16 }
- 17 else P1 = 0;
- 18 SM2 = 1;
- 19 P3_5 = 0;
- 20 ES = 1;
- 21 }
- 22 void main()
- 23 {
- 24 P1 = 0x00;
- 25 TMOD = 0x20;
- 26 TH1 = 0xFD;
- 27 TL1 = 0xFD;
- 28 PCON = 0x00;
- 29 TR1 = 1;
- 30 SCON = 0xF0;
- 31 EA = 1;
- 32 ES = 1;
- 33 P3_5 = 0;
- 34 while(1)
- 35 _nop_();
- 36 }
- 从机2:略
-