基于51最小系统的超声波测距

发布者:大橙子5511最新更新时间:2021-07-27 来源: eefocus关键字:最小系统  超声波测距 手机看文章 扫描二维码
随时随地手机看文章

原理:

超声波方面:

超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波可用于距离的测量。


超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s),

即:S=Vt/2 。


51单片机方面:

震荡周期,时钟周期:晶振提供

机器周期:CPU完成一个独立操作,为十二个震动周期

即:外接12MHz晶振51单片机每进行一次操作需要1us


HC-SR04方面:

(1)采用IO口TRIG触发测距,给至少10us的高电平信号; (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。


时序图:

在这里插入图片描述

代码实现部分:


#include  

#include

typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;



sbit Trig = P2^1;

sbit Echo = P2^0;

sbit LED=P2^2;


u8 str[20]={0};

u8 zhi=10;

u8 code strerror[]={"error"};

u8 i;

u16 time;

u16 S=0;

bit flag=0;



/*******************************************************************************

函数功能 :串口通信配置

*******************************************************************************/

void USARTinit()                                          

{

SCON=0X50; //设置为工作方式1

TMOD=0X20|TMOD; //设置计数器工作方式2

PCON=0X80; //波特率加倍

TH1=0XF3; //计数器初始值设置,波特率是4800

TL1=0XF3;

ES=1; //打开串口中断

EA=1; //打开总中断

TR1=1; //打开计数器

}


/*******************************************************************************

函数功能 : 串口通信发送中断函数

输入           : 要发送的一字节数据

*******************************************************************************/

void send(u8 Data) 

{

SBUF=Data;     //数据放入到发送寄存器

while(!TI); //等待发送数据完成

TI=0;       //清除发送完成标志位

}


/*******************************************************************************

函数功能 : 定时器0初始化,用于计算时间

*******************************************************************************/

void T0inti()

{

TMOD=0x01|TMOD;    //设T0为方式1

TH0=0;

TL0=0;          

ET0=1;             //允许T0中断

EA=1;    //开启总中断

}


/*******************************************************************************

函数功能 : 外部中断初始化

*******************************************************************************/

void EXinit()

{

EX0=1;              //打开外部中断0

IT0=1;             //边沿触发方式

EX1=1;              //打开外部中断1

IT1=1;             //边沿触发

EA=1;        //打开总中断

}


/*******************************************************************************

函数功能 : 阈值初始化

*******************************************************************************/

void zhiinit() interrupt 0

{

zhi=10;

}


/*******************************************************************************

函数功能 : 阈值加10

*******************************************************************************/

void zhichuli() interrupt 2

{

zhi=zhi+10;

}


/*******************************************************************************

函数功能:  提示计数器溢出,超过测距范围

*******************************************************************************/

void error() interrupt 1  

  {

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

S=0;

  }

/*******************************************************************************

函数功能 : 定时器0初始化,用于计算距离

*******************************************************************************/

void Conut() 

{

if(flag==0)

{

time=TH0*256+TL0;

TH0=0;

TL0=0;

(u16)S=(time*1.7)/100;     //算出来是CM

}

}

/*******************************************************************************

函数功能 : 对计算数据做处理,并发送,同时做量程判断

*******************************************************************************/

void chuli()

{

  ES=1;                                       //打开串口中断

TI=0;

if(S<=zhi)                              //距离小于阈值cm或者距离大于测量值LED点亮,LED低电平点亮 (初始为10)

{

  LED=0;

}

else 

{

LED=1;

}

if(S==0)

{

for(i=0;i<=5;i++)

{

send(strerror[i]);

}

flag=0;

TH0=0;

TL0=0;

}

if(S>0)

{

for(i=1;S>=1;i++)

{

str[i]=(unsigned char)(S%10)+'0';

(u16)S=S/10;

}

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

{

send(str[i]);

}

send('r');

send('n');

   ES=0;                                                                    //关闭串口中断

}

}


/*******************************************************************************

函数功能 : 启动HC-SR04

*******************************************************************************/

void  Start()                                                          //启动HC-SR04需要10us高电平,一个_nop_()是1us,保险起见设置20个

  {

  Trig=1;                      

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_(); 

  _nop_();

  _nop_(); 

  _nop_(); 

  _nop_(); 

  Trig=0;                       

  }

void main()

{

T0inti();

EXinit();

    USARTinit() ;

while(1)

{

Start() ;

while(!Echo); //当Echo为零时等待

     TR0=1;     //开启计数

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

     TR0=0; //关闭计数

Conut() ;

chuli();

}

}



收获:

对于单片机串口通信有了更深理解。

模块化编程有了一些尝试。

关键字:最小系统  超声波测距 引用地址:基于51最小系统的超声波测距

上一篇:LCD液晶显示的51单片机简单计算器
下一篇:基于51单片机的呼吸灯

推荐阅读最新更新时间:2024-11-12 09:47

51单片机振荡周期时钟周期机器周期指令周期
(1)振荡周期 振荡周期指为单片机提供定时信号的振荡源的周期或外部输入时钟的周期。 (2)时钟周期 时钟周期又称作状态周期或状态时间S,它是振荡周期的两倍,分为P1节拍和P2节拍,通常在P1节拍完成算术逻辑操作,在P2节拍完成内部寄存器之间的数据传送操作。(注意P1 和P2的相位关系 ) (3)机器周期 一个机器周期由6个状态组成,如果把一条指令的执行过程分作几个基本操作,则将完成一个基本操作所需的时间称作机器周期。单片机的单周期指令执行时间就为一个机器周期。 (4)指令周期 指令周期是执行一条指令所需的全部时间。MCS-51单片机的指令周期通常由1、2、4个机器周期组成。 例:若晶
[单片机]
51单片机实现三相六拍的步进电机控制
单片机源程序如下 #include reg52.h #define uchar unsigned char #define uint unsigned int uint speed = 100; //初始转速 uint max = 200; //最慢转速 uint min = 20; //最快转速 sbit swich = P2^0; //总开关 sbit dir = P2^1;
[单片机]
<font color='red'>51</font>单片机实现三相六拍的步进电机控制
51单片机银行自动取款机模拟仿真
卡1卡2卡3键 表示插入的卡号 卡1密码是123456 余额20500 卡2密码654321余额2600 卡3密码111111 余额3700 准备钞票键表示系统以为用户准备好钞票取走钞票键表示用户取走钞票 有自动存储功能他已经存到iic中了 你没次打开的时候要初始化iic所以看不到 运行一下在再把始化的屏蔽掉在运行就行了 查询 取款 改密 退卡 都是旁边对应的键
[单片机]
<font color='red'>51</font>单片机银行自动取款机模拟仿真
利用中断结构,编制一个脉冲计数8051单片机程序
在8051单片机的INTO引脚外接脉冲信号,要求每送来一个脉冲,把30H单元值加1,若30H单元记满则进位31H单元。试利用 中断 结构,编制一个脉冲计数程序。 解: ORG 0000H AJMP MAIN ORG 0003H AJMP SUBG MAIN:MOV A,#OOH MOV 30H,A MOV 31H,A MOV SP,#70H SETB INT0 SETB EA SETB EX0 AJMP $ ORG 0200H SUBG:PUSH ACC INC 30H MOV A,30H JNZ BACK INC
[单片机]
51单片机定时器/计数器T0|T1的四种工作方式
• 选择方式0、方式1、方式2时,T0|T1的工作情况相同 • 选择方式3时,T0|T1的工作情况不同 方式0:13位定时器/计数器,TH0的高8位,TL0的低5位 方式1:16位定时器/计数器,TH0的高8位,TL0的低8位 方式2:自动重装的8位计数器,TL0用于计数,TH0用于备份 方式3:被分为TH0和TL0两个独立的8位计数器(只有T0可以在方式3下工作)
[单片机]
<font color='red'>51</font>单片机定时器/计数器T0|T1的四种工作方式
51单片机定时器初值怎么精确计算?
void main(void) { s1=1; TMOD=0x01; //使用定时器T0的模式1 TH0=(65536-46083)/256; //定时器T0的高8位设置初值 TL0=(65536-46083)%256; //定时器T0的低8位设置初值 函数功能:定时器T0的中断服务函数 ********************************************************/ void Time0(void ) interrupt 1 using 0 //定时器T0的中断编号为1,使用第1组工作寄存器 { count++; //每产生1次中断,中断累计次数加1
[单片机]
STC89C52RC单片机额外篇 | 03 - 认识C51编译器支持的数据类型
以前我们在学习C语言的时候,有C语言支持的数据类型,它们被称为标准C,现在对于51单片机,它与标准C的数据类型稍有不同,并且追加了一些关键字。 在标准C语言中基本的数据类型,例如char、int、short、long、float与double,它们存储数据的长度是有差异的,而在C51编译器中,int与short是一样的,float与double也是一样的,我们通过表格来看看它们具体的定义: 对于unsigned char、signed char、unsigned int、signed int、unsigned long、signed long这些数据类型,我们在C语言的学习中就已经用得较多,这里不再赘述。下面分别对指针型*
[单片机]
STC89C52RC单片机额外篇 | 03 - 认识C<font color='red'>51</font>编译器支持的数据类型
利用PCI1510实现PCI板卡的热插拔测试
对于普通的PCI板卡,无论是总线的硬件结构还是操作系统(如Windows序列操作系统)都不支持热插拔。在批量生产PCI板卡时,必须在关机的情况下插拔PCI板卡,然后开机测试,因此测试工作十分费时费力。本文介绍利用TI公司的PCI1510制作一个PCI-to-PCI转接卡,从硬件和软件两个方面实现PCI板卡的热插拔。 1 系统总体结构 利用PCI1510制作的PCI-to-PCI转接卡的总体结构框图如图1所示。在电气原理上类似于一款PCI总线到CardBus总线的接口电路板,但在物理形式上,CardBus总线并没有使用PCMCIA插座,而是使用PCI插座。由于PCI板卡的电源要求同PCMCIA板卡的电源要求相差很大,这款PCI-
[电源管理]
利用PCI1<font color='red'>51</font>0实现PCI板卡的热插拔测试
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved