找回密码
 立即注册

QQ登录

只需一步,快速开始

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

AT89C51超声波测距

[复制链接]
跳转到指定楼层
楼主
ID:259189 发表于 2017-12-8 19:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

A   /****************************************************************
Title: 超声波测距系统
Mcu: AT89S51                                                Oscillator: 12M
Designer: linqiuxiong                                        Date: 2010.2.12
Email:taking@vip.qq.com
Directions: 经实践表明该系统的测距范围在0.21m-2m时,误差不超0.5cm;
大于2m时,最大误差不超过1.5cm;因发射功率不足,本系统的稳定测量范
围是0.21m-4m。
*****************************************************************/
#include<reg51.h>                                                /*头文件*/
#include<intrins.h>
#define uchar unsigned char                                /*缩定义*/
#define uint unsigned int
#define nop() _nop_()                                        /*定义空操作指令*/
#define sled_dm_port P0                                /*定义数码管段码控制端口*/
#define sled_wm_port P1                                /*定义数码管位码控制端口*/
sbit vout=P1^6;                                                /*声明40KHz脉冲信号输出口*/
sbit fm=P1^7;                                                        /*声明蜂鸣器使能引脚*/
void delay_1ms(uchar x);                                /*1MS为单位的延时程序 */
void display();                                                        /*显示子程序*/
uchar code num_table[13]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0x7f};
/*  0    1    2    3    4    5    6    7    8    9   -   消隐   .*/       
/*定义数码管显示字符跟数字的对应数组关系*/
uchar data sled_lighten_table[]={0xf7,0xfb,0xfd,0xfe};
                                                                        /*定义每次扫描时需点亮的数码管*/
uchar dis_buff[4]={0xff,0xff,0xff,0xff};        /*定义段码缓冲数组*/
uint time,distance;                                                /*定义接收时间与距离变量*/
bit rec_flag;                                                          /*定义接收成功标志位*/
uchar k,j,wm;                                                        /*定义脉冲个数与位选控制变量*/

/*主程序*/
void main()
{
        uint i;
        TMOD=0x21;                                                /*T1为8位自动重装模式*/
        TH0=0x00;                                                /*65ms计数初值*/
        TL0=0x00;
        TH1=0xf2;                                                /*12us计数初值*/
        TL1=0xf2;
        PX0=1;                          /*外部中断0定义为高优先级中断源*/
        PT1=1;                          /*定时器1定义为高优先级中断 */
        ET0=1;                          /*T0溢出中断允许*/
        EA=1;                           /*开中断*/
        TR0=1;                         /*启动T0定时器*/
        while(1)
        {
                dis_buff[2]=num_table[distance/100];
                dis_buff[1]=num_table[distance%100/10];
                dis_buff[0]=num_table[distance%10];
                display();
                if(rec_flag)
                {
                        rec_flag=0;
                        for(i=400;i>0;i--)                                        /*测量间隔控制(约4*100=400MS)*/
                        display();
                        EA=1;
                        TR0=1;                             
                }               
        }               
}
/*显示子程序*/
void display()
{
        sled_wm_port=0xff;                                                /*显示消影*/
        if(wm==3)
                sled_dm_port=0xff;
        if(wm==2)
        {
                if(dis_buff[2]==0xc0)                                        /*若第2位数码管为0则不显示*/
                        sled_dm_port=0xff;
                else
                        sled_dm_port=dis_buff[2];
        }
        else
                sled_dm_port=dis_buff[wm];       
        sled_wm_port=sled_lighten_table[wm];
        wm++;
        if(wm==4)
                wm=0;
        delay_1ms(1);       
}
/*定时器T0中断程序*/
void TIMER0() interrupt 1
{
        EA=0;
        TH0=0x00;
        TL0=0x00;
        ET1=1;
        EA=1;
        TR1=1;
        TR0=1;
}
/*定时器T1中断程序*/
void TIMER1() interrupt 3
{
        vout=!vout;
        k++;
        if(k>=4)                                                                /*超声波脉冲个数控制(为赋值的一半)*/
        {
                k=0;
                TR1=0;
                ET1=0;
                for(j=200;j>0;j--);                                        /*1ms延时避开盲区*/
                for(j=200;j>0;j--);
                for(j=200;j>0;j--);
                EX0=1;                                                        /*开启外部中断0*/
        }               
}
/*外部中断0程序*/
void PINT0() interrupt 0
{
        TR0=0;                              
        TR1=0;
        ET1=0;
        EA=0;
        EX0=0;                              /*禁止外部中断0中断 */
        rec_flag=1;                                                        /*接收成功标志位置1*/
        time=TH0;
        time=time*256+TL0;
        time=time-120;                                                /*补偿软件或硬件带来的误差*/
        distance=time*0.017;               
}
/*1MS为单位的延时程序*/
void delay_1ms(uchar x)
{
        uchar i;
        while(x--)
                for(i=0;i<100;i++);
}

AT89S51单片机超声波测距源程序.doc

38 KB, 下载次数: 43, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:429384 发表于 2018-11-19 18:28 | 只看该作者
谢谢大佬
回复

使用道具 举报

板凳
ID:429713 发表于 2018-11-20 10:59 | 只看该作者
程序有错误啊
回复

使用道具 举报

地板
ID:407566 发表于 2018-11-26 11:36 | 只看该作者
怎么接线
回复

使用道具 举报

5#
ID:458913 发表于 2019-1-1 02:56 | 只看该作者
请问有没有仿真图
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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