程序沒有錯誤
/*
計算公式
我們知道聲速是340m/s
根據x=vt
因為超聲波發送出去和回來是測量距離的兩倍,所以假設距離是L
2L=344xt
t我們用定時器測出來
一般都是us
所以就是tx172x10的-6次方=L,L單位為cm
最終的出 L= t(us) * 0.0172(cm/us)
0.0172=1/58
所以 L= t(us)/58(cm)
對于51單片機,12mhz的周期時間為1us
所以11.059200mzh的計算公式為
L = 計數 x(12/11.0592) x (1/58)
= 計數 x 0.0187
= (計數 x 1.87)/100(cm)
*/
#include "reg52.h"
#include "lcd.h"
#include "intrins.h"
#include "delay.h"
typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;
sbit Echo = P2^0;//回響信號輸出
sbit Trig = P2^1;//觸發信號輸入
u8 di[]="Distance";//液晶顯示:Distance(距離)
u8 code ASCII[13] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
u16 time = 0;
u16 s = 0;
u8 disbuff[4] = {0,0,0,0,};//提供4個數據位
u16 i = 0;
//對使用到函數進行聲明定義
void StartModule();
void Timer0Init(void);
void Conut(void);
/******************************************
* 函 數 名 : main
* 函數功能 : 主函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************/
void main(void)
{
Timer0Init();
LCD_Init(); //液晶初始化
LCD_Write_String(4,0,di);//液晶第一行顯示字符“Distance”
while(1)//獲取一次超聲波測距模塊的距離
{
StartModule();
while(!Echo); //當Echo為零時等待
TR0=1; //開啟
while(Echo); //當Echo為1計數并等待
TR0=0; //關閉
Conut(); //計算
DelayMs(10);
}
}
/*-------------啟動超聲波模塊------------*/
void StartModule()
{
Trig=1;//啟動一次模塊
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();/*可以生成10us脈沖,此處可以使用Delay10us_51();代替*/
Trig=0;
}
/*
51延時10us程序
void Delay10us_51(void)
{
u8 i=15;
_nop_();
while(--i);
}
*/
void Timer0Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01; //設T0為方式1
TH0 = 0;
TL0 = 0;
TF0 = 0; //清除TF0標志
ET0 = 1; //允許T0中斷
EA = 1; //開啟總中斷
TR0 = 1; //開啟定時器0
}
/*--------------距離計算模塊------------*/
void Conut(void)
{
time=TH0*0x100+TL0; //獲取時間 0x100=256 TH0*0x100+TL0=256
/*也可以寫成
1、time=TH0*256+TL0;
2、time=TH0<<8|TL0;
*/
//重置初值
TH0=0;
TL0=0;
//s=(time/58.0/100.0)*1000; 與下面的一樣意思
s=((u16)(time/58.0)); //獲取距離——計數出來的是M
if( s>= 400 )//超出測量范圍顯示“-”
{
LCD_Write_Char(4, 1, ASCII[11]);//液晶第二行第4個點陣顯示ASCII[]第11個數據'-',一下以此類推!!!
LCD_Write_Char(5, 1, ASCII[10]);//顯示點
LCD_Write_Char(6, 1, ASCII[11]);
LCD_Write_Char(7, 1, ASCII[11]);
LCD_Write_Char(8, 1, ASCII[11]);
LCD_Write_Char(9, 1, ASCII[12]);//顯示M
}
else
{
disbuff[0]=s/1000%10;
disbuff[1]=s/100%10;
disbuff[2]=s/10%10;
disbuff[3]=s/1%10;
LCD_Write_Char(4, 1, ASCII[disbuff[0]]);//顯示千位
LCD_Write_Char(5, 1, ASCII[10]);//顯示點
LCD_Write_Char(6, 1, ASCII[disbuff[1]]);//顯示百位
LCD_Write_Char(7, 1, ASCII[disbuff[2]]);//顯示十位
LCD_Write_Char(8, 1, ASCII[disbuff[3]]);//顯示個位
LCD_Write_Char(9, 1, ASCII[12]);//顯示M
}
}
|