找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1284|回复: 0
打印 上一主题 下一主题
收起左侧

单片机超声波测距代码

[复制链接]
跳转到指定楼层
楼主
#include "reg52.H"//器件配置文件
#include"lcd.h"
//传感器接口
sbit RX  = P3^2;
sbit TX  = P3^3;
sbit key  = P1^4;
char keymode=0;
int keycount=0;

//变量声明
unsigned int  time=0;
unsigned int  timer=0;
unsigned char posit=0;
unsigned long S=0;

char Mode=0;
bit  flag=0;
bit flag_KEY=0;
unsigned char act[]={0xff,0xfa,0xf5,0xf9,0xf6};          //小车动作控制
unsigned char disbuff[4]           ={0,0,0,0};                 //数组用于存放距离信息
void Display();
//延时20ms(不精确)
void delay_ms(unsigned int m)
{
    unsigned int b,c;
    for(c=0;c<m;c++)
        for(b=0;b<120;b++);
}
void Key(void)
{
        key = 1;
        delay_ms(1);
        if(key==0)                  //检测按键K1是否按下           开关
        {        
                        delay_ms(10);   //消除抖动 一般大约10ms
                        if(key==0)         //再次判断按键是否按下
                        {
                                keymode++;
                                if(keymode == 2)keymode = 0;
                                
                        }
                        while(!key);         //检测按键是否松开
        }
        if(keymode==1)
        {
                keycount++;
                if(keycount==8)
                {
                        keycount=0;
                        keymode=0;
                }
        }
}

void Conut(void)
{
        time=TH0*256+TL0;          //读出T0的计时数值
        TH0=0;
        TL0=0;                                  //清空计时器
        S=(time*1.7)/100;     //算出来是CM
        //声音的速度是340m/s,时间的单位是us,计算到秒需要将时间数据/1000000,
        //长度=速度*时间,340*time/1000000,长度数据单位是m转换成cm需要乘以100得到340*time/10000,
        //小数点都向左移两位得到3.4*time/100,因为超声波是往返了,所以再除以2,得到距离数据(time*1.7)/100
        if(Mode==0)                          //非设置状态时
        {
                if(S>=800) //超出测量范围显示“-”
                {        
                        disbuff[0]='o'-0x30;           //“-”
                        disbuff[1]='v'-0x30;           //“-”
                        disbuff[2]='e'-0x30;           //“-”
                        disbuff[3]='r'-0x30;           //“-”
                }
                else
                {
                        disbuff[0]=S%1000/100;                 //将距离数据拆成单个位赋值
                        disbuff[1]=S%100/10;
                        disbuff[2]='.'-0x30;
                        disbuff[3]=S%10;
                }
        }

}
void delay(unsigned int t)
{
        while(t--);
}
/**********************************************************************************************************/
//定时器0
void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
{
        flag=1;                                                 //中断溢出标志
}
/**********************************************************************************************************/
//定时器1
void zd3() interrupt 3                  //T1中断用来扫描数码管和计800MS启动模块
{
        
        char n=10;
        P1 = 0xff;delay(7);        
        TH1=0xf8;
        TL1=0x30;                                 //定时2ms
        timer++;                                //变量加
        if(timer>=400)                        //1次就是40ms
        {
                timer=0;
                TX=1;                                  //40MS  启动一次模块
                while(n--);
                TX=0;
                SBUF=S/256;//将接收到的数据放入到发送寄存器
                while(!TI);                         //等待发送数据完成
                TI=0;                                                 //清除发送完成标志位
                SBUF=S%256;//将接收到的数据放入到发送寄存器
                while(!TI);                         //等待发送数据完成
                TI=0;                                                 //清除发送完成标志位
        }
        P1 = act[keymode];                //扫描显示
        
         
}
void UsartInit()
{
        SCON=0X50;                        //设置为工作方式1
        TMOD=0X20;                        //设置计数器工作方式2
        PCON=0X80;                        //波特率加倍
        TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
        TL1=0XF3;
        ES=1;                                                //打开接收中断
        EA=1;                                                //打开总中断
        TR1=1;                                        //打开计数器
}

/**********************************************************************************************************/
//主函数
void main(void)
{  
        TMOD=0x11;                   //设T0为方式1
        TH0=0;
        TL0=0;         
        TH1=0xf8;                   //2MS定时
        TL1=0x30;
        ET0=1;                                //允许T0中断
        ET1=1;                           //允许T1中断
        TR1=1;                           //开启定时器
        EA=1;                                        //开启总中断
        UsartInit();                                //串口初始化 9600
        LcdInit();        
        while(1)
        {
                while(!RX);                //当上次接收完波后,RX引脚是低电平,取反就是1,此while成立,反复判断RX状态。当RX没有接收到返回波时是高电平,取反就是0,此while不成立,跳出
                TR0=1;                        //开启计数
                while(RX);                //当RX没有接收到返回波,此while成立,程序停在这里一直判断RX状态。当RX接收到返回波,RX引脚变为低电平,此while不成立,跳出
                TR0=0;                        //停止计数
                Conut();                        //计算
                LcdWriteCom(0x80);
                LcdWritestr("distance:");                //液晶显示距离
                LcdWriteData(disbuff[0]+0x30);
                LcdWriteData(disbuff[1]+0x30);
                LcdWriteData(disbuff[2]+0x30);
                LcdWriteData(disbuff[3]+0x30);
                LcdWritestr("cm");
                Key();
        
                 
        }
}

void Usart() interrupt 4
{
        RI = 0;//清除接收中断标志位
}
            
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表