標(biāo)題: 超聲波測(cè)距程序就是不能顯示測(cè)出的距離,單片機(jī)程序沒(méi)錯(cuò)誤,求大佬們教我如何解決 [打印本頁(yè)]

作者: lj2443454061    時(shí)間: 2022-4-6 17:22
標(biāo)題: 超聲波測(cè)距程序就是不能顯示測(cè)出的距離,單片機(jī)程序沒(méi)錯(cuò)誤,求大佬們教我如何解決
程序沒(méi)有錯(cuò)誤
/*
計(jì)算公式
我們知道聲速是340m/s
根據(jù)x=vt
因?yàn)槌暡òl(fā)送出去和回來(lái)是測(cè)量距離的兩倍,所以假設(shè)距離是L
2L=344xt
t我們用定時(shí)器測(cè)出來(lái)
一般都是us
所以就是tx172x10的-6次方=L,L單位為cm
最終的出 L= t(us) * 0.0172(cm/us)
0.0172=1/58
所以 L= t(us)/58(cm)


對(duì)于51單片機(jī),12mhz的周期時(shí)間為1us
所以11.059200mzh的計(jì)算公式為
L = 計(jì)數(shù) x(12/11.0592) x (1/58)
= 計(jì)數(shù) x 0.0187
= (計(jì)數(shù) 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;//回響信號(hào)輸出
sbit Trig = P2^1;//觸發(fā)信號(hào)輸入


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個(gè)數(shù)據(jù)位
u16 i = 0;


//對(duì)使用到函數(shù)進(jìn)行聲明定義
void StartModule();
void Timer0Init(void);
void Conut(void);




/******************************************
* 函 數(shù) 名         : main
* 函數(shù)功能                   : 主函數(shù)
* 輸    入         : 無(wú)
* 輸    出         : 無(wú)
*******************************************/
void main(void)
{        
        Timer0Init();
        LCD_Init();              //液晶初始化
        LCD_Write_String(4,0,di);//液晶第一行顯示字符“Distance”
        
        while(1)//獲取一次超聲波測(cè)距模塊的距離
        {
               
                 StartModule();
             while(!Echo);                //當(dāng)Echo為零時(shí)等待
             TR0=1;                            //開啟
             while(Echo);                //當(dāng)Echo為1計(jì)數(shù)并等待
             TR0=0;                                //關(guān)閉
         Conut();                        //計(jì)算
         DelayMs(10);
        }
}


/*-------------啟動(dòng)超聲波模塊------------*/
void StartModule()         
{
          Trig=1;//啟動(dòng)一次模塊
   
          _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延時(shí)10us程序
      void Delay10us_51(void)
      {
          u8 i=15;
          _nop_();
          while(--i);
      }
      */


void Timer0Init(void)        
{
        TMOD &= 0xF0;
        TMOD |= 0x01;                //設(shè)T0為方式1
        TH0 = 0;
        TL0 = 0;
    TF0 = 0;                   //清除TF0標(biāo)志        
        ET0 = 1;           //允許T0中斷
        EA = 1;                           //開啟總中斷
    TR0 = 1;               //開啟定時(shí)器0
}




/*--------------距離計(jì)算模塊------------*/
void Conut(void)
{
         time=TH0*0x100+TL0;    //獲取時(shí)間 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));       //獲取距離——計(jì)數(shù)出來(lái)的是M
         if( s>= 400 )//超出測(cè)量范圍顯示“-”
         {         
         
          LCD_Write_Char(4, 1, ASCII[11]);//液晶第二行第4個(gè)點(diǎn)陣顯示ASCII[]第11個(gè)數(shù)據(jù)'-',一下以此類推!!
          LCD_Write_Char(5, 1, ASCII[10]);//顯示點(diǎn)
          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]);//顯示點(diǎn)
          LCD_Write_Char(6, 1, ASCII[disbuff[1]]);//顯示百位
          LCD_Write_Char(7, 1, ASCII[disbuff[2]]);//顯示十位
          LCD_Write_Char(8, 1, ASCII[disbuff[3]]);//顯示個(gè)位
          LCD_Write_Char(9, 1, ASCII[12]);//顯示M
         }
}

作者: lj2443454061    時(shí)間: 2022-4-6 17:23
仿真不能出數(shù)據(jù),怎么解決

51hei圖片20220406172057.png (43.79 KB, 下載次數(shù): 37)

51hei圖片20220406172057.png

作者: lkc8210    時(shí)間: 2022-4-6 23:09
試試在while(1)之前加個(gè)DelayMs(1000);
作者: lj2443454061    時(shí)間: 2022-4-7 19:53
lkc8210 發(fā)表于 2022-4-6 23:09
試試在while(1)之前加個(gè)DelayMs(1000);

還是不能顯示數(shù)據(jù),還要其他的方法嗎
作者: lkc8210    時(shí)間: 2022-4-7 21:14
lj2443454061 發(fā)表于 2022-4-7 19:53
還是不能顯示數(shù)據(jù),還要其他的方法嗎

