一. 代码思路
作业要求为:
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端口就可以控制两个数码管,避免了端口浪费。