在网上找了两个程序,“拼接”了下,能满足你目前提出的要求(P1口每次设置后,需重新启动proteus)。
//U1串口接收数据加上P1开关设置的值,在P0口用16进制数码显示。
//数码管动态扫描显示。
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit D1=P2^0;
sbit D2=P2^1;
sbit D3=P2^2;
sbit D4=P2^3;
char n=0;
unsigned char code LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
void delay(unsigned char us) //延迟函数
{
for(;us!=0;us--);
}
void init() //初始化函数
{
TMOD=0x20; //设置定时器T1工作于方式2
SCON=0x50; //串口工作方式1,允许接收数据
TH1=0xfd; //波特率为2400b/s
TL1=0xfd;
TR1=1; //启动定时器T1
REN=1; //允许接收数据
D1=0; //上电默认是高电平,所以先初始化为低电平
D2=0;
D3=0;
D4=0;
}
void Led_display(unsigned int temp) //数码管显示函数
{
P0=LED[temp%16]; //a的各位数
D4=1; //打开D4,显示
delay(20); //延迟,給硬件有响应时间
D4=0; //关闭D4
P0=0xff; //P2全部为高电平,以免下次显示出错,称为“消隐”
delay(20);
P0=LED[temp/16%16]; //a的十位数
D3=1; //打开D3
delay(20);
D3=0; //关闭D3
P0=0xff;
delay(20);
P0=LED[temp/256%16]; //a的百位数
D2=1; //打开D2
delay(20);
D2=0; //关闭D2
P0=0xff;
delay(20);
P0=LED[temp/4096]; //a的千位数
D1=1; //打开D1
delay(20);
D1=0; //关闭D1
P0=0xff;
delay(20);
}
unsigned char receive(void) //数据接收函数
{
unsigned char dat;
while(RI==0); //数据没有接收完毕时等待接收
RI=0; //接收完毕时清零
dat=SBUF; //将接收缓冲器中的数据存入dat
return dat; //将接收到的数据返回
}
void main(void)
{
unsigned int temp=0;
init(); //初始化
temp=receive()+P1; //将接收到的数据送到P1口显示
while(1)
{
Led_display(temp); //数码管显示
}
}
//U2程序如下:
//串口通信,接收、发送数据 这是U2的程序
//U2发送数据给U1,U3\U4控制LED显示P1口输入数
//根据U2的P1端口开关闭合情况,发送相应数据
#include <reg51.h>
unsigned char temp=0;
void main()
{
//设置定时器1
TMOD=0x20;//8位自动重装在
TH1=0xFD;
TL1=0xFD;//波特率为9600
SCON=0x50;//1位启动位,8位数据位,1位停止位,REN开启,可以接收
TR1=1;//启动定时器,开始产生波特率
while(1)
{
if(temp!=P1)//如果P1口开关发生变化
{
temp=P1;//赋值
SBUF=P1;//写入数据
while(0==TI);//等待发送完成
TI=0;//清除中断标志
}
}
}
|