欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 超聲波測試儀的設計仿真 [打印本頁]

作者: 紅燒鯉魚    時間: 2018-12-5 10:39
標題: 超聲波測試儀的設計仿真


#include <reg51.h>                                //預處理命令,定義SFR的頭
#include <math.h>
#include <intrins.h>                           //內部函數庫文件
#define uchar unsigned char            //定義縮寫字符uchar
#define uint unsigned int                //定義縮寫字符uint
#define lcd_data P0            //定義LCD1602接口 P0
sbit DQ =P1^7;                             //將18B20DQ位定義為P1.7引腳
sbit lcd_RS=P2^0;                           //將18B20RS位定義為P2.0引腳
sbit lcd_RW=P2^1;                           //將18B20RW位定義為P2.1引腳
sbit lcd_EN=P2^2;                           //將18B20EN位定義為P2.2引腳       
sbit BEEP=P3^0;              //測量超出指定范圍,報警  
sbit Trig=P2^5;                  //HC-SR04觸發信號輸入
sbit Echo=P2^6;                  //HC-SR04回響信號輸出
uint Distance;              //測量的距離值
uint SPEEDSOUND;            //聲速
uint t[2];              //將距離轉換成十進制數時,中間變量
uchar Buffer1[12]={0x20,0x20,0x20,0x20,0x63,0x6d,'\0'};         //距離顯示cm
uchar tab[16]={0x20,0x20,0x20,0x20,0x44,0x69,0x73,0x74,0x61,0x6e,0x63,0x65,'\0'};  //顯示"Distance"       
/**********lcd顯示子程序************/
void delay20us(void)        //20us延時
{   
  unsigned char a;   
  for(a=100;a>0;a--);
  }       

void delay_20ms(void)          /*延時20ms函數*/
{
   uchar i,temp;               //聲明變量i,temp
   for(i = 20;i > 0;i--)       //循環
   {
    temp = 248;                //給temp賦值248
    while(--temp);             //temp減1是否等于0,否則繼續執行該行
    temp = 248;                //給temp賦值248
    while(--temp);             //temp減1是否等于0,否則繼續執行該行
    }
}
void delay_38us(void)          /*延時38us函數*/
{   uchar temp;                //聲明變量temp
    temp = 18;                 //給temp賦值
    while(--temp);             //temp減1是否等于0,否則繼續執行該行
}
void delay_1520us(void)         /*延時1520us函數*/
{  uchar i,temp;                //聲明變量i,temp
   for(i = 3;i > 0;i--)         //循環
   {
    temp = 252;                 //給temp賦值
    while(--temp);              //temp減1是否等于0,否則繼續執行該行
    }
}
uchar lcd_rd_status( )          /*讀取lcd1602的狀態,主要用于判斷忙*/
{
uchar tmp_sts;                 //聲明變量tmp_sts
lcd_data = 0xff;               //初始化P3口
lcd_RW = 1;                    //RW =1  讀      
lcd_RS = 0;                    //RS =0  命令,合起來表示讀命令(狀態)
lcd_EN = 1;                    //EN=1,打開EN,LCD1602開始輸出命令數據,100nS之后命令數據有效
tmp_sts = lcd_data;            //讀取命令到tmp_sts
lcd_EN = 0;                    //關掉LCD1602
lcd_RW = 0;                    //把LCD1602設置成寫
return tmp_sts;                //函數返回值tmp_sts
}
void lcd_wr_com(uchar command )  /*寫一個命令到LCD1602*/
{
  while(0x80&lcd_rd_status()); //寫之前先判斷LCD1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續讀,直到不忙
  lcd_RW = 0;
  lcd_RS = 0;                  //RW=0,RS=0 寫命令
  lcd_data = command;          //把需要寫的命令寫到數據線上
  lcd_EN = 1;  
  lcd_EN = 0;                  //EN輸出高電平脈沖,命令寫入
}
void lcd_wr_data(uchar sjdata )  /*寫一個顯示數據到lcd1602*/
{
while(0x80&lcd_rd_status());  //寫之前先判斷lcd1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續讀,直到不忙
lcd_RW = 0;
lcd_RS = 1;                   //RW=0,RS=1 寫顯示數據
lcd_data = sjdata ;            //把需要寫的顯示數據寫到數據線上
lcd_EN = 1;
lcd_EN = 0;                   //EN輸出高電平脈沖,命令寫入
lcd_RS = 0;                 
}
void Init_lcd(void)            /*初始化lcd1602*/
{
  delay_20ms();                //調用延時
  lcd_wr_com(0x38);            //設置16*2格式,5*8點陣,8位數據接口
  delay_38us();                //調用延時
  lcd_wr_com(0x0c);            //開顯示,不顯示光標
  delay_38us();                //調用延時
  lcd_wr_com(0x01);            //清屏
  delay_1520us();              //調用延時
  lcd_wr_com(0x06);            //顯示一個數據后光標自動+1
}       
void GotoXY(uchar x, uchar y)  //設定位置,x為行,y為列
{
        if(y==0)                        //如果y=0,則顯示位置為第一行
                lcd_wr_com(0x80|x);
        if(y==1)
                lcd_wr_com(0xc0|x);           //如果y=1,則顯示位置為第二行
}

void Print(uchar *str)                   //顯示字符串函數
{
        while(*str!='\0')                   //判斷字符串是否顯示完
        {
                lcd_wr_data(*str);           //寫數據
                str++;                                  
        }
}
void LCD_Print(uchar x, uchar y, uchar *str)//x為行值,y為列值,str是要顯示的字符串   
{
  GotoXY(x,y);                                   //設定顯示位置
  Print(str);                                   //顯示字符串
}
                                                  
