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

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

相关推荐
m0_739312872 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章3 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
TeYiToKu3 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
基极向上的三极管4 小时前
【AD】3-4 在原理图中放置元件
嵌入式硬件
徐嵌4 小时前
STM32项目---水质水位检测
stm32·单片机·嵌入式硬件
徐嵌4 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot
lantiandianzi4 小时前
基于单片机的老人生活安全监测系统
单片机·嵌入式硬件·生活
东胜物联5 小时前
探寻5G工业网关市场,5G工业网关品牌解析
人工智能·嵌入式硬件·5g
stm32发烧友5 小时前
基于STM32的智能家居环境监测系统设计
stm32·嵌入式硬件·智能家居
hairenjing112312 小时前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word