8051单片机—单片机串口通信: 显示学号+数码管显示

 一. 代码思路

作业要求为:
1. 单片机1按键按下发送字符/字符串,单片机2接收并显示接收到的字符/字符串   
2. 按键可以一次发送一个字符,也可以按下一次发送整条字符串
3. 要求16位数码管可以显示学号的后两位
4. 发送内容为:学号+姓名的拼音(学号在前姓名在后)

根据作业要求可以将任务进行分解:
1. 单片机1button按下后发送字符串
2. 单片机2接收字符串并存储在数组
3. 数码管显示学号后两位

二. 编写代码

根据分解任务来编写相关代码,可以先将大框架(串口通信的初始化函数)写好。

1. 发送端

首先发送端单片机要完成的任务是将字符串通过串口通信进行发送,内容较为简单。

#include <reg51.h>

sbit button = P1^0;
unsigned char Student_Info[] = "2238010044 CaoJie";
unsigned char i,j;
bit flag = 0;

//串口初始化函数
void Serial_Init()
{
	TMOD = 0x20;
	TH1 = 0xfd;
	SCON = 0x50;
	TR1 = 1;
}

//发送函数
void Tran_Info()
{
	for(i=0;i<18;i++)
	{
		SBUF = Student_Info[i];
		while(TI == 0);
		TI = 0;
	}
}

void main()
{
	Serial_Init();
	while(1)
	{
		if(button == 0 && flag == 0)
		{
			flag = 1;
		}
		if(flag == 1 && button == 1)
		{
			flag = 0;
			Tran_Info();
		}
	}
}

这里面需要强调的是,由于需要使用按键,所以需要进行消抖操作,但是串口对于按键极为敏感,所以使用软件延时消抖的方法并不是很好,所以这里采取了标志位消抖。具体可见51单片机Proteus仿真_51单片机仿真-CSDN博客中按键部分。

2. 接收端

#include <reg51.h>
#include <stdio.h>

#define REC_SIZE 18
unsigned char rec[REC_SIZE];
unsigned char Rec_Index = 0;
bit Rec_Flag = 0;

//共阴极数码管段码表
unsigned char Seg_Buf[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};

//串口初始化函数
void Serial_Init()
{
    TMOD = 0x20;
    TH1 = 0xFD;
    SCON = 0x50;
    TR1 = 1;
}

//接收函数
void Rec_Info()
{
    if (RI == 1)
    {
        RI = 0;
        rec[Rec_Index++] = SBUF;
        if (Rec_Index >= REC_SIZE)
        {
            Rec_Index = 0;
            Rec_Flag = 1;
        }
    }
}

//低延时提高刷新率
void Delay()
{
    unsigned int i;
    for(i = 0; i < 10; i++);
}

//数码管显示函数
void Seg_Disp()
{
    unsigned char digit1, digit2;

    if (Rec_Flag)
    {
        digit1 = rec[8] - '0';
        digit2 = rec[9] - '0';

        P1 = Seg_Buf[digit1];
        P2 = 0x02;
        Delay();

        P1 = Seg_Buf[digit2];
        P2 = 0x01;
        Delay();
    }
}

void main()
{
    Serial_Init();
    while(1)
    {
        Rec_Info();
        Seg_Disp();
    }
}

接收端涉及到单片机接收以及数码管显示的问题。

为了接收单片机1发送的字符串,我们同样可以采取数组进行接收,在接收的时候需要注意发送一位接收一位,所以在接收函数中一定要将数组递增,否则会报错。

由于我们需要对两位数进行显示,所以可以采用Proteus中的7SEG-MPX2-CC两位数码管进行显示。后缀CC表示共阴极,CA表示共阳极,两种方法的段码表不同,这里采取了共阴极的方法。

该数码管的使用方法为:A-DP采取段码方法进行显示,1和2分别对应了第一个数码管和第二个数码管,当给P2.0低电平时,第一个数码管亮,给P2.1低电平时,第二个数码管亮。相关数码管的知识可见博客51单片机Proteus仿真_51单片机仿真-CSDN博客数码管部分。

那么我们需要将接收到的数组的其中第9位和第10位取出来然后送给数码管,由于接收到都是字符,所以可以直接将字符减去字符'0',就可以得到每个字符对应的数字。然后将数字对应到段码表中即可。

三. Proteus仿真电路图

在实际仿真中,由于数码管接收数据需要一定时间,如果将数码管的刷新频率降到很低,大家会发现一个现象:数码管显示有错。这是因为我们先要实现一种视觉暂留的效果,通过快速的数码管交替显示来实现两位数码管同时显示,但是由于数码管接收需要一定的时间,如果数码管还没有接收到下一个要显示的数值就已经切换,那么会导致数码管接收的值可能存在不定态,造成数码管显示出错。所以可以将延时函数改成150ms,这样就可以避免数码管接受数值出错,但是大家又会发现数码管无法同时显示。

为了解决上面的问题,大家可以使用两个数码管,通过BCD码进行4控制8,这样一个Px端口就可以控制两个数码管,避免了端口浪费。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值