下面是郭天祥课本源码:
新概念51单片机,11.4
单片机源程序如下:
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define SLAVE2 0x02 //从机地址02
- #define BN 16
- uchar rbuf[16];
- uchar tbuf[16];
- void err(void)
- {
- SBUF=0xff;
- while(TI!=1);
- TI=0;
- }
- uchar master(uchar addr,uchar command)
- {
- uchar aa,i,p;
- while(1)
- {
- SBUF=addr; //呼叫地址
- while(TI!=1);
- TI=0;
- while(RI!=1);
- RI=0; //等待从机回答
- if(SBUF!=addr)
- err(); //若地址错发复位信号
- else //地址相符
- {
- TB8=0; //清地址标志
- SBUF=command; //发命令,数据帧发,命令是主函数输入
- while(TI!=1);
- TI=0;
- while(RI!=1);
- RI=0;
- aa=SBUF; //接受从机状态字
- if((aa&0x08)==0x08) //若命令未被接受发复位信号
- {
- TB8=1;
- err();
- }
- else
- {
- if(command==0x01) //是发送命令
- {
- if((aa&0x01)==0x01) //从机准好就绪
- {
- do
- {
- p=0; //清校验和
- for(i=0;i<BN;i++)
- {
- SBUF=tbuf[i]; //发送数据
- p+=tbuf[i];
- while(TI!=1)
- TI=0;
- }
- SBUF=p; //发送校验和
- while(TI!=1);
- TI=0;
- while(RI!=1);
- RI=0;
- }
- while(SBUF!=0); //接受不正确,重新发送
- TB8=1; //置地址标志
- return(0);
- }
- }
- else
- {
- if((aa&0x02)==0x02) //是接受命令,从机准备好发送
- {
- while(1)
- {
- p=0; //清校验和
- for(i=0;i<BN;i++)
- {
- while(RI!=1);
- RI=0;
- rbuf[i]=SBUF; //接受数据
- p+=rbuf[i];
-
- }
- while(RI!=1);
- RI=0;
- if(SBUF==p)
- {
- SBUF=0x00; //校验和相同发“00”
- while(TI!=1)
- TI=0;
- break;
- }
- else
- {
- SBUF=0xff; //校验和不同发ff重新接受
- while(TI!=1);
- TI=0;
-
- }
- }
- TB8=1; //置地址标志
- return(0);
- }
-
-
- }
- }
- }
- }
- }
- void main()
- {
- TMOD=0x20; //T/C1定义为方式2
- TL1=0xfd;
- TH1=0xfd; //置初值
- PCON=0x00;
- TR1=1;
- SCON=0xf8; //串行口方式3
- master(SLAVE2,0x01); //命令从机02接受
- master(SLAVE2,0x02); //命令从机02发送
- while(1);
-
- }
- 从机
- //=======================================================================================
- #include <reg52.h>
- #define uchar unsigned char
- #define SLAVE2 0x02
- #define BN 16
- uchar code trbuf[16]={"congji transmit"};
- uchar rebuf[16];
- bit tready;
- bit rready;
- void str(void);
- void sre(void);
- void main(void)
- {
- TMOD=0x20; //T/C1定义为方式2
- TL1=0xfd;
- TH1=0xfd; //置初值
- PCON=0x00;
- TR1=1;
- SCON=0xf0; //串行口方式3,TB8=1,发地址命令
- ES=1;
- EA=1; //开串行口中断
- while(1)
- {
- tready=1;
- rready=1;
- } //假定准备好发送和接受
- }
- void ssio(void) interrupt 4
- {
- uchar a;
- RI=0;
- ES=0; //关串行中断
- if(SBUF!=SLAVE2)
- {
- ES=1;
- goto reti;
- }
- SM2=0; //取消监听状态
- SBUF=SLAVE2; //从本地址发回
- while(TI!=1);
- TI=0;
- while(RI!=1);
- RI=0;
- if(RB8==1) //是复位信号,恢复监听
- {
- SM2=1;
- ES=1;
- goto reti;
- }
- a=SBUF; //接受命令
- if(a==0x01) //主机接受的数据
- {
- if(rready==1)
- SBUF=0x01; //接受准备好发状态
- else
- SBUF=0x00;
- while(TI!=1)
- TI=0;
- while(RI!=1)
- RI=0;
- if(RB8==1)
- {
- SM2=1;
- ES=1;
- goto reti;
- }
- sre(); //接受数据
- }
- else
- {
- if(a==0x02) //从机向主机发送数据
- {
- if(tready==1)
- SBUF=0x02; //发送准备好状态
- else
- SBUF=0x00;
- while(TI!=1);
- TI=0;
- while(RI!=1);
- RI=0;
- if(RB8==1)
- {
- SM2=1;
- ES=1;
- goto reti;
-
- }
- str(); //发送数据
- }
- else
- {
- SBUF=0x80; //命令非法,发送状态
- while(TI!=1);
- TI=0;
- SM2=1;
- ES=1; //恢复监听
- }
- }
- reti:;
-
- }
- void str(void) //发送数据块
- {
- uchar p,i;
- tready=0;
- do
- {
- p=0; //清校验和
- for(i=0;i<BN;i++)
- {
- SBUF=trbuf[i]; //发送数据块
- p+=trbuf[i];
- while(TI!=1);
- TI=0;
- }
- SBUF=p;
- while(TI!=1);
- TI=0;
- while(RI!=1);
- RI=0;
- }
- while(SBUF!=0); //主机接受不正确,重新发送
- SM2=1;
- ES=1;
- }
- void sre(void) //接受数据块
- {
- uchar p,i;
- rready=0;
- while(1)
- {
- p=0; //清校验和
- for(i=0;i<BN;i++)
- {
- while(RI!=1);
- RI=0; //接受数据
- rebuf[i]=SBUF;
- p+=rebuf[i];
-
- }
- while(RI!=1);
- RI=0;
- if(SBUF==P)
- {
- SBUF=0x00;
- break; //校验和相同发“00”
- }
- else
- {
- SBUF=0xff; //校验和不同发ff重新接受
- while(TI!=0);
- TI=0;
- }
- }
- SM2=1;
- ES=1;
- }
复制代码
//===========================================================================
课本源码有明显2处纰漏修改了一下,但是proteus仿真没有结果,求助大神帮分析下
|