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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1424|回復: 3
打印 上一主題 下一主題
收起左側

單片機超聲波測距程序加入了舵機控制后無法實時測量?

[復制鏈接]
跳轉到指定樓層
樓主
ID:582255 發表于 2022-4-17 22:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
51單片機超聲波測距,通過DHT11測溫進行修正,距離小于1時控制舵機轉動,為什么總是不能實時刷新數據?通過控制中斷開關能夠刷新數據(沒辦法的辦法),但是單片機有抖動,請教一下高手怎么解決實時刷新的問題啊
#include <reg51.h>        
#include "lcd.h"
#include <intrins.h>
/*對數據類型進行聲明定義*/
typedef unsigned int u16;         
typedef unsigned char u8;
/*外設IO定義*/
sbit Data = P3^7; //定義DHT11數據線
sbit Trig = P1^2;
sbit Yellow = P2^3;
sbit Echo = P1^3;
sbit  Distance1 = P1^0;
/*尾部超聲波定義*/

sbit Red = P2^4;
sbit Green = P2^2;
sbit pwm = P2^0;
/*變量定義*/
u16 Distance=0;

//sbit Yellow = 0 ;
bit flag =0;                 
u8 TEMP = 25 ,HR,count=0,ct,angle=1;//采集值

void DHT11_delay_ms(u16 z)
{
   u16 i,j;
   for(i=z;i>0;i--)
      for(j=110;j>0;j--);
}
void DHT11_delay_us(u8 n)
{
    while(--n);
}

void DHT11_start()
{
   Data=1;
   DHT11_delay_us(2);
   Data=0;
   DHT11_delay_ms(30);   //延時18ms以上
   Data=1;
   DHT11_delay_us(30);
}

u8 DHT11_rec_byte()      //接收一個字節
{
   u8 i,dat=0;
   for(i=0;i<8;i++)    //從高到低依次接收8位數據
   {         
      while(!Data);   ////等待50us低電平過去
      DHT11_delay_us(8);     //延時60us,如果還為高則數據為1,否則為0
      dat<<=1;           //移位使正確接收8位數據,數據為0時直接移位
      if(Data==1)    //數據為1時,使dat加1來接收數據1
         dat+=1;
      while(Data);  //等待數據線拉低   
    }  
    return dat;
}

void DHT11_receive()      //接收40位的數據
{
        u8 R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  DHT11_start();
  if(Data==0)
        {
                while(Data==0);   //等待拉高     
                DHT11_delay_us(40);  //拉高后延時80us
                R_H=DHT11_rec_byte();    //接收濕度高八位  
                R_L=DHT11_rec_byte();    //接收濕度低八位  
                T_H=DHT11_rec_byte();    //接收溫度高八位  
                T_L=DHT11_rec_byte();    //接收溫度低八位
                revise=DHT11_rec_byte(); //接收校正位
                DHT11_delay_us(25);    //結束
                if((R_H+R_L+T_H+T_L)==revise)      //校正
                {
                                RH=R_H;
                                RL=R_L;
                                TH=T_H;
                                TL=T_L;
                }
                /*數據處理,方便顯示*/
                TEMP=TH;
                HR=RH;
        }
        DisplayOneChar(5,0,'0'+(TEMP/10));
        DisplayOneChar(6,0,'0'+(TEMP%10));
        DisplayOneChar(12,0,'0'+(HR/10));
        DisplayOneChar(13,0,'0'+(HR%10));
}
void GetDistance() //超聲波測距
{
        static u16 time=0;
        count++;
        TH0=0;
    TL0=0;
        
        Trig=1; //啟動一次模塊
  //時間要求很嚴格,否則會影響精度
        _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();
        _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();
        _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();
        Trig=0;
        
        while(!Echo);                //當RX為零時等待
        TR0=1;                            //開啟計數
        while(Echo);                //當RX為1計數并等待
        TR0=0;                                  //關閉計數
               
        time=TH0*256+TL0;//計算時間
        TH0=0;
        TL0=0;
        Distance=(time*(331.4+0.607*TEMP))/20000;//算出來是CM,帶溫度補償

        if((Distance>=330)||flag==1) //超出測量范圍顯示“-”
        {         
                flag=0;
                DisplayOneChar(5, 1, '-');
                DisplayOneChar(6, 1, '-');
                DisplayOneChar(7, 1, '-');
        }
        else
        {
                DisplayOneChar(5, 1, Distance/100+'0');
                DisplayOneChar(6, 1, '.');
                DisplayOneChar(7, 1, Distance%100/10+'0');
                DisplayOneChar(8, 1, Distance%10+'0');
        }
        

}

