超声波

其实超声波贼简单,只是难者不会,会者不难而已。

核心就是先让Trig产生10+us的高电平,然后等待echo的出现高电平,开启定时器进行计数,完了关闭计数。计数对应的时间就是往返的时间。
乘以声速除以2就是距离。

不多说了,看代码一切理解。

#include <stdio.h>
#include <reg51.h>
#include <intrins.h>

sbit echo = P2 ^ 1;//超声波测距的数据返回端口
sbit trig = P2 ^ 0;//起始控制端口

unsigned char flag = 0;
unsigned int time=0;//计数
float length;//返回距离
unsigned char str[12];

extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void LcdFullClear();

void FloatToStr(unsigned char *str, float dat)
{
    unsigned int H, L;
    signed char i = 0;
    unsigned char buf[12] = {0};
    H = (unsigned int)dat;
    L = dat*100-H*100;

    do {          //先转换为低位在前的十进制数组
        buf[i++] = H % 10;
        H /= 10;
    } while (H > 0);

    while (i-- > 0)   //将数组值转换为ASCII码反向拷贝到接收指针上
    {
        *str++ = buf[i] + '0';
    }
    *str++ = '.';
    *str++ = L/10 + '0';
    *str++ = L%10 + '0';
    *str = '\0';
}

void Init()//用于初始化设置定时器和串口波特率
{
    SCON = 0x50;
    TH1 = 0xFD;
    TL1 = 0xFD;//串口设置
    TI = 1;
    TR1 = 1; //开启定时器
    TMOD = 0x21; //设T0为方式1
    TH0 = 0;
    TL0 = 0;
    TR0 = 0;//定时器初始关闭
    ET0 = 1; //允许T0中断

    EA = 1; //开启总中断

}
void start_10() //10us+的起始信号
{
    int i;
    trig = 1;
    for (i = 0; i <= 13; i++)
    {
        _nop_();
    }

    trig = 0; //重新拉回低电平
}

void Count(void)//用于将时间换算成长度
{
    unsigned char str[12];

    time = TH0 * 256 + TL0;
    TH0 = 0;
    TL0 = 0;
    length = (time * 1.87)/100;     //算出来是CM
    if(!flag)
    {
        //printf("%f\n",length);
        FloatToStr(str, length);
        LcdShowStr(2,0, str);
    }
    else
    {
        flag = 0;
        //printf("error\n");
        LcdShowStr(2,0, "error");
    }
}
void Delay500ms()       //@11.0592MHz
{
    unsigned char i, j, k;

    i = 22;
    j = 3;
    k = 227;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void Scan()
{
    start_10();
    while (!echo);    //当RX为零时等待
    TR0 = 1; //开启计数
    while (echo);    //当RX为1计数并等待
    TR0 = 0; //关闭计数
    Count();//计算出距离
    Delay500ms();
    LcdFullClear();
}

void main()
{
    Init();//定时器初始化
    InitLcd1602();
    while(1)
    {
        Scan(); 
    }
}

void Timer0() interrupt 1
{
    flag = 1;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值