藍橋杯 — 超聲波測距模塊的使用

目錄

 

1、測距原理

2、超聲波原理圖

3、用到的頭文件說明

4、實現超聲波傳感器功能


1、測距原理

超聲波測距的原理是利用超聲波在空氣中的傳播速度爲已知,測量聲波在發射後遇到障礙物反射回來的時間,根據發射和接收的時間差計算出發射點到障礙物的實際距離。

超聲波發射器向某一方向發射超聲波,在發射時刻的同時開始計時,超聲波在空氣中傳播,途中碰到障礙物就立即返回來,超聲波接收器收到反射波就立即停止計時。超聲波在空氣中的傳播速度爲340m/s,根據計時器記錄的時間t,就可以計算出發射點距障礙物的距離(s),即:s=340t/2 。這就是所謂的時間差測距法。

這都是忽略了其它因素,如:溫度等,在代碼中聲速給定爲340m/s。精確度達到cm級。

2、超聲波原理圖

發射部分:JS2爲發射模塊,由NA1控制。

 接收部分:JS1爲接收模塊,由NB1控制。

Rb3集電器:可以用於調節

其它部分: 

在藍橋杯單片機的競賽綜合平臺CT107D中,超聲波模塊的TX引腳接到單片機的P1.0端口,RX引腳接到單片機的P1.1端口。在進行藍橋杯超聲波模塊測試前,要把跳線帽J2中的1—3,2—4相連接(sonic),這樣上述模塊就互相連接在一起了,然後在P10接口發射超聲波,P11接口接收超聲波。如果接收到反射回來的信號,P11(RX)引腳變爲低電平。

3、用到的頭文件說明

#include "intrins.h"

intrins.h,函數,應用於程序設計,一般出現在C51單片機編程中,一般程序中需要使用到空指令_nop_();字符循環移位指令_crol_等時使用。

內部函數:

_crol_ 字符循環左移

_cror_ 字符循環右移

_irol_ 整數循環左移

_iror_ 整數循環右移

_lrol_ 長整數循環左移

_lror_ 長整數循環右移

_nop_ 空操作 (相當於8051 NOP 指令)

_testbit_ 測試並清零位 (相當於8051 JBC 指令)

4、實現超聲波傳感器功能

下面是實現超聲波功能的代碼,最大測量距離爲99cm。

#include<STC15F2K60S2.H>
#include "intrins.h"

#define uchar unsigned char 
#define uint unsigned int	

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();}	//空指令操作
sbit TX = P1^0;  //	發射引腳
sbit RX = P1^1;  //接受引腳

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};//0-9,-,全滅
uchar yi,er,san,si,wu,liu,qi,ba;

unsigned int intr = 0;
bit s_flag;
unsigned int t = 0;

void send_wave(void);
void Timer0Init(void);
void Timer1Init(void);

void delayms(int ms);
void allinit();
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);

void main()
{
	unsigned int distance;
	
	Timer0Init();
    Timer1Init();

	EA = 1;
	ET0 = 1;  //打開定時器0中斷
	
	allinit();
	yi=11;er=11;san=11;si=11;wu=11;liu=0;qi=0;ba=0;
	
	while(1)
	{
		if(s_flag) // 200毫秒更新一次數據 
		{
			s_flag = 0;
			send_wave();  //發送方波信號
			TR1 = 1;  //啓動計時
			while((RX == 1) && (TF1 == 0));  //等待接受到脈衝
			TR1 = 0;  //關閉計時		
			
			if(TF1 == 1)//發生溢出
			{
				TF1 = 0;
				distance = 9999;  //無返回
			}
			else
			{		
				t = TH1;// 計算時間 
				t <<= 8;
				t |= TL1;
				distance = (unsigned int)(t*0.017);  //計算距離
				distance = distance/12;
			}
			TH1 = 0;
			TL1 = 0;
		}
		  						 
		liu = distance/100;
		qi = distance%100/10;
		ba = distance%10; 
		
		display1(yi,er);
		display2(san,si);
		display3(wu,liu);
		display4(qi,ba);
	}
}

void Timer0Init(void)		//2ms @11.0592MHz
{
	AUXR |= 0x80;		//定時器時鐘1T模式
	TMOD &= 0xF0;		//設計定時器模式  	TMOD=0X01;
	TL0 =(65536-2000)%256;		//設置定時器初值
	TH0 =(65536-2000)/256;		//設置定時器初值
	TF0 = 0;		//清除TF0標誌
	TR0 = 1;		//定時器0開始計時
}

void Timer1Init(void)		//2ms @11.0592MHz
{
	AUXR |= 0x40;		//定時器時鐘1T模式
	TMOD &= 0x0F;		//設計定時器模式  	TMOD=0X02;
}

