51单片机双机通信

对于这个51单片机双机通信,之前无聊做的玩的,但是既然写了一篇51单片机串行口通信的博客,那就顺便出来供大家学习,希望能够帮助到一些刚刚接触51单片机的朋友。废话不多讲,直接上正题。

1、实习任务

1.1 任务目的

通过单片机之间的双机通信设计,进一步学习定时器的功能和编程使用,理解穿行通信与并行通信两种通信方式的异同,掌握串行通信的重要指标:字符帧和波特率,初步了解MCS-51系列单片机串行口的使用方法。

1.2 任务要求

本任务是建立一个简单的单片机串行口双机通信测试系统。系统中,发射与接收各用一套STC89C51单片机电路,成为甲机和乙机。编制程序,使甲、乙双方能够进行串行通信。要求:将甲机内的多个数据(例如1,3,4,6,7,5共六个数据)发送个乙机,并在乙机的六个数码管上显示出来。

2、系统总体设计

2.1 设计思路

STC89C52单片机双机通信可以采用串口通信的方式。首先要确定串口通信的参数,包括波特率、数据位、停止位和校验位。编写发送程序和接收程序,可以使用C语言编写程序,在发送端将要传输的数据存储在发送缓冲区中,然后根据协议依次发送每个字节。在接收端收到数据后,根据协议依次读取每个字节并存储到接收缓冲区中。使用定时器或者外部终端等方式实现异步通信。可以在发送端通过定时器产生中断来发送数据,而在接收端通过外部中断的方式接收数据。实现数据的校验,为保证数据的完整性和正确性,可以使用校验位、CRC等方式实现数据校验。进行调试和测试,设计完成后,可以通过实际测试来验证通信的可靠性和稳定性,针对不同情况进行调整和优化。需要注意的是,在进行STC89C52单片机双机通信时,应根据具体实际情况进行选择和调整,比如要考虑到硬件电路的设计和外界干扰等因素,保证通信的稳定和可靠性。

2.2 设计结构框图

3、51单片机双机通信原理图、仿真图及实物图

3.1 原理图

原理图的组成是:两个51单片机最小系统,还有一个按键及一个数码管显示。至于51最小系统的知识,我已经在前面的博客讲解过了,不懂得朋友可以翻看我之前的博客的。这里没有画USB转TTL下载模块,由于资源有限,就只能在开发板上下载好程序之后再把芯片拿出来放到自己制作的手工电路板了。

3.2 仿真图

没有允许仿真如下图:

仿真图也是很简单的。

开始的时候乙机数码管初始化为0。按一下按键就送发1,后面相应的发送2、3、4、5、6、7、8、9,然后又从0开始发。

3.3 实物图

上图是发送数据0的现象。

上图是发送数据9的现象。

4、程序

甲机(主机)是属于发送机,按键发送数据;乙机(从机)属于接收机,接收后数码管显示出甲机(主机)发送个数据。 甲机(主机)只发不接,乙机(从机)只接不发。

甲机(主机)

main.c

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "UART.h"
sbit KEY = P1^7;//按键口
unsigned char flag;
unsigned char count;
unsigned char DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void main()
{
	P2=0xc0;
	UartInit();		
	while(1)
	{	
		P2=DSY_CODE[count];	
		if(KEY==0)
		{
			Delay(20);
			if(KEY==0)
			{
				flag=1;
				count++;
			}
			while(!KEY);
		}
		if(count>9)count=0;
        if(flag)
        {
            flag=0;
             switch(count)
            {
                case 0:UART_SendByte(0);break;
                case 1:UART_SendByte(1);break;
                case 2:UART_SendByte(2);break;
                case 3:UART_SendByte(3);break;
                case 4:UART_SendByte(4);break;
                case 5:UART_SendByte(5);break;
                case 6:UART_SendByte(6);break;
                case 7:UART_SendByte(7);break;
                case 8:UART_SendByte(8);break;
                case 9:UART_SendByte(9);break;        
            }
        }

	}
}


void TR_process(void) interrupt 4
{
        if(RI)
        {
                RI = 0;               
        }
}

Delay.c

cpp 复制代码
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

cpp 复制代码
#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

UART.c

cpp 复制代码
#include <REGX52.H>

void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;			//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	ES=1;		//串口中断允许控制位
	EA=1;		//中断允许总控制位
}


void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

UART.h

cpp 复制代码
#ifndef __UART_H__
#define __UART_H__

void UartInit();
void UART_SendByte(unsigned char Byte);

#endif

乙机(从机)

main.c

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "UART.h"
unsigned char DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void main()
{
	P2=0xc0;
	UartInit();		//串口初始化
	while(1);
}

void UART_Routine() interrupt 4
{
        if(RI)
        {
            RI=0;		
            switch(SBUF)
            {
                case 0x00: P2=DSY_CODE[0];break;
                case 0x01: P2=DSY_CODE[1];break;
                case 0x02: P2=DSY_CODE[2];break;
                case 0x03: P2=DSY_CODE[3];break;
                case 0x04: P2=DSY_CODE[4];break;
                case 0x05: P2=DSY_CODE[5];break;
                case 0x06: P2=DSY_CODE[6];break;
                case 0x07: P2=DSY_CODE[7];break;
                case 0x08: P2=DSY_CODE[8];break;
                case 0x09: P2=DSY_CODE[9];break;
            }
        }
        if(TI)
        {
            TI=0;
        }
}

Delay.c

cpp 复制代码
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

cpp 复制代码
#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

UART.c

cpp 复制代码
#include <REGX52.H>


void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;			//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	ES=1;		//串口中断允许控制位
	EA=1;		//中断允许总控制位
}


void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

/*
void UART_Routine() interrupt 4
{
	if(RI==1)
	{
		
		RI=0;
	}
}
*/

UART.h

cpp 复制代码
#ifndef __UART_H__
#define __UART_H__

void UartInit();
void UART_SendByte(unsigned char Byte);

#endif

最后提醒一下,这里我使用的数码管是共阳数码管的,如果使用共阴数码管的朋友则是不符合我的代码、原理图、仿真图的,因为共阴数码管和共阳数码管的公共端的接法是不一样的,这里就不多说关于数码管的知识了,感兴趣的朋友可以自己去了解。

相关推荐
MARIN_shen28 分钟前
Marin说PCB之POC电路layout设计仿真案例---06
网络·单片机·嵌入式硬件·硬件工程·pcb工艺
Asa3191 小时前
STM32-按键扫描配置
stm32·单片机·嵌入式硬件
南城花随雪。1 小时前
单片机:实现驱动超声波(附带源码)
单片机·嵌入式硬件
yutian060610 小时前
Keil MDK下载程序后MCU自动重启设置
单片机·嵌入式硬件·keil
析木不会编程12 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
枯无穷肉16 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
不过四级不改名67717 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件
嵌入式大圣17 小时前
单片机UDP数据透传
单片机·嵌入式硬件·udp
云山工作室17 小时前
基于单片机的视力保护及身姿矫正器设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
嵌入式-老费18 小时前
基于海思soc的智能产品开发(mcu读保护的设置)
单片机·嵌入式硬件