1. 程式人生 > >STC15微控制器使用HC-SR04超聲波測距模組

STC15微控制器使用HC-SR04超聲波測距模組

目錄

【HC-SR04】

基本工作原理

時序圖

【程式】


【HC-SR04】

HC-HR04超聲波測距可提供2cm-400cm的非接觸式距離感測功能,測距精度可達3mm。

基本工作原理

1、採用IO口TRIG觸發測距,給最少10us的高電平信呈。

2、模組自動傳送8個40KHz的方波,自動檢測是否有訊號返回。

3、有訊號返回,通過IO口ECHO輸出一個高電平,高電平持續時間就是超聲波從發射到返回的時間。測試距離=(高電平時間*聲速(340m/s))/2.

時序圖

以上時序圖表明你只需要提供一個10uS以上脈衝觸發訊號,該模組內部將:發出8個40kHz週期電平並檢測回波。一.旦檢測到有回波訊號則輸出迴響訊號。迴響訊號的脈衝寬度與所測的距離成正比。由此通過發射訊號到收到的迴響訊號時間間隔可以計算得到距離。公式: uS/58=釐米或者uS/148=英寸;或是:距離=高電平時間*聲速(340M/S) /2;建議測量週期為60ms以上,以防止發射訊號對迴響訊號的影響。


【程式】

我使用的是STC15F2K60S2微控制器,內部晶振設定12M。以下程式省略管腳定義等無關語句,僅提供程式思路供參考。

uchar Flag_hypertelorism = 0;		//超聲波距離過遠標誌
float distance = 0;
uchar Flag_Fucker = 0;				//超聲波開啟標誌

void main()
{
    Time0_Init();
    Time1_Init();
    while(1)
    {
        if(Flag_Fucker == 1)
            Ultrasonic();
    }
}

/*初始化定時器0*/
void Time0_Init(void)
{
//	AUXR |= 0x80;                   //定時器0為1T模式
	AUXR &= 0x7f;                   //定時器0為12T模式
	
    TMOD = 0x00;                    //設定定時器為16位自動重灌載
    TL0 = 0x60;                     //初始化計時值 4ms
    TH0 = 0xF0;
    TR0 = 1;                        //定時器0開始計時
    ET0 = 1;                        //使能定時器0中斷
    EA = 1;
}

//定時器1初始化
void Time1_Init()
{
//	AUXR |= 0x40;                   //定時器1為1T模式
	AUXR &= 0xdf;                   //定時器1為12T模式
	
    TMOD = 0x00;                    //設定定時器1為16位自動重灌載
    TL1 = 0x60;                     //初始化計時值 4ms
    TH1 = 0xF0;	
//  TR1 = 1;                     	//暫時不開啟定時器1計時
	ET1 = 1;                        //使能定時器1中斷
    EA = 1;
}

/*定時器0中斷*/
void Time0 () interrupt 1
{
	static uchar time = 0;
//	自動裝載模式下可省略
//	TL0 = T0MS; 
//  TH0 = T0MS >> 8;
	time++;
	
	if(time == 25)					//100ms測距一次
	{
		time = 0;
		Flag_Fucker = 1;
	}
}

//定時器1溢位中斷
void Time1() interrupt 3
{
	Flag_hypertelorism = 1;			//超聲波距離過遠
}

//超聲波測距
void Ultrasonic()
{
	uchar i;
	
	Trig = 1;						//超聲波觸發訊號開啟
	_nop_();						//延時10us以上
	i = 30;
	while(--i);
	Trig = 0;						//超聲波觸發訊號關閉
	while(!Echo);					//Echo為0時等待
	TR1 = 1;						//開啟定時器1計時
	while(Echo == 1 && TF1 == 0);	//Echo為1時等待
	TR1 = 0;						//關閉定時器1計時
	Distance_Count();				//計算距離
	Flag_Fucker = 0; 				//關閉超聲波測距
}

//距離值計算
void Distance_Count()
{
	float Text_time = 0;
	if(Flag_hypertelorism == 0)
	{
		Text_time = ((TH1 - temp_TH) * 256 + (TL1 - temp_TL)) / 2.0;
		TL1 = 0x60;                     //初始化計時值 4ms
		TH1 = 0xF0;	
		distance = Text_time * 0.34;	//單位mm
	}
	else
	{
		distance = 9999;
		Flag_hypertelorism = 0;
	}
}