天天看點

基于藍橋杯的單片機子產品練習——超音波測距基于藍橋杯的單片機子產品練習——超音波測距

基于藍橋杯的單片機子產品練習——超音波測距

功能概述

利用超音波子產品測量距離并顯示在數位管的後三位,機關是cm。如果距離超出量程,就在第一位顯示‘F’

#include "stc15f2k60s2.h"

/*
Debug 總結:

*/

sbit TX = P1^0; // 發射引腳
sbit RX = P1^1; // 接收引腳
unsigned char code SMG_duanma[] = {0xc0,0xf9,0xa4,0xb0,
                                   0x99,0x92,0x82,0xf8,
                                   0x80,0x90,0x88,0x83,
                                   0xc6,0xa1,0x86,0x8e,
                                   0xbf,0x7f
                                  }; 

unsigned char Segbuff[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
unsigned int distance = 0;
bit flag = 0;

void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 0 : P2 = (P2 & 0X1F) | 0X00;break;
		case 4 : P2 = (P2 & 0X1F) | 0X80;break;
		case 5 : P2 = (P2 & 0X1F) | 0Xa0;break;
		case 6 : P2 = (P2 & 0X1F) | 0Xc0;break;
		case 7 : P2 = (P2 & 0X1F) | 0Xe0;break;
	}
}

void InitSystem()
{
	SelectHC573(5);
	P0 = 0x00;
	SelectHC573(4);
	P0 = 0xFF;
	SelectHC573(0);
}

void DispalySMG_Bit(unsigned char pos, unsigned char dat)
{
/**********消隐效果最佳******************/	
	SelectHC573(7);
	P0 = 0xff;//關閉所有段選
	SelectHC573(6);
	P0 = 0x01 << pos;	
	SelectHC573(0);
	P0 = 0xff;	
	SelectHC573(7);
	P0 = dat;	
SelectHC573(0);
/**********消隐效果最佳******************/	 	
}

void Timer1_Init()
{
	TMOD = 0X00;
	TH1 = (65536 - 1000) / 256;
	TL1 = (65536 - 1000) % 256;
	EA = 1;
	ET1 = 1;
	TR1 = 1;
}

void Measure_Distance()
{
	unsigned char num = 10;//??個方波信号
	unsigned int time = 0;
	
	TMOD &= 0xf0;
	//方波信号的頻率要在38-40khz,是以用定時器0制造一個周期為26us的占空比為50%的方波信号
  TH0 = (65536 - 13) / 256;
	TL0 = (65536 - 13) % 256;
	TR0 = 1;
	TX = 0;
	while(num--)//連續發送8個波
	{
		while(TF0 == 0);
		TX = ~TX;
		TF0 = 0;		
	}//花費大約208us

	TR0 = 0;//發送完信号立即關閉定時器
	TL0 = 0; // 設定定時初值
  TH0 = 0; // 設定定時初值
  TR0 = 1;
	while((RX == 1) && (TF0 == 0));    //等待超音波信号傳回或者等到測量超出範圍
	TR0 = 0;            //停止定時器				
//**************最好嚴格按照這種if else 的格式寫,否則容易出bug************	
	if(TF0 == 0)	            //正常測量範圍							
	{
		time = TH0;									
		time = (time << 8) | TL0;		
		distance = time*0.017;//機關是cm,計算方法是:【(time/1000000)*340】/2*100
	}
	else                        //超出測量範圍			
	{
		TF0 = 0;
		distance = 9999;
	}
//**************最好嚴格按照這種if else 的格式寫,否則容易出bug************
}



void Display_Distance()
{
	if(distance == 9999)
	{
		Segbuff[0] = SMG_duanma[15];			//超出測量範圍标志:F
		Segbuff[1] = 0xff;
		Segbuff[2] = 0xff;
		Segbuff[3] = 0xff;
		Segbuff[4] = 0xff;
		Segbuff[5] = 0xff;
		Segbuff[6] = 0xff;
		Segbuff[7] = 0xff;
	}
	else
	{
		Segbuff[0] = 0xff;		
		Segbuff[1] = 0xff;
		Segbuff[2] = 0xff;
		Segbuff[3] = 0xff;
		Segbuff[4] = 0xff;
		Segbuff[5] = SMG_duanma[distance / 100];
		Segbuff[6] = SMG_duanma[(distance % 100) / 10];
		Segbuff[7] = SMG_duanma[distance % 10];
		
	}
}



void main()
{
	InitSystem();
	Timer1_Init();
	while(1)
	{
		
	 if(flag)//間隔200ms測量一次資料
	 {
		  Measure_Distance();
		 flag = 0;
	 }

    Display_Distance();
  }
}

void Timer1_Service() interrupt 3
{
	
  static unsigned char pos = 0;
	static unsigned char t_1ms = 0;
	t_1ms++;
  switch(pos)
	{
		case 0 : DispalySMG_Bit(pos, Segbuff[0]);pos++;P0 = 0XFF;break;
		case 1 : DispalySMG_Bit(pos, Segbuff[1]);pos++;P0 = 0XFF;break;
		case 2 : DispalySMG_Bit(pos, Segbuff[2]);pos++;P0 = 0XFF;break;
		case 3 : DispalySMG_Bit(pos, Segbuff[3]);pos++;P0 = 0XFF;break;
		case 4 : DispalySMG_Bit(pos, Segbuff[4]);pos++;P0 = 0XFF;break;
		case 5 : DispalySMG_Bit(pos, Segbuff[5]);pos++;P0 = 0XFF;break;
		case 6 : DispalySMG_Bit(pos, Segbuff[6]);pos++;P0 = 0XFF;break;
		case 7 : DispalySMG_Bit(pos, Segbuff[7]);pos = 0;P0 = 0XFF;break;
	}
	if(t_1ms == 200)
	{flag = 1;t_1ms = 0;}
	
}
           

相關知識點

基于藍橋杯的單片機子產品練習——超音波測距基于藍橋杯的單片機子產品練習——超音波測距

使用超音波子產品之前記得要短接1、3和短接2、4

注意:一定要間隔一段時間再測量距離,本例程中間隔了200ms。如果在while循環裡不斷地使用測量函數的話,會造成數位管顯示在一直跳變。

原因是,上一次的資料剛測量完成,還沒來得及顯示穩定,又立馬執行了Measure_Distance()函數,數值又發生了變化,這樣就會表現在數位管在不同測量值之間快速的跳變,你根本看不出結果是多少。

繼續閱讀