天天看点

超声波测距 c语言程序流程图,超声波测距单片机C程序+原理图+PCB源文件

#include          //STC89C52头文件

#define uchar unsigned char

#define uint unsigned int

unsigned int  time=0;

unsigned int  timer=0;

unsigned long S=0;         //距离变量

bit  flag =0;                 //超声波模块量程溢出标志(>5米时置1)

sbit echo=P1^0;               //超声波模块的发射端

sbit trig=P1^1;               //超声波模块的接收端

sbit ds=P2^2;                //DS18B20的信号线

sbit P24=P2^4;

sbit P25=P2^5;

sbit P26=P2^6;

sbit P27=P2^7;

sbit P07=P0^7;

int temp;

//八位共阳极

unsigned char code shuzu[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//毫秒级延时

void delayms(unsigned char z)

{

unsigned char a,b;

for(a=z; a>0; a--)

for(b=110; b>0; b--);

}

//微秒级延时

void delayus(unsigned char z)

{

while(z)

z--;

}

void delay_ms(unsigned int ms)  //1ms延时

{

uchar a;

while(ms--)

for(a=123;a>0;a--);

}

//DS18B20初始化

void ds18b20init()

{

ds=0;

delayus(80);                //延时480-960us

ds=1;

delayus(4);                 //等待应答

}

//DS18B20读命令子程序(读一字节)

uchar dushuju()

{

uchar i,dat,m;

for(i=8;i>0;i--)

{

ds=0;

delayus(1);

ds=1;

delayus(2);

m=ds;

dat=(m<<7)|(dat>>1);   //读出的数据最低位在最前面,刚好一个字节在dat里

delayus(8);

}

return dat;

}

//DS18B20写命令子程序(写一字节)

void xiemingling(uint shuju)

{

uint i;

bit m;

for(i=8;i>0;i--)

{

m=shuju&0x01;

shuju=shuju>>1;

if(m)                           //写1

{

ds=0;

delayus(2);

ds=1;

delayus(8);

}

else                     //写0

{

ds=0;

delayus(8);

ds=1;

delayus(2);

}

}

}

//DS18B20开始获取温度并转换

void zhuanhuan()

{

ds18b20init();

delayms(1);

xiemingling(0xcc);        //写跳过读ROM指令

xiemingling(0x44);       //写温度转换命令

}

//DS18B20读寄存器中存储的温度数据

int duwendu()

{

uint a,b;

ds18b20init();

delayms(1);

xiemingling(0xcc);                     //跳过ROM,忽略64位ROM地址

xiemingling(0xbe);                    //读内部RAM中的9字节的温度数据

a=dushuju();                            //读低8位

b=dushuju();                           //读高8位

b=b<<8;                                //高8位左移8位

temp=b|a;                             // 高8位和低8位组合为1个字

temp=temp*0.0625;              //温度在寄存器中位12位,分辨率为0.0625度

return temp;

}

//显示子程序

void xianshi(unsigned long num)

{

unsigned char bai,shi,ge;

bai=num/100;                        //分离三位距离数据

shi=num%100/10;

ge=num%10;

P24=0;

P0=shuzu[ge];

delay_ms(1);

P24=1;

P25=0;

P0=shuzu[shi];

P07=1;

delay_ms(1);

P25=1;

P26=0;

P0=shuzu[bai];

delay_ms(1);

P26=1;

//                 P24=0;

//                         P0=shuzu[bai];

//                         P07=1;

//                 delay_ms(1);

//                         P24=1;

}

//计算距离子程序

void Conut()

{

float a;

time=TH0*256+TL0;             //这是最后计算到的时间,但应该再乘以12/11.092

//时间应该是time*12/11.0592

TH0=0;                                   //定时器0的初始值位0

TL0=0;

a=(331.5+0.607*temp);    //声速与温度的函数关系:声速=331.5+0.607*温度

S=(time*a/200)/100;        //算出来是cm

if (S>=500)                     //最大距离为5m,即500cm

S=888;

if (flag==1)                     //判断是否溢出

{

S=888;

flag=0;

TH0=0;

TL0=0;

}

}

//初始化定时器0和定时器1

void T0_init()

{

TMOD=0x11;

TH0=0;

TL0=0;

TH1=0xf8;        //定时器1赋初值,应该是2ms

TL1=0x30;

ET0=1;

ET1=1;

TR1=1;

EA=1;

}

void  main( )

{

unsigned int i;

T0_init();

while(1)

{

duwendu();                               //获取温度后计算相应声速,从而计算距离

while(!echo);                            //当echo为0时等待

TR0=1;                                    //开启定时器0

while(echo);                            //当echo为1计数并等待

TR0=0;                                   //关闭定时器0

Conut();                                  //计算距离

for(i=150;i>0;i--)

{

xianshi(S);                      //数码管显示

}

}

}

void zd0() interrupt 1

{

flag=1;                                            //中断溢出标志

}

void  zd3()  interrupt 3

……………………

…………限于本文篇幅 余下代码请从51黑下载附件…………