久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1621|回復: 0
收起左側

超聲波測試儀的設計仿真

[復制鏈接]
ID:439809 發表于 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

8超聲測距.rar

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

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品一区二区三区四区 | 亚洲一区在线播放 | 亚洲 日本 欧美 中文幕 | 欧美日韩一二三区 | 精品久久久久久久人人人人传媒 | 日韩网站在线观看 | 一区二区免费 | 一区二区三区中文字幕 | 精品久久久久一区二区国产 | 羞羞在线观看视频 | 欧美成视频 | 午夜在线观看免费 | 精品国产一级片 | 日韩一区二区三区视频 | 国产精品一区二区三区99 | 在线视频亚洲 | 伊人精品一区二区三区 | 91免费入口| 99国产精品视频免费观看一公开 | 日日日干干干 | 成人h视频在线观看 | 国产乱码精品一区二三赶尸艳谈 | 免费污视频 | 日韩欧美在线观看 | 久操亚洲 | 中文字幕一区二区三区四区 | 91视频网址 | 成人精品一区二区 | 欧美狠狠操 | 亚洲第一视频网站 | 亚洲一区二区在线播放 | 成人区一区二区三区 | 日韩中文不卡 | 久久精品小视频 | 国产精品国产精品国产专区不片 | 色成人免费网站 | 精品国产一区二区在线 | 蜜桃毛片| 欧美1区| 天天夜碰日日摸日日澡 | 精品视频99 |