蓝桥杯(单片机组)学习笔记(七)---------超声波

本文详细介绍了HC-SR04超声波模块的工作原理及使用方法,包括其接口说明、基本工作流程,以及如何利用单片机进行超声波测距的程序设计。通过实例代码展示了如何发送40kHz脉冲并计算回波时间来测量距离。

1.超声波(ultrasound)
调试相当重要,推荐一篇在线调试的帖子,在需要的时候(特别是后面的STM32)

1.简介
我用的超声波是HC-SR04,一共有四个接口,分别是Gnd,Echo(接收端),Trig(控制端),Vcc接口。(是插在蓝牙接口上面共用的)。
基本工作原理:
(1)采用IO口TRIG触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,即可以达到你移动测量的值
在这里插入图片描述
在这里插入图片描述
2.原理图
在这里插入图片描述

在这里插入图片描述
可以看到最终是由P10/P11控制的接收。(用跳线帽连接)
使用单片机发送8个40KHz的脉冲,然后开启定时器计时就好了。
3.程序设计
在这里插入图片描述
特别注意的是,我这里不需要用到中断,直接计数就行,所以ETX=1(控制定时器中断),EA = 1(总中断)都不用加。直接读出没有溢出(TF1 != 1)时的TH1和TL1就行了,再进行转换。
假设我用的时12Mhz,定时器1方式0(16位自动重装初值的定时/计数器),1T分频的定时器,那么最终的计算是:
12*1/(12M)= 1US(一次计数所需要的时间) Distance = TIME(s) * 340/2 * 1us ,转换成cm就是0.017 * time。
贴一下超声波发射的代码和定时器计数的代码

#include <STC12C5A60S2.H>
#include "intrins.h"
typedef unsigned char uchar;
typedef unsigned int uint;

#define somenop {_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();};

sbit Trig = P1^0;//发射引脚
sbit Echo = P1^1;//接收引脚

bit flag_400ms = 0;
code uchar tab[] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uchar disbuff[8] = {10,10,10,10,10,10,10,10};  //显示缓冲区
uchar discom = 0;
uint distance = 988;//检查超声波有没有工作



void ceju(void);
void Send_Wave();
void Timer0Init(void);
void Timer1Init(void);

void Send(void);
	

void All_Init()
{
	P2 = (P2&0X1F|0X80);
	P0 = 0XFF;
	
	P2 = (P2&0X1F|0XA0);
	P0 = 0X00;
	
	P2 =(P2&0X1F|0XC0);
	P0 = 0X00;
	
	P2 = (P2&0X1F|0XE0);
	P0 = 0XFF;
}

void main(void)
{
	All_Init();
	Timer0Init();
	Timer1Init();
	while(1)
	{
		ceju();
	}
	
}
	
void Send_Wave()
{
	uchar i =8;//8个40khz的脉冲
	while(i--)
	{
		Trig = 1;
		somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;
		Trig = 0;
		somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;
	}
}

void ceju(void)
{
	int t;
	if(flag_400ms)
		{
			flag_400ms =0;
			Send_Wave();
			TR1 = 1;
			while((Echo == 1)&&(TF1 == 0));
			TR1 = 0;
			if(TF1)//如果TF1真的溢出了
			{
				TF1 = 0;
				distance = 999;//没有检测到
			}
			else
			{
				t = TH1<<8|TL1;
				distance = (uint)(t*0.017);
			}
			disbuff[0] = distance%10;//个
			disbuff[1] = distance/10%10;
			disbuff[2] = distance/100;
			TH1 = 0;
			TL1 = 0;
			distance = 0;
	
		}
}


void Timer0Init(void)		//2毫秒,用来每400ms检测一次超声波
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x40;		//设置定时初值
	TH0 = 0xA2;		//设置定时初值
	EA =1;
	ET0 =1;
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

void Timer0Inter() interrupt 1
{
	static int i;
	if(++i == 200)
	{
		flag_400ms = 1;
		i = 0;
	}
	display();
}

void Timer1Init(void)//用于计数
{
	AUXR |= 0x80;//1T
	TMOD &= 0x0F;  //定时器1方式0
	TL1 = 0;		//设置定时初值,从零开始计数
	TH1 = 0;		//设置定时初值
	TF1 = 0;        //清除TF1标志
	TR1 = 0;        //定时器先不忙计数
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值