//定時器0中斷服務函數
void isr_timer_0(void)  interrupt 1  //默認定時器中斷1
{
    TL0 =(65536-2000)%256;		//設置定時器初值
	TH0 =(65536-2000)/256;		//設置定時器初值

	if(++intr == 100)
	{
		s_flag = 1;
		intr = 0;
  }
}

//TX引腳發送40kHZ方波信號驅動超聲波發送探頭
void send_wave(void)
{
	unsigned char i = 8;  //發送8個脈衝
	
	do
	{
		TX = 1;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;		
		TX = 0;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;		
	}
	while(i--);
}


void delayms(int ms)
{
	int i,j;
	for(i=ms;i>0;i--)
		for(j=400;j>0;j--);
}

void allinit()
{
	P2=0XA0;
	P0=0X00;//關閉蜂鳴器、繼電器
	
	P2=0X80;
	P0=0XFF;//關閉LED燈
	
	P2=0XC0;
	P0=0XFF;//選擇所有的數碼管
	P2=0XFF;
	P0=0XFF;//關閉所有數碼管
}

void display1(uchar yi,uchar er)
{
		P2=0XC0;//打開位選573   U8
		P0=0X01;//選擇第一個數碼管
		P2=0XFF;//打開斷選573   U7
		P0=tab[yi];
		delayms(1);
		
		P2=0XC0;//打開位選573   U8
		P0=0X02;//選擇第二個數碼管
		P2=0XFF;//打開斷選573   U7
		P0=tab[er];
		delayms(1);
}	

void display2(uchar san,uchar si)
{
		P2=0XC0;
		P0=0X04;//選擇第三個數碼管
		P2=0XFF;
		P0=tab[san];
		delayms(1);
		
		P2=0XC0;
		P0=0X08;//選擇第四個數碼管
		P2=0XFF;
		P0=tab[si];
		delayms(1);
}

void display3(uchar wu,uchar liu)
{
		P2=0XC0;
		P0=0X10;//選擇第五個數碼管
		P2=0XFF;
		P0=tab[wu];
		delayms(1);
		
		P2=0XC0;
		P0=0X20;//選擇第六個數碼管
		P2=0XFF;
		P0=tab[liu];
		delayms(1);
}

void display4(uchar qi,uchar ba)
{
		P2=0XC0;
		P0=0X40;//選擇第七個數碼管
		P2=0XFF;
		P0=tab[qi];
		delayms(1);
		
		P2=0XC0;
		P0=0X80;//選擇第8個數碼管
		P2=0XFF;
		P0=tab[ba];
		delayms(1);
}

上述代碼可以加以修改如下:

#include<stc15f2k60s2.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}

sbit TX=P1^0;
sbit RX=P1^1;

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar f1,f2,f3,f4,f5,f6,f7,f8;
unsigned int count;
bit num;
unsigned int t=0;

void Time0_Init();
void Timer1_Init();
void delay();
void all_Init();
void send_wave();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);

void main(){
unsigned int distance;
Time0_Init();
Timer1_Init();
EA=1;
ET0=1;
all_Init();
f1=11,f2=11,f3=11,f4=11,f5=11,f6=0,f7=0,f8=0;
while(1){
if(num==1)
  {
    num=0;
	send_wave();
	TR1=1;
	while ((RX==1)&&(TF1==0));
	TR1=0;
	if(TF1==1)
	{
	  TF1=0;
	  distance=9999;
	}
	else
	{
	t=TH1;
	t <<= 8;
	t|=TL1;
	distance=(unsigned int)(t*0.017);
	distance=distance/12;
	}
	TH1=0;
	TL1=0;
	}
f6=distance/100;
f7=distance%100/10;
f8=distance%100%10;

display12(f1,f2);
display34(f3,f4);
display56(f5,f6);
display78(f7,f8);
}
}

void Time0_Init()
{
AUXR|=0X80;
TMOD&=0XF0;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TF0=0;
TR0=1;
}

void service_Time0() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
count++;
if(count==100)
{	 
     num=1;
	 count=0;
}
}
 
void Timer1_Init(){
AUXR|=0X40;
TMOD&=0X0F;
}

void delay(){
int j,k;
for(j=0;j<1;j++)
for(k=0;k<400;k++);
}

void all_Init(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void send_wave(){
uchar i=8;
do
{
  TX=1;
  somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
  TX=0;
  somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
}
while(i--);
}

void display12(uchar f1,uchar f2)
{
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delay();
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delay();
}

void display34(uchar f3,uchar f4)
{
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delay();
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delay();
}

void display56(uchar f5,uchar f6)
{
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delay();
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delay();
}


void display78(uchar f7,uchar f8)
{
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delay();
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delay();
}


        
 

 超聲波實現的代碼,要做到知道每一步的操作過程,具體代碼有何用處,多加練習,最後應該不會有太大問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章