发送数据改变蜂鸣器的频率,问题是需要通过发送两次单.....
时间:10-02
整理:3721RD
点击:
#include "reg52.h"
sbit p2_3=P2^3;
unsigned char timer=0;
unsigned char send[5],rec[5];
unsigned char sid=0,rid=0;
unsigned char d=0,b=0,x,y,rd ;
void delay(int a) //延时 根据传来的数值
{
while(a>0)
{
a--;
}
}
void pin(x,y)
{
//timer=(x/16)*16+x%16;
//timer+=(y/16)*16+y%16;
timer=(x/10)*16*16*16+(x%10)*16*16+(y/10)*16+(y%10); //将功能号里面第三第四位的数字转换为10进制 timer是个全局函数 控制延迟
}
void init()
{
TH1=0xfd;
TL1=0xfd;
TH0=0x4c;
TL0=0x00;
SCON=0x50;
TMOD=0x21;
TR0=1;
ET0=1;
TR1=1;
ES=1;
EA=1;
}
void main()
{
unsigned char a,open=0,i;
init();
while(1)
{
if(b==1) //数据传输完毕标志位
{
b=0;
a=rec[0];
for(i=1;i<rid-1;i++) //计算传过来的五位数据的前四句的效验位异或
a=a^rec[i];
if(a==rec[rid-1]){//跟传过来的效验位进行比较
if(rec[0]==0x00){//判断地址位
if(rid==5)//判断传过来的是几位
{
for(i=0;i<rid;i++)
send[i]=rec[i]; //将收到的数据位传给发送数组
switch(rec[1]){//判断功能号
case 0x00:SBUF=send[0];open=1;pin(rec[2],rec[3]);break;//如果是00号就传送数据 并开open标志让蜂鸣器响
case 0x01: open=0;p2_3=1;break;//01号就关掉open不响
//case 0x02: ;break;
}
rid=0;}//将数组计数位清零 方便下次计数
if(rid==3)//判断是3位
{ a=rec[0];
send[0]=rec[0];
send[1]=rec[1]; //将收到的0位 1位 放到数组中
for(i=1;i<4;i++)//此时send数组中还有上次数据 0位1位已被替代 计算这几位的效验位
a^=send[i];
send[4]=a;//将效验位放在第四位
switch(rec[1]){//判断功能位 同上
case 0x01: SBUF=send[0];open=1;break;
case 0x02: open=0;p2_3=1;break;
}
rid=0;
}
}
}
else {open=0;}//如果效验位不断 也是不响
}
if(open==1){ //判断标志位
p2_3=0;
delay(timer);
p2_3=1;
delay(timer);
}
}
}
void chuanxing() interrupt 4//串行中断
{
if(RI)//接受中断标志 如果SBUF里面有数据 为1
{
RI=0;
b=0;//发送完毕标志位
if(rid<5)//发送五位或三位数据
{
rec[rid]=SBUF;
rid++;
}
else
{
rid=0;//接受数组计数位
}
}
else
{
TI=0;//发送中断标志位
if(sid<5)
{
SBUF=send[sid];//将send里德数据送到SBUF中
sid++;
}
else
{
sid=0;//发送数组计数位
}
}
}
void jinwei() interrupt 1//定时器中断位
{
TH0=0x4c;
TL0=0x00;
if(rid==5||rid==3)//如果接受了5位或3位 将接收完毕位置1
{ b=1;
}
}
sbit p2_3=P2^3;
unsigned char timer=0;
unsigned char send[5],rec[5];
unsigned char sid=0,rid=0;
unsigned char d=0,b=0,x,y,rd ;
void delay(int a) //延时 根据传来的数值
{
while(a>0)
{
a--;
}
}
void pin(x,y)
{
//timer=(x/16)*16+x%16;
//timer+=(y/16)*16+y%16;
timer=(x/10)*16*16*16+(x%10)*16*16+(y/10)*16+(y%10); //将功能号里面第三第四位的数字转换为10进制 timer是个全局函数 控制延迟
}
void init()
{
TH1=0xfd;
TL1=0xfd;
TH0=0x4c;
TL0=0x00;
SCON=0x50;
TMOD=0x21;
TR0=1;
ET0=1;
TR1=1;
ES=1;
EA=1;
}
void main()
{
unsigned char a,open=0,i;
init();
while(1)
{
if(b==1) //数据传输完毕标志位
{
b=0;
a=rec[0];
for(i=1;i<rid-1;i++) //计算传过来的五位数据的前四句的效验位异或
a=a^rec[i];
if(a==rec[rid-1]){//跟传过来的效验位进行比较
if(rec[0]==0x00){//判断地址位
if(rid==5)//判断传过来的是几位
{
for(i=0;i<rid;i++)
send[i]=rec[i]; //将收到的数据位传给发送数组
switch(rec[1]){//判断功能号
case 0x00:SBUF=send[0];open=1;pin(rec[2],rec[3]);break;//如果是00号就传送数据 并开open标志让蜂鸣器响
case 0x01: open=0;p2_3=1;break;//01号就关掉open不响
//case 0x02: ;break;
}
rid=0;}//将数组计数位清零 方便下次计数
if(rid==3)//判断是3位
{ a=rec[0];
send[0]=rec[0];
send[1]=rec[1]; //将收到的0位 1位 放到数组中
for(i=1;i<4;i++)//此时send数组中还有上次数据 0位1位已被替代 计算这几位的效验位
a^=send[i];
send[4]=a;//将效验位放在第四位
switch(rec[1]){//判断功能位 同上
case 0x01: SBUF=send[0];open=1;break;
case 0x02: open=0;p2_3=1;break;
}
rid=0;
}
}
}
else {open=0;}//如果效验位不断 也是不响
}
if(open==1){ //判断标志位
p2_3=0;
delay(timer);
p2_3=1;
delay(timer);
}
}
}
void chuanxing() interrupt 4//串行中断
{
if(RI)//接受中断标志 如果SBUF里面有数据 为1
{
RI=0;
b=0;//发送完毕标志位
if(rid<5)//发送五位或三位数据
{
rec[rid]=SBUF;
rid++;
}
else
{
rid=0;//接受数组计数位
}
}
else
{
TI=0;//发送中断标志位
if(sid<5)
{
SBUF=send[sid];//将send里德数据送到SBUF中
sid++;
}
else
{
sid=0;//发送数组计数位
}
}
}
void jinwei() interrupt 1//定时器中断位
{
TH0=0x4c;
TL0=0x00;
if(rid==5||rid==3)//如果接受了5位或3位 将接收完毕位置1
{ b=1;
}
}
要发送两次 单片机才能判断 麻烦大家看看 怎么回事
没人知道吗
我把你的程序烧写到我的51开发板上没有效果....
