串口通讯实验,设计一个甲、乙、丙多机通信实验,甲机发送数据给乙机,乙机收到后反馈一个内容给甲机,甲机收到反馈内容再加上原来发送内容再发给到乙机,乙机收到信息,进行确认对比,内容正确就在显示终端显示相应内容,三个收发端都可以按照此方式收发。当甲机连续通过按键发送同一个内容三次,就对三个收发端的数码管清零。
从一个单片机发送5个给另一个单片机,另一个单片机接收到后完成数据相加,并通过数码管显示出来,要求所有数据为十进制格式。
#include
#define uchar unsigned char
unsigned char code str1[]="1"; //设置需要发送的协议代码
unsigned char code str2[]="2";
unsigned char code str3[]="3";
sbit P1_0=P1^0; //给相应端口一个编号
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit led0 = P1^6; // 作为主机,接收到从机反馈信号,显示
sbit led1 = P1^7; // 作为从机,接收到主机信号,显示
sbit key = P3^3; //主从机运行选择 按下时,无法通信
uchar temp,flag;
uchar a[10];
uchar count = 0;
uchar code table[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
//函数的功能是:向PC端发送一个字节数据
void send(unsigned char dat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
void delay(unsigned int n) //延时函数的设置
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=249;j>0;j--)
;
}
void main(void)
{
unsigned int i;
TMOD=0x20; //TMOD=0010 0000,设置定时器T1工作于方式二
SCON=0x60; //SCON=0100 0000,设置串口的工作方式为方式1
PCON=0x00; //PCON=0000 0000,波特率为9600 晶振为11.0592
TH1=0xfd; //设置定时器T1的初值
TL1=0xfd; //定时器T1自动填充的值
TR1=1; //启动定时器T1
REN=1; //允许接收
EA=1; //开起总中断开关
ES=1; //需要用到串行口的中断所以ES=1就是把串行口的中断打开了
EX1 = 1; //INT1中断允许
EA = 1; //全局中断打开
IT1 = 1; //触发方式为下降沿触发
led1 = 0;
led0 = 0;
while(1)
{
if(P1_0==0) //判断P1_0口的开关状态 U1->U2
{
i=0;
while(str1[i]!='\0') //循环发送相应数组中的数据
{
send(str1[i]);
//P0=table[str1[i]];
i++;
delay(1);
}
send('\0'); //最后一位补上\0作为接收机判断结束的标准
delay(1000);
}
// if(key==0)
// {
// flag=0;
// }
if(flag==1) //等待中断的来临,然后flag就会被赋值为1
{
if(P1_1==0 & P1_2==0) // 同时按下按键2 与按键3 ,处于发送状态 否则处于接收状态
{
if(a[0]==0x32)
{
i=0;
a[1] = str1[0];
while(a[i] != '\0')
{
//p0 = 0x00;
send(a[i]);
//P0=table[a[i]];
i++;
delay(1);
}
send('\0'); //最后一位补上\0作为接收机判断结束的标准
led0 = 1;
delay(1000);
}
}
//处于接收状态
else
{
if(a[0]==0x31)
{
i=0;
while(str2[i]!='\0')
{
send(str2[i]);
i++;
delay(1);
}
send('\0');
led1 = 1;
delay(1000);
}
if(a[0]==0x32 && a[1]==0x31)
{
P0=table[2];
delay(500);
P0=table[1];
delay(500);
}
}
flag=0;
led0=0;
led1=0;
P0=0xff;
}
}
}
void serial() interrupt 4 //设置中断函数
{
temp=SBUF; //当有中断时把传过来的数据暂存到temp中
RI=0; //把设置中断的标志初始化,等待下一中断
if(temp==0x00) //当到达最后一位
{
a[count]=temp;
count=0; //计数器初始化为下一次中断准备
flag=1; //标志置1进入主函数,进行端口的赋值
}
else
{
a[count]=temp;
count=count+1;
}
}
void jump_low() interrupt 2
{
flag=0; //无法进入串口中断
delay(1000);
}
/** 功能描述: 甲机发数据!”**/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define lcd_out P0
/***********端口定义********************************/
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;
sbit p10=P1^0;
sbit p11=P1^1;
sbit p12=P1^2;
sbit p13=P1^3;
sbit p14=P1^4;
sbit p15=P1^5;
sbit p16=P1^6;
sbit p17=P1^7;
sbit led=P3^7;
/***********函数申明***********************************/
void UART_Init(void);
void UART_SendData(uchar dat);
void UART_SendString(uchar *p);
void delay(uint j);
void check_busy(void);
void write_command(uchar com);
void write_data(uchar dat);
void LCD_initial(void);
void dis_char(uchar ad, uchar input);
void shaomiao(void);
void panduan(void);
void display1(void);
void display2(void);
/***********变量定义********************************/
uchar address=0x00; //显示地址
uchar sting[]="0123456";
unsigned char code str[]="0123456789";
uchar code temp[]="0123456789";
uchar temp1[8],mm[4],temp2[8];
float q;
uchar num,num1,k,r=0,n,h,d,w;
float sum;
long uu;
void main(void)
{
LCD_initial(); //LCD1602 初始化
UART_Init(); //串口初始化
led=0;
while(1)
{
shaomiao();
panduan();
// UART_SendString(sting); //发送字符串
// address=0x00; //发送完数据 地址就归零 从头再来
// delay(1000);
// write_command(0x01); //发送完一帧数据 清屏
}
}
//串口初始化
void UART_Init(void)
{
SCON=0x50;
TMOD=0x20;
PCON=0x00;
TH1 =0xf4;
TL1 =0xf4; //预置初值,设波特率为2400
TR1 =1;
}
//串口发送一个字节的数据
void UART_SendData(uchar dat)
{
SBUF=dat; //发送数据
while(!TI); //判断是否发送完
TI=0; //软件清0
delay(100);
dis_char(address++,dat); //发送完一个数据 显示一个数据
if(address==0x10) address=0x40;//显示完第一行 就显示第二行
if(address==0x50){
write_command(0x01);
address=0x00;//显示完第二行 清屏后又显示第一行
}
}
//串口发送多字节数据
void UART_SendString(uchar *p)
{
while(*p!='\0')
{
UART_SendData(*p);
p++;
}
}
//1ms延时程序
void delay(uint j)
{
uchar i=250;
for(;j>0;j--)
{
while(--i);
i=249;
while(--i);
i=250;
}
}
查忙程序
//void check_busy(void)
//{
// uchar dt;
// do
// {
// dt=0xff;
// e=0;
// rs=0;
// rw=1;
// e=1;
// dt=lcd_out;
// }while(dt&0x80);
// e=0;
//}
//写控制指令
void write_command(uchar com)
{
//check_busy();
e=0;
rs=0;
rw=0;
lcd_out=com;
e=1;
_nop_();
e=0;
delay(1);
}
//写数据指令
void write_data(uchar dat)
{
//check_busy();
e=0;
rs=1;
rw=0;
lcd_out=dat;
e=1;
_nop_();
e=0;
delay(1);
}
//液晶屏初始化
void LCD_initial(void)
{
write_command(0x38);//8位总线,双行显示,5X7的点阵字符
write_command(0x0C);//开整体显示,光标关,无黑块
write_command(0x06);//光标右移
write_command(0x01);//清屏
delay(1);
}
// 输出字符
void dis_char(uchar ad, uchar input)
{
write_command(ad+0x80);//ad是显示位置信息
write_data(input);
delay(10);
}
void shaomiao()
{
uchar i,s;
for (i=0,s=0xfe;i<4;i++)
{
P1=s;
if(p14==0|p15==0|p16==0|p17==0)
{
delay(10);
if(p14==0|p15==0|p16==0|p17==0)
{
if(p14==0)
{
if(p10==0)
{ num=7;
UART_SendData(str[7]);
}
if(p11==0)
{ num=4;
UART_SendData(str[4]);}
if(p12==0)
{ num=1;
UART_SendData(str[1]);
}
if(p13==0)
num=10;
}
if(p15==0)
{
if(p10==0)
{ num=8;
UART_SendData(str[8]);
}
if(p11==0)
{ num=5;
UART_SendData(str[5]);
}
if(p12==0)
{ num=2;
UART_SendData(str[2]);
}
if(p13==0)
{ num=0;
UART_SendData(str[0]);
}
}
if(p16==0)
{
if(p10==0)
{ num=9;
UART_SendData(str[9]);
}
if(p11==0)
{ num=6;
UART_SendData(str[6]);
}
if(p12==0)
{ num=3;
UART_SendData(str[3]);
}
if(p13==0)
num=11;
}
if(p17==0)
{
if(p10==0)
num=15;
if(p11==0)
num=14;
if(p12==0)
num=13;
if(p13==0)
num=12;
}
while(p14==0|p15==0|p16==0|p17==0);
}
if(num<10)
{
k++;
w=0;
}
if(d==1)
{
d=0;
sum=-sum;
}
}
s=s<<1|0x01;
s=s|0xf0;
}
}
void display1()
{
uchar i;
uu=(long)(sum);
temp1[7]=uu/10000000;
temp1[6]=uu%10000000/1000000;
temp1[5]=uu%10000000%1000000/100000;
temp1[4]=uu%10000000%1000000%100000/10000;
temp1[3]=uu%10000000%1000000%100000%10000/1000;
temp1[2]=uu%10000000%1000000%100000%10000%1000/100;
temp1[1]=uu%10000000%1000000%100000%10000%1000%100/10;
temp1[0]=uu%10;
if(h==1)
{
h=2;
write_command(0x80+15-k);
write_data(0x2d);
}
if(r==0)
write_command(0x80+15);
if(r==1)
write_command(0xc0+15);
write_command(0x04);
for (i=0;i<k;i++)
{
write_data(temp[temp1[i]]);
delay(5);
}
}
void display2()
{
uchar i;
temp2[7]=uu%10000000/1000000;
temp2[6]=uu%10000000%1000000/100000;
temp2[5]=uu%10000000%1000000%100000/10000;
temp2[4]=uu%10000000%1000000%100000%10000/1000;
temp2[2]=uu%10000000%1000000%100000%10000%1000/100;
temp2[1]=uu%10000000%1000000%100000%10000%1000%100/10;
temp2[0]=uu%10;
if(h==1)
{
h=2;
write_command(0x80+15-k-4);
write_data(0x2d);
}
if(r==0)
write_command(0x80+15);
if(r==1)
write_command(0xc0+15);
write_command(0x04);
for (i=0;i<k+4;i++)
{
if(i==3)
{
write_data(0x2e);
i++;
}
write_data(temp[temp2[i]]);
delay(5);
}
}
void panduan()
{
if(n==1&num==0)
{
write_command(0x01);
write_command(0x80+15);
write_data(temp[0]);
k=0;
n=0;
}
if(num==10)
{
write_command(0x01);
k=0;
n=0;
r=0;
}
if(n==1&num>=1&num<10)
{
write_command(0x01);
k=1;
n=0;
r=0;
}
if(num<10&k==1)
{
sum=num;
mm[0]=num;
if(num==0)
k=0;
}
if(num<10&k==2)
{
sum=mm[0]*10+num;
mm[1]=num;
}
if(num<10&k==3)
{
sum=mm[0]*100+mm[1]*10+num;
mm[2]=num;
}
if(num<10&k==4)
{
sum=mm[0]*1000+mm[1]*100+mm[2]*10+num;
mm[3]=num;
}
if(num<10&k==5)
{
num=10;
}
if (num>=12&num<16)
{
r=1;
k=0;
q=sum;
if(num==12)
{
write_command(0xc0);
write_data(0x2b);
}
if(num==13)
{
write_command(0xc0);
write_data(0x2d);
}
if(num==14)
{
write_command(0xc0);
write_data(0x2a);
}
if(num==15)
{
write_command(0xc0);
write_data(0xfd);
}
num1=num;
n=0;
}
if(num==11&w==0)
{
w=1;
n=1;
r=0;
num=16;
write_command(0x01);
if(num1==12)
sum=q+sum;
if(num1==13)
sum=q-sum;
if(num1==14)
sum=q*sum;
if(num1==15)
sum=q/sum;
if(sum>=0)
h=0;
else
{
h=1;
sum=-sum;
d=1;
}
if(sum<100000000)
k=8;
if(sum<10000000)
k=7;
if(sum<1000000)
k=6;
if(sum<100000)
k=5;
if(sum<10000)
k=4;
if(sum<1000)
k=3;
if(sum<100)
k=2;
if(sum<10)
k=1;
if(sum!=(long)(sum))
{
uu=sum*10000;
display2();
}
}
if(sum==(long)(sum))
display1();
}
大佬们,可以支持一下。谢谢!!!
实验一 多机串口通讯实验 数码管显示
实验二 双机串口通讯实验 LCD显示