/****溫度轉換函數,2字節轉換為1字節 *****************/

void convert1()                       //溫度轉化程序,存放在x
{
   uchar x=0x00;                           //變量初始化
   if(t[1]>0x07)               //判斷溫度為負值
   {
    x=14;
   }
   else                    //溫度為正值
    t[1]<<=4;                           //將高字節左移4位
    t[1]=t[1]&0x70;                       //取出高字節的3個有效數字位
    x=t[0];                                   //將t[0]暫存到X,因為取小數部分還要用到它
    x>>=4;                                           //右移4位
    x=x&0x0f;                                   //和前面兩句就是取出t[0]的高四位       
    t[1]=t[1]|x;                           //將高低字節的有效值的整數部分拼成一個字節
    x=t[1];                                                                 
  }

/*******************DS18B20初始化函數**********************/

void delay_18B20(uint i)                        //延時程序
{
        while(i--);
}
void Init_DS18B20(void)                          //ds18b20初始化函數
{
         uchar x=0;
         DQ = 1;                                          //DQ復位
         delay_18B20(8);                                  //稍做延時
         DQ = 0;                                          //單片機將DQ拉低
         delay_18B20(80);                                 //精確延時大于480us
         DQ = 1;                                          //拉高總線
         delay_18B20(14);
         x=DQ;                                            //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
         delay_18B20(20);
}
uchar ReadOneChar(void)                                 //ds18b20讀一個字節函數
{
        unsigned char i=0;
        unsigned char dat0 = 0;
        for (i=8;i>0;i--)
         {
                  DQ = 0;                    //讀前總線保持為低
                  dat0>>=1;
                  DQ = 1;                    //開始讀總線釋放
                  if(DQ)                                         //從DS18B20總線讀得一位
                  dat0|=0x80;
                  delay_18B20(4);                         //延時一段時間
         }
        return(dat0);                                     //返回數據
}
void WriteOneChar(uchar dat1)                 //ds18b20寫一個字節函數
{
        uchar i=0;
        for (i=8; i>0; i--)
        {
                  DQ = 0;                                                 //開始寫入DS18B20總線要處于復位(低)狀態
                DQ = dat1&0x01;                                 //寫入下一位
            delay_18B20(5);
                DQ = 1;                                                 //重新釋放總線
            dat1>>=1;                                         //把一個字節分成8個BIT環移給DQ
}
}
void ReadTemperature()                            //讀取ds18b20當前溫度
{       
        delay_18B20(80);                //延時一段時間
        Init_DS18B20();       
        WriteOneChar(0xCC);                // 跳過讀序號列號的操作
        WriteOneChar(0x44);           // 啟動溫度轉換
        delay_18B20(80);              // 延時一段時間
        Init_DS18B20();                                //DS18B20初始化
        WriteOneChar(0xCC);                 //跳過讀序號列號的操作
        WriteOneChar(0xBE);                 //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
        delay_18B20(80);                            //延時一段時間
    t[0]=ReadOneChar();                //讀取溫度值低位
    t[1]=ReadOneChar();               //讀取溫度值高位
}

void HCSR04_Initialize()     //HCSR04初始化
{  
  SPEEDSOUND=334.1+25*0.61;   //溫度25度時聲速的值
  Trig=0;   
  Echo=0;  
  TMOD=0x01;                         //T0定時方式1
}  

float MeasuringDistance()                 //測量距離
{  
TH0=0;  TL0=0;                           //最大定時時間約65ms
  Trig=1;                                      //生成20us脈沖寬度的觸發信號
  delay20us();           //20us脈沖
  Trig=0;
  while(!Echo);                           //等待回響信號變高電平
TR0=1;                                          //啟動定時器0
  while(Echo);                            //等待回響信號變低電平
TR0=0;                  //關閉定時器0
return (SPEEDSOUND*(TH0*256+TL0))/2000; }  //返回距離值mm

void DisplayDistance()         //顯示距離
{
Distance= MeasuringDistance();
if(Distance<20)
{
BEEP=0;
}   
        t[1]=Distance/10;
    Buffer1[1]=t[1]/100+0x30;    //加0x30 為變 0~9 ASCII碼
    Buffer1[2]=(t[1]%100)/10+0x30;     //分離出十位
    Buffer1[3]=(t[1]%100)%10+0x30;     //分離出個位       
    LCD_Print(4,1,Buffer1);             //顯示距離
}                    

/*************************main主程序*********************/
void main(void)
{
    uchar x;
        BEEP=1;                          //關閉報警   
        delay_20ms();           //系統延時20ms啟動
           Init_lcd();                        //調用LCD初始化函數
        delay_20ms();                                           //延時一段時間
        LCD_Print(0,0,tab);
    HCSR04_Initialize();                           //HC-SR04初始化
    while(1)
        {
        ReadTemperature();            //測溫度,存放在t[1]t[0]
    delay_18B20(100);
    convert1();               //溫度轉換,存放在x
        if(x<14)                       //溫度界限判斷
     x=14;
    else if(x>26)  
         x=26;
    SPEEDSOUND=334.1+x*0.61;    //聲速修正M/S
        DisplayDistance();                //顯示距離值
    }
   }


搜狗截圖18年12月05日1038_2.png (35.21 KB, 下載次數: 45)

搜狗截圖18年12月05日1038_2.png

8超聲測距.rar

86.89 KB, 下載次數: 6, 下載積分: 黑幣 -5






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