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

被折叠的 条评论
为什么被折叠?



