超声波流量计的主程序研究与设计 十八
//发送数据子程序:将时间差tc通过函数printf()发送到串口
transmit_data()//调用发送数据函数,将时间差tc传给主单片机
{
if(send_flag==1)
{
SBUF=tc;//先将时间差tc送到缓冲器
printf(tc);//发送tc
while(TI==0); //等待发送完成
TI=0; //清除发送中断TI标志,准备下一次发送
send_flag==0;//将标志位清零
}
}
//从单片主程序:收发电路的控制,获取单次时间tc,将tc传给主单片机
void main()
{ P0=0xff;
p1_0=0;//对计数器清零
p1_1=1;//不向主单片机申请中断
p1_5=0;//先将继电器开关关闭
p2_0=1;//关闭上一个锁存器
p2_1=1;//关闭下一个锁存器
IT1=0;//外部中断INT1,为低电平触发方式
EX1=1;//允许外部中断INT1申请中断
EA=1;//打开总的中断开关
ES=1;//打开串口中断开关
TMOD=0x20;//定时器1工作在方式三,作为波特率发生器
TR1=1;//开定时器
TI=1;//串口中断发送申请标志位
SCON=0x50;//串口工作在方式一
PCON=0x80;//速率加倍,波特率为4.8K
TH1=0xf3H;//根据波特率设置初值
TL1=0xf3H;
while(1)
{
p1_2=1;//启动发射信号
p1_5=1;//顺流发射N次
delay(50);//延时50ms,等待顺流发射时,计数结束
flag1=1;//顺流发射结束标志位
p1_0=0;//计数器清零,以便逆流时重新计数
delay(1);
p1_2=1;//再次开启动信号
p1_5=0;//逆流发射N次
delay(50);//延时50ms,等待四逆流发射时,计数结束
flag2=1;//逆流发射结束标志位
p1_2=0;//关闭启动信号
transmit_data()//调用发送数据函数,将时间差tc传给主单片机
}
}
//外部中断1的子程序:获取时间差tc
void INT1() interrupt 2 using 1
{
long int n1,n2,ta;
long int n11,n22,tb;
if(flag1==1)//如果顺流发射结束
{
flag1==0;//标志位清零
p1_2=0;//关闭启动信号
p2_0=1;//关闭上一个锁存器
p2_1=0;//打开下一个锁存器
n1=P0;//读入高位数据
p2_0=0;//打开上一个锁存器
p2_1=1;//关闭下一个锁存器
n2=P0;//读入低位数据
ta=(n1*100+n2)*10;//计算顺流发射时间,单位为ns
p2_0=1;//关闭上一个锁存器
p2_1=1;//关闭下一个锁存器
}
if(flag2==1)//如果逆流发射结束
{
flag2==0;//标志位清零
p1_2=0;//关闭启动信号
p2_0=1;//关闭上一个锁存器
p2_1=0;//打开下一个锁存器
n11=P0;//读入高位数据
p2_0=0;//打开上一个锁存器
p2_1=1;//关闭下一个锁存器
n22=P0;//读入低位数据
tb=(n11*100+n22)*10;//计算逆流发射时间,单位为ns
p2_0=1;//关闭上一个锁存器
p2_1=1;//关闭下一个锁存器
}
tc=(tb-ta)/1000/1000/1000/1024;//求出单次时间差,将纳秒ns转化为秒s
send_flag=1;//发送标志位:告诉从单片机可以向主单片机发送tc
超声波流量计