void Timer0Init()//定時器0初始化
{
        //TMOD|=0x01;                   //設T0為方式1,GATE=1;
        TMOD=0x11;
        TH0=0;
        TL0=0;         
        ET0=1;        //允許T0中斷
        EA=1;                           //開啟總中斷
                TH1=0xfc;        
                TL1=0x66;         
                        ET1=1;
                        TR1= 1;                                
}

void main(void)
{
        Distance1=1;
        Timer0Init();
        LcdInit();        
        Trig=0;//初始化必不可少!!!

        DisplayListChar(0,0,"TEMP:");DisplayOneChar(7,0,'C');DisplayListChar(9,0,"HR:");DisplayOneChar(14,0,'%');
  DisplayListChar(0,1,"DIS:");DisplayListChar(9,1,"M");
    //EA=0;
        while(1)
        {        
                EA=1;
                GetDistance(); //超聲波測距

                if((Distance<100) && (Distance1 == 1) )
                   {
                     Yellow = 0 ;
                         Red = 1 ;
                         Green = 1 ;
                         angle = 1 ;
                         EA=0;
                   }
                if   ((Distance<100) && (Distance1 == 0) )
                    {
                     Yellow = 1 ;
                         Red = 0 ;
                         Green = 1 ;
                         angle = 2 ;
                         EA=0;
                    }
                if   (Distance>100)
                        {
                     Yellow = 1 ;
                         Red = 1 ;
                         Green = 0 ;
                         angle = 1 ;
                         EA=0;
                    }
               
                //DHT11_delay_ms(20);
                if(count>20)
                {
                   DHT11_receive();//溫濕度顯示
                   count = 0;
                }
        }
                        
}
void Timer0() interrupt 1                  //T0中斷用來計數器溢出,超過測距范圍
{
        flag=1;        //中斷溢出標志
}
void Time1_Int() interrupt 3//舵機
{
        
        TH1=0xfc;         
        TL1=0x66;         
        if(ct<angle)//判斷1ms次數是否小于角度標識
    pwm=1;//確實小于,pwm輸出高電平
    else
    pwm=0;//大于則輸出低電平
        ct=(ct+1);//1ms次數加1
        ct=ct%20;//次數始終保持為20即保持周期為20ms
        //if(count>=20)count=0;
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:582255 發表于 2022-4-18 13:17 | 只看該作者
為什么不能實時刷新
回復

使用道具 舉報

板凳
ID:123289 發表于 2022-4-18 16:19 | 只看該作者
沒有細看,提示:時序上有沖突嗎?(如在某個時刻,干著A,B干不成了。)
回復

使用道具 舉報

地板
ID:161164 發表于 2022-4-19 14:37 | 只看該作者
舵機定時器的中斷延誤了DHT11的電平檢測
導致程序在while(Data)死循環了
在用while(XXX)的時候應加上超時條件
以防止死循環
例:
  1. u8 DHT11_rec_byte()      //接收一個字節
  2. {
  3.    u8 i,dat=0, j=0;
  4.    for(i=0;i<8;i++)    //從高到低依次接收8位數據
  5.    {         
  6.       while(!Data);   ////等待50us低電平過去
  7.       DHT11_delay_us(8);     //延時60us,如果還為高則數據為1,否則為0
  8.       dat<<=1;           //移位使正確接收8位數據,數據為0時直接移位
  9.       if(Data==1)    //數據為1時,使dat加1來接收數據1
  10.          dat+=1;
  11.                         j=0;
  12.       while(Data && j++<250);  //等待數據線拉低   
  13.     }  
  14.     return dat;
  15. }
復制代碼




回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品91| 精品日韩| 日韩视频一区在线观看 | 丝袜美腿av| 久久精品播放 | 免费av直接看 | 亚卅毛片 | 亚洲视频欧美视频 | 日本大香伊一区二区三区 | 久久综合狠狠综合久久综合88 | 日韩精品久久 | 免费看黄色视屏 | 成年人在线观看 | 伦理二区 | 成年精品 | 91国内产香蕉| 丁香五月缴情综合网 | 欧美午夜精品久久久久久浪潮 | 成人特区 | 黄色片免费| 狠狠躁夜夜躁人人爽天天高潮 | 国产精品电影在线观看 | 伊人手机在线视频 | 91久久精品视频 | 欧美精品一二三区 | 四虎影音| 天天艹日日干 | 久草欧美视频 | 国产精品91网站 | 亚洲综合小视频 | 欧美日韩综合一区 | 在线观看av免费 | 成人国产精品 | 国产一区二区三区免费 | 成人av影院 | 在线日韩av电影 | 一区二区三区四区不卡 | 视频一区欧美 | 欧美精品在线一区 | 美女天堂在线 | 亚洲自拍偷拍欧美 |