我又沒(méi)有l(wèi)cd.h和delay.h
作者: lj2443454061    時(shí)間: 2022-4-8 10:17
lkc8210 發(fā)表于 2022-4-7 21:14
我又沒(méi)有l(wèi)cd.h和delay.h

#ifndef __LCD_H_
#define __LCD_H_

/**********************************
包含頭文件
**********************************/
#include <reg52.h>
#include "intrins.h"

//---重定義關(guān)鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

/**********************************
            PIN口定義
**********************************/
sbit EN = P2^7;
sbit RW = P2^5;
sbit RS = P2^6;

/**********************************
            函數(shù)聲明
**********************************/
void busy();//忙檢測(cè)函數(shù)

/*LCD1602寫入8位命令子函數(shù)*/
void LCD_Write_Com(unsigned char cmd);

/*LCD1602寫入8位數(shù)據(jù)子函數(shù)*/       
void LCD_Write_Data(unsigned char dat);

/*LCD1602初始化子程序*/               
void LCD_Init(void);

void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);

void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);
                                                  

#endif



#ifndef __DELAY_H__
#define __DELAY_H__

void DelayUs2x(unsigned char t);

void DelayMs(unsigned char t);

#endif





作者: lj2443454061    時(shí)間: 2022-4-8 10:48
#include "lcd.h"

//---------------------------------------------------------------------
//函數(shù):判忙函數(shù)
//功能:判斷液晶是否忙碌
void busy()
{
        uchar sta;
        P0= 0xFF;                //P0初始化
        RS = 0;                        //選擇指令寄存器
        RW = 1;                        //讀模式
        do
        {
                EN = 1;
                _nop_();
                sta = P0;         //讀取狀態(tài)字
                EN = 0;                //當(dāng)E端由高電平跳變成低電平時(shí),液晶模塊執(zhí)行命令
               
        }
        while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重復(fù)檢測(cè)直到其等于 0 為止
}

//---------------------------------------------------------------------
//函數(shù):寫命令函數(shù)
//功能:向液晶寫入一字節(jié)命令(8位命令), cmd-待寫入命令值
void LCD_Write_Com(unsigned char cmd)
{
        busy(); //判斷液晶是否忙碌
        RS = 0; //選擇指令寄存器
        RW = 0; //寫模式
        P0 = cmd;//把數(shù)據(jù)給P0,即寫入指令和地址
        EN = 1;
    _nop_();//短暫延時(shí)1us
        _nop_();//短暫延時(shí)1us       
        EN = 0;        //當(dāng)E端由高電平跳變成低電平時(shí),液晶模塊執(zhí)行命令
       
}

//---------------------------------------------------------------------
//函數(shù):寫數(shù)據(jù)函數(shù)
//功能:向液晶寫入一字節(jié)數(shù)據(jù)(8位數(shù)據(jù)), dat-待寫入數(shù)據(jù)值
void LCD_Write_Data(unsigned char dat)
{
        busy(); //判斷液晶是否忙碌
        RS = 1; //選擇數(shù)據(jù)寄存器
        RW = 0; //寫模式
        P0= dat;//把數(shù)據(jù)給P0
        EN = 1;
        _nop_();//短暫延時(shí)1us
        _nop_();//短暫延時(shí)1us               
        EN = 0;        //當(dāng)E端由高電平跳變成低電平時(shí),液晶模塊執(zhí)行命令
       
}


//---------------------------------------------------------------------
//函數(shù):初始化液晶函數(shù)
//功能:初始化液晶,并顯示啟動(dòng)界面
void LCD_Init()
{
        LCD_Write_Com(0x38); //16*2 顯示, 5*7 點(diǎn)陣, 8 位數(shù)據(jù)傳送
        LCD_Write_Com(0x0C); //顯示器開,光標(biāo)關(guān)閉
        LCD_Write_Com(0x06); //文字不動(dòng),地址自動(dòng)+1
        LCD_Write_Com(0x01); //清屏
       
}


//---------------------------------------------------------------------
/*函數(shù):寫入字符函數(shù)*/
//功能:設(shè)置顯示 DDRAM 起始地址,亦即光標(biāo)位置, (x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo)
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{     
    if (y == 0) //由輸入的屏幕坐標(biāo)計(jì)算顯示 DDRAM 的地址
        {     
        LCD_Write_Com(0x80 + x); //第一行字符地址從 0x80 起始   
        }   
    else
        {     
        LCD_Write_Com(0xC0 + x); //第二行字符地址從 0xc0起始   
        }        
    LCD_Write_Data( Data);           //寫數(shù)據(jù)-設(shè)置 DDRAM 地址
}

/*函數(shù):寫入字符串函數(shù)*/
//可參考網(wǎng)上的
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{            
    while (*s) //先取 s 指向的數(shù)據(jù),然后s自加 1,指向下一個(gè)待寫字符
    {     
        LCD_Write_Char(x,y,*s);     
        s++;  
        x++;   
    }
}




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1