两个51单片机之间进行串行通信

文章目录

  • 一、项目分析
  • 二、程序设计
  • 三、硬件设计
  • 四、功能实现展示
  • 总结

前言:利用a单片机按键按下发送数值给单片机b,b单片机收到对应的数值,来控制从单片机b的P1口,点亮对于的8位LED灯。

提示:本次博主都把软件和硬件全部介绍,也希望对大家有帮助,有什么好的意见或者建议,能告诉博主将会十分感激。


一、项目分析

两个单片机都使用串口方式1进行通信,并且必须保证两单片机通信波特率完全一致,否则接受不到正确的数。在发送数据时,向SBUF中写入一个数据后,使用 “while(!TI);” 等待是否发送完毕,因为当发送完毕后,TI被硬件置1,然后才退出 “while(!TI);” 接下来在将TI手动清零,同理,在接受数据时,在中断服务程序中也需要将接受中断标志位RI置零。

二、程序设计

a完成发送,b完成接收。编写程序设置a,令SM0=0,SM1=1(串行口工作方式1)。设置b,令SM0=0,SM1=1,REN=1,使接收允许。

(1)a单片机程序[数据发送程序]

#include 	//单片机头文件

//宏定义
#define uint unsigned int	
#define uchar unsigned char
	
//位声明
sbit k1=P2^0;
sbit k2=P2^1;
sbit k3=P2^2;
sbit k4=P2^3;
sbit k5=P2^4;
sbit k6=P2^5;
sbit k7=P2^6;
sbit k8=P2^7;

//函数声明
void Usart_Init(void);
void DelayMs(uint xms);
void Send_Data(uchar Key_val);
void Keyscan(void);

//主函数
void main()
{
	while(1)	//循环
	{
			Keyscan();
	}
}

//串口中断初始化
void Usart_Init(void)
{
    TMOD=0X20;//定时器1方式2
    TH1=0xF3;         //计数器初始值设置,注意波特率是4800
    TL1=0xF3;
    TR1=1;//打开定时器
    SM0=0;//设置串口工作方式
    SM1=1;
    EA=1;//打开总中断
    ES=1;//打开串口中断
}

//延时函数
void DelayMs(uint xms)
{   
	uchar i,j;                        
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}

//发送数据函数
void Send_Data(uchar Key_val)
{
    SBUF=Key_val;      //将要发送的数据存入发送缓冲器中
    while(!TI);        //若发送中断标志位没有置1(正在发送数据),就等待
    TI=0;              //若发送完成,TI自动置1,这里把它清零
}
 
//按键函数
void Keyscan(void)
{
	uchar Val;	//定义局部变量
	if(k1==0)		//如果按下k1
	{
		DelayMs(10);//消抖
		if(k1==0)	//确认按下k1
		{
				Usart_Init();	
				Val=0;
		}
		while(!k1);	//等待按键释放
		Send_Data(Val);	//发送“0”
	}
	if(k2==0)		//如果按下k2
	{
		DelayMs(10);//消抖
		if(k2==0)	//确认按下k2
		{
				Usart_Init();
				Val=1;
		}
		while(!k2);	//等待按键释放
		Send_Data(Val);	//发送“1”
	}
	if(k3==0)		//如果按下k3
	{
		DelayMs(10);//消抖
		if(k3==0)	//确认按下k3
		{
				Usart_Init();
				Val=2;	//发送“2”
		}
		while(!k3);	//等待按键释放
		Send_Data(Val);
	}
	if(k1==4)		//如果按下k4
	{
		DelayMs(10);//消抖
		if(k4==0)	//确认按下k4
		{
				Usart_Init();
				Val=3;	//发送“3”
		}
		while(!k4);	//等待按键释放
		Send_Data(Val);
	}
	if(k5==0)		//如果按下k5
	{
		DelayMs(10);//消抖
		if(k5==0)	//确认按下k5
		{
				Usart_Init();
				Val=4;
		}
		while(!k5);	//等待按键释放
		Send_Data(Val);	//发送“4”
	}
	if(k6==0)		//如果按下k6
	{
		DelayMs(10);//消抖
		if(k6==0)	//确认按下k6
		{
				Usart_Init();
				Val=5;
		}
		while(!k6);	//等待按键释放
		Send_Data(Val);	//发送“6”
	}
	if(k7==0)		//如果按下k7
	{
		DelayMs(10);//消抖
		if(k7==0)	//确认按下k7
		{
				Usart_Init();
				Val=6;
		}
		while(!k7);	//等待按键释放
		Send_Data(Val);	//发送“7”
	}
	if(k8==0)		//如果按下k8
	{
		DelayMs(10);//消抖
		if(k8==0)	//确认按下k8
		{
				Usart_Init();
				Val=7;
		}
		while(!k8);	//等待按键释放
		Send_Data(Val);	//发送“7”
	}
}

(2)b单片机程序[数据接收程序]

#include 	//单片机头文件

//宏定义
#define uint unsigned int
#define uchar unsigned char
     
//位声明
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;

//定义全局变量
uchar i;

//函数声明
void Uart_init();

//主函数
void main()
{
	Uart_init();        //串口初始化
	while(1);
}

//串口初始化函数
void Uart_init() 
{
	TMOD=0X20;//定时器1方式2
	TH1=0xF3;         //计数器初始值设置,注意波特率是4800
	TL1=0xF3;
	TR1=1;//打开定时器
	SM0=0;//设置串口工作方式
	SM1=1;
	REN=1;
	EA=1;//打开总中断
	ES=1;//打开串口中断
}

//串口中断服务函数
void uart() interrupt 4
{
	uchar receiveData;
	i=SBUF;                   
	 switch(i)
	{
		case 0:	//收到“0”
			led0=0;
			break;
		
		case 1:	//收到“1”
			led1=0;
			break;
		
		case 2:	//收到“2”
			led2=0;
			break;
		
		case 3:	//收到“3”
			led3=0;
			break;
		
		case 4:	//收到“4”
			led4=0;
			break;
		
		case 5:	//收到“5”
			led5=0;
			break;
		
		case 6:	//收到“6”
			led6=0;
			break;
		
		case 7:	//收到“7”
			led7=0;
			break;
		
		default:
			P2=0XFF;
			break;
	}
	receiveData=SBUF;        //出去接收到的数据
	RI=0;                    //清除接收中断标志位
}

三、硬件设计

a单片机与b单片机连线(把这两个程序分别烧写到两块板子上,然后用连接线分别连接两个板子的发送引脚和接收引脚。)

a单片机 → b单片机
TXD(P3.1) → RXD(P3.0)
RXD(P3.0) → TXD(P3.1)
GND → GND

四、功能实现展示

两个51单片机之间进行串行通信_第1张图片


总结

本次课程设计我主要研究的是单片机双机通信实验,使我学习到了最大的是51单片机的串口中断程序的编写,在实验中需要用到两个单片机作为主从机来控制信号的接受与发送。还学习到了单片机在使用中断的时候,如果有中断申请的话,硬件电路会自动把单片机里接受发送中断的TI和RI置1。虽然在这段时间里每天都那么繁忙,但是在这忙碌的过程中却得到了许多的收获。
坚持不一定成功,但放弃就一定失败!

你可能感兴趣的:(51单片机,单片机,串口通信)