当前位置:网站首页>甲、乙机之间采用方式 1 双向串行通信,具体要求如下: (1)甲机的 k1 按键可通过串行口控制乙机的 LEDI 点亮、LED2 灭,甲机的 k2 按键控制 乙机的 LED1

甲、乙机之间采用方式 1 双向串行通信,具体要求如下: (1)甲机的 k1 按键可通过串行口控制乙机的 LEDI 点亮、LED2 灭,甲机的 k2 按键控制 乙机的 LED1

2022-07-06 09:20:00 axu_990707

(原创)Proteus 虚拟仿真。甲、乙机之间采用方式 1 双向串行通信,具体要求如下:

(1)甲机的 k1 按键可通过串行口控制乙机的 LEDI 点亮、LED2 灭,甲机的 k2 按键控制乙机的 LED1 灭、LED2 点亮,甲机的 k3 按键控制乙机的 LED1和 LED2 全亮。

(2)乙机的 K4 按键可控制串行口向甲机发送 k4按键接下的次数,并显示在甲机 P0 口的数码管上。

【附上本实验的全部资源链接(代码+仿真文件)

点击前往下载

仿真图

在这里插入图片描述

以下是实验代码(分甲乙两机程序 不会编写请移步资源下载 里边是全部代码和仿真文件)

//甲机
#include<reg51.h>
unsigned char j=10;
char sign=1;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
void delay(unsigned char k){
    
	unsigned char i,j,h;
	for(h=0;h<k;h++){
    
		for(i=0;i<25;i++){
    
			for(j=0;j<20;j++);
		}
	}
}
void twoDigitDisplay(unsigned char num,unsigned char time,unsigned char portNumber){
    
	unsigned char box[] = {
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};
	unsigned char k;
	if(portNumber==0){
    
		if(num<0||num>99||time<0){
    
			for(k=0;k<40;k++){
    
				P2=0x00;
			}	
		}else{
    		
			for(k=0;k<time;k++){
    
				unsigned char numR = num%10;
				unsigned char numL = num/10;
				P2=0x11;
				P0=box[numL];
				delay(12);
				P2=0x22;
				P0=box[numR];
				delay(12);
			}
		}
	}	
}
void main(){
    
	unsigned char sum=0;
	TR0=1;
	EA=1;
	ET0=1;
	TMOD=0x21;
	TH0=0xee;
	TL0=0x00;
	
	while(1){
    
		if(sign==1){
    
			//执行数据发送
			TR1=1;
			TMOD=0x20;
			TL1=0xfd;
			TH1=0xfd;
			SCON=0x40;
			PCON=0x00;
		}
		while(sign==1){
    
			//发送数据SBUF
			if(P10==0){
    SBUF=0xfe;while(TI==0);TI=0;continue;}				
			if(P11==0){
    SBUF=0xfd;while(TI==0);TI=0;continue;}				
			if(P12==0){
    SBUF=0xfc;while(TI==0);TI=0;continue;}				
			SBUF=0xff;
		}
		if(sign==-1){
    
			//执行数据接收
			TR1=1;
			TL1=0xfd;
			TH1=0xfd;
			SCON=0x50;
			PCON=0x00;
		}
		while(sign==-1){
    
			//接收数据SBUF
			if(SBUF==0xf0){
    
				sum++;
				twoDigitDisplay(sum,5,0);
			}
			if(SBUF==0x0f){
    
				twoDigitDisplay(sum,5,0);
			}
		}
	}
}
void int0() interrupt 1 {
    
	j--;
	if(j==0){
    
		TF0=0;
		TH0=0xee;
		TL0=0x00;
		sign=sign*(-1);			
		j=10;					
	}	
}
//乙机
#include<reg51.h>
unsigned char j=10;
char sign=1;
sbit P10=P1^0;
void main(){
    
	unsigned char increment=0;
	TR0=1;
	EA=1;
	ET0=1;
	TMOD=0x21;
	TH0=0xee;
	TL0=0x00;
	if(sign==1){
    
		//执行数据接收
		TR1=1;
		TL1=0xfd;
		TH1=0xfd;
		TMOD=0x20;
		SCON=0x50;
		PCON=0x00;
	}
	while(sign==1){
    
		//接收数据SBUF
		P2=SBUF;
	}
	if(sign==-1){
    
		//执行数据发送
		TR1=1;
		TL1=0xfd;
		TH1=0xfd;
		SCON=0x40;
		PCON=0x00;
	}
	while(sign==-1){
    
		//发送数据SBUF
		if(P10==0){
    
			SBUF=0xf0;
			while(TI==0);TI=0;
		}else{
    
			SBUF=0x0f;
			while(TI==0);TI=0;
		}
	}
}
void int0() interrupt 1 {
    
	j--;
	if(j==0){
    
		TF0=0;
		TH0=0xee;
		TL0=0x00;
		sign=sign*(-1);			
		j=10;					
	}	
}

实验心得

1.程序的核心思想

本程序采用定时中断it0 定时,每隔50ms两机转换一次接收和发送状态。甲机开始默认执行发送,乙机默认接收。双机定时一致,到了时间后甲机由发送转为接收。乙机由接收转为发送。这样可保证双机步调完全相反。但推测:采用这样的方法,机器长时间运行,双机步调将逐渐不协调。达不到长期使用的目的。

① 甲机发送数据:甲机发送的数据SBUF由P1端口的三个开关的状态控制,交由乙机接收。
② 乙机接收数据:乙机接收甲机传送的SBUF,对其进行选择判断,从而让甲机P0端口的LED灯展示不同的效果。
③ 乙机发送数据:乙机在每次执行发送任务时,都会向甲机发送一个0xf0或者0x0f,默认为0xf0但当乙机的p10端口按钮按下时,乙机就会发送另外一个数据0x0f,交付甲机。
④ 甲机接收数据:甲机根据乙机穿来的数据SBUF的值作出判断。如果是0x0f, sum变量自增一然后用twoDigitDisplay(sum,5,0) 函数进行显示。如果是0xf0 ,sum变量值不增,直接交给twoDigitDisplay(sum,5,0) 函数显示。

2.实验中遇到的问题

由于编程较为匆忙,实验未将switch替换成button,导致开关k1到k3按下时必须手动断开才能进行下次状态的切换。而且数码管显数会有微小的闪烁,推测延时函数delay参数设置存在问题。
感兴趣的朋友可以继续改进,欢迎与我交流。

本文完全原创 请尊重劳动果实 欢迎转发 点赞 不定时更新更多单片机实验内容。

最后附上本实验的全部资源链接(代码+仿真文件)

点击前往下载

原网站

版权声明
本文为[axu_990707]所创,转载请带上原文链接,感谢
https://blog.csdn.net/axu_990707/article/details/124761018