51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真

51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真



实验内容

串口通讯实验,设计一个甲、乙、丙多机通信实验,甲机发送数据给乙机,乙机收到后反馈一个内容给甲机,甲机收到反馈内容再加上原来发送内容再发给到乙机,乙机收到信息,进行确认对比,内容正确就在显示终端显示相应内容,三个收发端都可以按照此方式收发。当甲机连续通过按键发送同一个内容三次,就对三个收发端的数码管清零。

从一个单片机发送5个给另一个单片机,另一个单片机接收到后完成数据相加,并通过数码管显示出来,要求所有数据为十进制格式。


一、实验一 多机串口通讯实验 数码管显示

1.仿真图

在这里插入图片描述

2.代码

#include<reg51.h>	

#define uchar unsigned char
	
unsigned char code str1[]="1";      //设置需要发送的协议代码
unsigned char code str2[]="2";
unsigned char code str3[]="3";

sbit P1_0=P1^0;                            //给相应端口一个编号
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit led0 = P1^6; // 作为主机,接收到从机反馈信号,显示
sbit led1 = P1^7; // 作为从机,接收到主机信号,显示
sbit key = P3^3; //主从机运行选择  按下时,无法通信

uchar temp,flag;
uchar a[10];
uchar count = 0;
uchar code table[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
 
//函数的功能是:向PC端发送一个字节数据
void send(unsigned char dat)
{
	SBUF=dat;
	while(TI==0);
	TI=0;
}

void delay(unsigned int n)                 //延时函数的设置
{
	unsigned int i,j;
	for(i=0;i<n;i++)
	  for(j=249;j>0;j--)
	  ;
}
 
void main(void)
{
	unsigned int i;
	TMOD=0x20;                //TMOD=0010 0000,设置定时器T1工作于方式二
	SCON=0x60;                //SCON=0100 0000,设置串口的工作方式为方式1
	PCON=0x00;                //PCON=0000 0000,波特率为9600 晶振为11.0592
	TH1=0xfd;                 //设置定时器T1的初值
	TL1=0xfd;                 //定时器T1自动填充的值
	TR1=1;                    //启动定时器T1
	
	REN=1;              //允许接收
	EA=1;               //开起总中断开关
	ES=1;               //需要用到串行口的中断所以ES=1就是把串行口的中断打开了
	
	EX1 = 1;		//INT1中断允许
	EA = 1;			//全局中断打开
	IT1 = 1;		//触发方式为下降沿触发
	
	led1 = 0;
	led0 = 0;
	while(1)
	{
	   if(P1_0==0)							   //判断P1_0口的开关状态 	U1->U2
	   {
	   		i=0;
				while(str1[i]!='\0')			   //循环发送相应数组中的数据
	   		{
	   			send(str1[i]);
					//P0=table[str1[i]];
					i++;
					delay(1);
	  		}
				send('\0');                     //最后一位补上\0作为接收机判断结束的标准
				delay(1000);
	   }
		 
//		if(key==0)
//		{
//			flag=0;
//		}
		if(flag==1)     //等待中断的来临,然后flag就会被赋值为1
		{
			if(P1_1==0 & P1_2==0)  // 同时按下按键2 与按键3 ,处于发送状态 否则处于接收状态
			{
					if(a[0]==0x32) 
					{												
						i=0;
						a[1] = str1[0];
						while(a[i] != '\0')			   
						{
							//p0 = 0x00;
							send(a[i]);
							//P0=table[a[i]];
							i++;
							delay(1);
						}
						send('\0');        //最后一位补上\0作为接收机判断结束的标准
						led0 = 1;
						delay(1000);                  
					}
			} 
			//处于接收状态
			else
			{	
				if(a[0]==0x31) 
				{												            
					i=0;
					while(str2[i]!='\0')			   
					{	
						send(str2[i]);
						i++;
						delay(1);
					}
					send('\0');                     
					led1 = 1;
					delay(1000);     
				}
				if(a[0]==0x32 && a[1]==0x31)
				{
					P0=table[2];
					delay(500);
					P0=table[1];
					delay(500);
				}
			}	
			flag=0;
			led0=0;
			led1=0;
			P0=0xff;
		}		 
	}	
}


void serial() interrupt 4            //设置中断函数
{
	temp=SBUF;                       //当有中断时把传过来的数据暂存到temp中
	RI=0;                            //把设置中断的标志初始化,等待下一中断
	if(temp==0x00)                   //当到达最后一位
	{
		a[count]=temp; 
		count=0;                     //计数器初始化为下一次中断准备
		flag=1;                      //标志置1进入主函数,进行端口的赋值
	}
	else
	{
	 	a[count]=temp;
		count=count+1;
	}
}


void jump_low()	 interrupt 2
{
	flag=0;  //无法进入串口中断
	delay(1000);
}

二、实验二 双机串口通讯实验 LCD显示

1.仿真图

在这里插入图片描述

2.代码

/** 功能描述: 甲机发数据!”**/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd_out P0

/***********端口定义********************************/
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;

sbit p10=P1^0;
sbit p11=P1^1;
sbit p12=P1^2;
sbit p13=P1^3;
sbit p14=P1^4;
sbit p15=P1^5;
sbit p16=P1^6;
sbit p17=P1^7;

sbit led=P3^7;
/***********函数申明***********************************/
void UART_Init(void);
void UART_SendData(uchar dat);
void UART_SendString(uchar *p);
void delay(uint j);

void check_busy(void);
void write_command(uchar com);
void write_data(uchar dat);
void LCD_initial(void);
void dis_char(uchar ad, uchar input);


void shaomiao(void);
void panduan(void);
void display1(void);
void display2(void);
/***********变量定义********************************/
uchar address=0x00;   //显示地址

uchar sting[]="0123456";

unsigned char code str[]="0123456789";

uchar code temp[]="0123456789";
uchar  temp1[8],mm[4],temp2[8];
float q;
uchar num,num1,k,r=0,n,h,d,w;
float  sum;
long uu;


void main(void)
{
    LCD_initial();			     //LCD1602 初始化
  	UART_Init();                 //串口初始化 
		led=0;
		while(1)
		{
			shaomiao();
			panduan();
//			UART_SendString(sting);	   //发送字符串
//			address=0x00;   //发送完数据 地址就归零 从头再来
//			delay(1000);
//			write_command(0x01);  //发送完一帧数据 清屏 	
    }
}

//串口初始化 
void UART_Init(void)
{
	SCON=0x50;
  TMOD=0x20;
	PCON=0x00;
  TH1 =0xf4;
	TL1 =0xf4;  //预置初值,设波特率为2400
	TR1 =1;	
 }

//串口发送一个字节的数据 
void UART_SendData(uchar dat)
{
	SBUF=dat;      //发送数据
	while(!TI);  //判断是否发送完
	TI=0;    //软件清0
	delay(100);
	dis_char(address++,dat);  //发送完一个数据 显示一个数据
	if(address==0x10) address=0x40;//显示完第一行 就显示第二行
	if(address==0x50){ 
     write_command(0x01);
	   address=0x00;//显示完第二行  清屏后又显示第一行
	 }
}

//串口发送多字节数据
void UART_SendString(uchar *p)
{
  while(*p!='\0')
  {
   UART_SendData(*p);
   p++;
  }
}

//1ms延时程序
void delay(uint j)
{
	uchar i=250;
	for(;j>0;j--)
	{
		while(--i);
		i=249;
		while(--i);
		i=250;
	}
}
查忙程序
//void check_busy(void)
//{
//	uchar dt;
//	do
//	{
//		dt=0xff;
//		e=0;
//		rs=0;	
//		rw=1;
//		e=1;
//		dt=lcd_out;
//	}while(dt&0x80);
//	e=0;
//}	
//写控制指令
void write_command(uchar com)
{
	//check_busy();
	e=0;
	rs=0;
	rw=0;
	lcd_out=com;
	e=1;
	_nop_();
	e=0;
	delay(1);
}
//写数据指令
void write_data(uchar dat)
{
	//check_busy();
	e=0;
	rs=1;
	rw=0;
	lcd_out=dat;
	e=1;
	_nop_();
	e=0;
	delay(1);	
}
//液晶屏初始化
void LCD_initial(void)
{
	write_command(0x38);//8位总线,双行显示,5X7的点阵字符
	write_command(0x0C);//开整体显示,光标关,无黑块
	write_command(0x06);//光标右移
	write_command(0x01);//清屏
	delay(1);
}

// 输出字符

void dis_char(uchar ad, uchar input)

{
	write_command(ad+0x80);//ad是显示位置信息
	write_data(input);
	delay(10);

}

void shaomiao()
{
  uchar i,s;
  for (i=0,s=0xfe;i<4;i++)
     {
	   P1=s;
	   if(p14==0|p15==0|p16==0|p17==0)
	     {
		   delay(10);
		   if(p14==0|p15==0|p16==0|p17==0)
		     {
            if(p14==0)
				  {
				    if(p10==0)
						{	num=7;
							UART_SendData(str[7]);
						}
					  if(p11==0)
					  {	num=4;
							UART_SendData(str[4]);}
					  if(p12==0)
					  {	num=1;
							UART_SendData(str[1]);
						}
					  if(p13==0)
					  num=10;
				  }			 
				if(p15==0)
				  {
				    if(p10==0)
					  {	num=8;
							UART_SendData(str[8]);
						}
					  if(p11==0)
					  {	num=5;
							UART_SendData(str[5]);
						}
					  if(p12==0)
					  {	num=2;
							UART_SendData(str[2]);
						}
					  if(p13==0)
					  {	num=0;
							UART_SendData(str[0]);
						}
				  }	
				if(p16==0)
				  {
				    if(p10==0)
					  {	num=9;
							UART_SendData(str[9]);
						}
					  if(p11==0)
					  {	num=6;
							UART_SendData(str[6]);
						}
					  if(p12==0)
					  {	num=3;
							UART_SendData(str[3]);
						}
					  if(p13==0)
					  num=11;
				  }
				if(p17==0)
				  {
				    if(p10==0)
					  num=15;
					  if(p11==0)
					  num=14;
					  if(p12==0)
					  num=13;
					  if(p13==0)
					  num=12;
				  }
			 while(p14==0|p15==0|p16==0|p17==0);	  	
			 }
		 if(num<10)
		  {
					k++;
          w=0;
		  }		  

   	if(d==1)
		 {
			 d=0;
			sum=-sum;
		 
		 }
		  
  }
   
   s=s<<1|0x01;
   s=s|0xf0;	 
 }  
} 

void display1()
{
 
	 uchar i;
	 uu=(long)(sum);
	 temp1[7]=uu/10000000;
	 temp1[6]=uu%10000000/1000000;
	 temp1[5]=uu%10000000%1000000/100000;
	 temp1[4]=uu%10000000%1000000%100000/10000;
	 temp1[3]=uu%10000000%1000000%100000%10000/1000;
	 temp1[2]=uu%10000000%1000000%100000%10000%1000/100;
	 temp1[1]=uu%10000000%1000000%100000%10000%1000%100/10;
	 temp1[0]=uu%10;
  
	  if(h==1)
		   {
		     h=2;
		   	 write_command(0x80+15-k);
			   write_data(0x2d);
		   } 
	  if(r==0)
			write_command(0x80+15);
	  if(r==1)
			write_command(0xc0+15);
			write_command(0x04);
	 for (i=0;i<k;i++)
		 {  
		   write_data(temp[temp1[i]]);
		   delay(5);
		 }
    
}
void display2()
{
	 uchar i;
	 temp2[7]=uu%10000000/1000000;
	 temp2[6]=uu%10000000%1000000/100000;
	 temp2[5]=uu%10000000%1000000%100000/10000;
	 temp2[4]=uu%10000000%1000000%100000%10000/1000;
	 temp2[2]=uu%10000000%1000000%100000%10000%1000/100;
	 temp2[1]=uu%10000000%1000000%100000%10000%1000%100/10;
	 temp2[0]=uu%10;
  
  
	  if(h==1)
		   {
		     h=2;
		   	 write_command(0x80+15-k-4);
				 write_data(0x2d);
		   } 
	  if(r==0)
			write_command(0x80+15);
	  if(r==1)
			write_command(0xc0+15);
			write_command(0x04);
		for (i=0;i<k+4;i++)
			 {  
				 
						if(i==3)
					 {
					 write_data(0x2e);
					 i++;
					 }	
					 write_data(temp[temp2[i]]);
					 delay(5);
			 }	 
}

void panduan()
{
    
    if(n==1&num==0)
     {
      write_command(0x01);
			write_command(0x80+15);
			write_data(temp[0]);
			k=0;
			n=0;
 
     }
	if(num==10)
		 {
		   write_command(0x01);
		   k=0;
		   n=0;
		   r=0;		
		 }
	if(n==1&num>=1&num<10)
		 {
		   write_command(0x01);
		   k=1;
		   n=0;
		   r=0;
		 }  
   if(num<10&k==1)
         {
	       sum=num;
	       mm[0]=num;
	       if(num==0)
	       k=0;
         }
   if(num<10&k==2)
	     {
	       sum=mm[0]*10+num; 
	       mm[1]=num;	  
	     }  
   if(num<10&k==3)
	     {
	       sum=mm[0]*100+mm[1]*10+num;
	       mm[2]=num; 
	     }
   if(num<10&k==4)
	     {
	       sum=mm[0]*1000+mm[1]*100+mm[2]*10+num;
	       mm[3]=num; 
	     }
   if(num<10&k==5)
	     {
	          
			num=10;
	     }
   
   if (num>=12&num<16)
         {
		   
   	     r=1;
	       k=0;
	       q=sum;
		    
		if(num==12)
		    {
			  write_command(0xc0);
			  write_data(0x2b);
			 }
	  if(num==13)
		     {
			  write_command(0xc0);
			  write_data(0x2d);
			 }
		if(num==14)
		     {
			  write_command(0xc0);
			  write_data(0x2a);
			 }
		if(num==15)
		     {
			  write_command(0xc0);
			  write_data(0xfd);
			 }
		    num1=num;
				n=0;
       }

   if(num==11&w==0)
	{
			w=1;
			n=1;
			r=0;	 
			num=16;  
			write_command(0x01); 
			if(num1==12)	     
			sum=q+sum;
			if(num1==13) 	        
				 sum=q-sum;	 
			if(num1==14)
			sum=q*sum;
			if(num1==15)
				sum=q/sum;	   
			
			if(sum>=0)
				h=0;
			else
			 {
			 h=1;
			 sum=-sum;
			 d=1;
			 }
				if(sum<100000000)
			 k=8;
			if(sum<10000000)
			 k=7;
			if(sum<1000000)
			 k=6;
			if(sum<100000)
			 k=5;
			if(sum<10000)
			 k=4;
			if(sum<1000)
			 k=3;
			if(sum<100)
			 k=2;  
			if(sum<10)
			 k=1; 
	
	if(sum!=(long)(sum))
	  {
	  	uu=sum*10000;
	  
	    display2();
	 	
	  } 

  }   
if(sum==(long)(sum)) 
  	display1();	 
 			 
}		 


总结

大佬们,可以支持一下。谢谢!!!
实验一 多机串口通讯实验 数码管显示
实验二 双机串口通讯实验 LCD显示

  • 19
    点赞
  • 198
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

眰恦I

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值