找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2126|回復(fù): 12
打印 上一主題 下一主題
收起左側(cè)

這個(gè)單片機(jī)超聲波程序,別的占用一個(gè)定時(shí)器怎么解決?為什么定時(shí)器0的中斷進(jìn)不...

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 10 黑幣 回復(fù)本帖可獲得 1 黑幣獎(jiǎng)勵(lì)! 每人限 10 次
跳轉(zhuǎn)到指定樓層
#
ID:515826 發(fā)表于 2022-4-1 16:01 | 只看該作者 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
#include<reg51.h>        //包含頭文件
#include"18b20.h"        //包含溫度讀取文件
#include<stdio.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

//--定義使用的IO--//
#define GPIO_DIG P0                 //定義GPIO_DIG代替P0

sbit servorControl =P1^6;  //舵機(jī)的控制引腳
sbit Trig=P1^7;            //控制端
sbit Echo=P3^3;          //接收端

sbit K1=P3^4;
sbit K2=P3^5;
sbit K3=P3^6;                         //按鍵定義
sbit HE=P3^2;                         //霍爾傳感器
sbit BUZZ=P1^2;                         //蜂鳴器
sbit relay=P1^4;                 //吹風(fēng)繼電器
sbit relay_w=P1^3;                 //加熱繼電器


//--定義全局變量
unsigned char code DIG_CODE[17]={
0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,
0xdf,0xd7,0x77,0x7c,0x39,0x5e,0x79,0x8b};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的顯示碼
unsigned char DisplayData[8];
//用來存放要顯示的8位數(shù)的值
//--聲明全局變量--//

uchar control=5;
uchar servorTime=0;

unsigned char key_num;
unsigned char flag_d;
unsigned int count_HE;
unsigned int flag_HE;
unsigned char sec_bj=0,sec_gb=0,m=0;
int TH;
bit flag_js_gb=0;
bit flag_js_bj=0;
bit flag_bj=0;
//--聲明全局函數(shù)--//
void LcdDisplay(int,unsigned char);
void DigDisplay();
void delay(unsigned int xms)         //延時(shí)函數(shù)
{
  unsigned int i;
  unsigned char j;
  for(i=0;i<xms;i++)
  for(j=0;j<110;j++);
}

void Delay_us(unsigned char t)
{
        while(--t);
}         //大約延時(shí)t*2+5us         超聲波模塊用

void keyscan()                                   //按鍵函數(shù)
{
        if(K1==0)                                   //設(shè)置按鍵按下
        {
                delay(20);                           //延時(shí)去抖
                if(K1==0)                           //再次判斷按鍵按下
                {
                        key_num=!key_num;  //設(shè)置變量取反,也就是按一下設(shè)置鍵進(jìn)入設(shè)置,再按一下就退出設(shè)置狀態(tài)
                        while(K1==0)           //按鍵是否松開,沒有松開就執(zhí)行下面的程序,松開后跳出
                        {
                                if(key_num==1)                        //設(shè)置狀態(tài)
                                LcdDisplay(TH*100,1);        //顯示上限值
                                else
                                LcdDisplay(tvalue,0);        //否則顯示正常值
                        }
                }
        }
        if(K2==0&&key_num==1)                          //設(shè)置狀態(tài)時(shí)加按鍵按下
        {
                delay(20);                                          //延時(shí)去抖
                if(K2==0&&key_num==1)                  //設(shè)置狀態(tài)時(shí)按鍵按下
                {
                        if(TH<98)                                  //上限如果小于98,就讓變量加,也就是最大可以加到99
                        TH++;                                          //上限加
                        else                                          //否則
                        TH=20;                                          //上限值賦值20
                        while(K2==0) LcdDisplay(TH*100,1);           //按鍵松開后顯示設(shè)置值
                }
        }
        if(K3==0&&key_num==1)                                         //注釋同加按鍵
        {
                delay(20);
                if(K3==0)
                {
                        if(TH>1)                //大于1就減
                        TH--;
                        else
                        TH=99;
                        while(K3==0)LcdDisplay(TH*100,1);
                }
        }
}
/*******************************************************************************
* 函 數(shù) 名         : main
* 函數(shù)功能                   : 主函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/

void main()
{

        unsigned int time,distance;        
        uchar a=0,b=0,c=0,d=0,i=0;

        TH=30;                  //上電初始值30
        EX0=0;                  //關(guān)閉外部中斷
        IT0=1;                  //下降沿有效
        EA=1;                  //打開中斷系統(tǒng)總開關(guān)
        TMOD=0x11;          //定時(shí)器工作方式
        TH0=0x3c;
        TL0=0xb0;          //定時(shí)器0賦初值50ms
        TH1=0xff;
        TL1=0x9c;
        ET0=1;                  //T0中斷允許
        ET1=1;
        TR0=1;                  //開啟T0計(jì)時(shí)
        servorTime=0;
        Trig=0;
        Echo=0;
        while(1)          //進(jìn)入while循環(huán)
        {

                Trig=1;
                Delay_us(5);
                Trig=0;
                while(Echo==0);                                
                a=TL0;
                b=TH0;
                while(Echo);
                c=TL0;
                d=TH0;
                time=(d-b)*256+(c-a);
                distance=(int)(time*0.017);                           //計(jì)算路程 單位為cm

                read_wendu();                         //讀溫度
                keyscan();                                 //按鍵掃描
                if(key_num==0)                         //判斷狀態(tài),是否是設(shè)置狀態(tài)
                LcdDisplay(tvalue,0);         //顯示正常值
                else
                LcdDisplay(TH*100,1);         //顯示設(shè)置值
                if(distance<=30)                                 //紅外傳感器有信號(hào)
                {

                        relay_w=0;                         //加熱繼電器打開
                        flag_js_bj=1;                 //計(jì)時(shí)報(bào)警標(biāo)志位置1
                        flag_js_gb=0;                 //計(jì)時(shí)關(guān)閉標(biāo)志位清零
                        EX0=1;                                 //關(guān)閉外部中斷

                        if(distance<=20)                                        //如果距離小于30cm 蜂鳴器響
                        {
                                if(distance<=10)                                        //如果距離小于30cm 蜂鳴器響
                                {
                                        control=15;   //使舵機(jī)向正擺動(dòng)
                                    servorTime=0;
                                    TR1=1;
                                    delay(200);
                                    TR1=0;
                                }
                                else
                                {
                                        control=12;   //使舵機(jī)向正擺動(dòng)
                                    servorTime=0;
                                    TR1=1;
                                    delay(200);                                
                                    TR1=0;
                                }
                        }
                        else
                        {
                                  control=9;   //使舵機(jī)向正擺動(dòng)
                            servorTime=0;
                            TR1=1;
                            delay(200);                        
                            TR1=0;
                        }

                }
                else                                         //沒有信號(hào)
                {
                        flag_js_gb=1;                 //計(jì)時(shí)關(guān)閉標(biāo)志位值1
                        flag_js_bj=0;                 //計(jì)時(shí)報(bào)警標(biāo)志位清零

                        control=5;   //使舵機(jī)向右擺動(dòng)
                    servorTime=0;
                    TR1=1;
                    delay(200);               
                    TR1=0;
                        delay(200);                        
                }


                if(flag_d&&flag_HE==1)         //溫度是否小于設(shè)置值
                {
                        relay=0;                         //打開加熱繼電器
                        count_HE=0;
                        flag_HE=0;
                }
                else
                {
                        count_HE++;                          //霍爾的狀態(tài)計(jì)數(shù)變量,計(jì)到一定時(shí)間(此值不精確,就是一個(gè)短延時(shí)的作用)關(guān)閉繼電器
                        if(count_HE>10&&relay==0||flag_d==0)  //計(jì)到時(shí)間或者溫度達(dá)到設(shè)置值
                        relay=1;                                         //關(guān)閉繼電器
                }
        }
}

/*******************************************************************************
* 函 數(shù) 名         : LcdDisplay()
* 函數(shù)功能                   : LCD顯示讀取到的溫度
* 輸    入         : v
* 輸    出         : 無
*******************************************************************************/

void LcdDisplay(int temp,unsigned char flag)          //lcd顯示
{
           float tp;  
        unsigned char i,k;
        unsigned int j;
        if(temp< 0&&flag==0)                                //當(dāng)溫度值為負(fù)數(shù)
          {
                DisplayData[1] = 0x80;
                //因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;        
                flag_d=1;                  //負(fù)溫度值時(shí)肯定需要加熱,所以變量為1
                //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
                //后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
                //算由?.5,還是在小數(shù)點(diǎn)后面。

          }
         else if(flag==0)
          {                        
               
                tp=temp;
                temp=tp*0.0625*100+0.5;        
            DisplayData[1] = DIG_CODE[temp / 10000];
                if(temp/10000==0)
                DisplayData[1]=0x00;
                if(temp<TH*100)         //溫度值小于設(shè)置值
                flag_d=1;                 //變量置1
                else                         //大于等于設(shè)置值時(shí)
                flag_d=0;                 //為0
        }
        if(flag==1)
        DisplayData[1] = DIG_CODE[15];
        DisplayData[2] = DIG_CODE[temp % 10000 / 1000];
        if(temp<1000)
        DisplayData[2]=0x00;
        DisplayData[3] = DIG_CODE[temp % 1000 / 100] | 0x20;
        DisplayData[4] = DIG_CODE[temp % 100 / 10];
        DisplayData[5] = DIG_CODE[temp % 10];
         for(k=0;k<8;k++)
        for(i=0;i<4;i++)
        {
                switch(i)         //位選,選擇點(diǎn)亮的數(shù)碼管,
                {
                        case(0):
                                  P2=0xef; break;//顯示第0位
                        case(1):
                                  P2=0xdf; break;//顯示第1位
                        case(2):
                                  P2=0xbf; break;//顯示第2位
                        case(3):
                                  P2=0x7f; break;//顯示第3位
                }
                GPIO_DIG=DisplayData[i+1];//發(fā)送段碼
                j=50;                                                 //掃描間隔時(shí)間設(shè)定
                while(j--);        
                GPIO_DIG=0x00;//消隱
        }
}
void waibu() interrupt 0          //外部中斷服務(wù)函數(shù),也就是霍爾元件檢測(cè)到信號(hào)就會(huì)有外部中斷
{
        if(flag_d)                                  //溫度是否小于下限,小于就進(jìn)入
                {
                relay=0;                          //啟動(dòng)吹風(fēng)繼電器
                count_HE=0;                          //霍爾計(jì)數(shù)變量清零
                flag_HE=0;                          //霍爾標(biāo)志位清零
                }
}
void T0_time() interrupt 1          //T0函數(shù)
{
        TH0=0x3c;
        TL0=0xb0;                                  //重新賦初值
        m++;                                  //每50ms加一次
        if(m>=1)                                  //加到20次就是1秒
        {        
                m=0;                                  //清零
                if(flag_js_gb==1)          //計(jì)時(shí)關(guān)閉標(biāo)志位
                {
                        sec_gb++;                  //關(guān)閉計(jì)時(shí)秒變量++
                        if(sec_gb>=3)          //加到3秒
                        {
                                sec_gb=0;          //清零
                                sec_bj=0;
                                flag_js_bj=0; //清零
                                flag_bj=0;
                                relay_w=1;
                                relay=1;          //關(guān)閉兩個(gè)繼電器
                                EX0=0;                  //關(guān)閉外部中斷
                        }        
                }
                if(flag_js_bj==1)          //計(jì)時(shí)報(bào)警標(biāo)志位
                {
                        sec_bj++;                  //報(bào)警計(jì)時(shí)秒變量++
                        if(sec_bj>=5)          //加到60秒
                        {
                                sec_bj=0;
                                sec_gb=0;          //兩個(gè)變量都清零
                                flag_js_gb=0; //關(guān)閉標(biāo)志位清零
                                flag_bj=1;          //啟動(dòng)報(bào)警標(biāo)志位
                        }
                }
                if(flag_bj==1)                  //報(bào)警標(biāo)志位為1
                {
                        BUZZ=!BUZZ;                  //蜂鳴器取反閃爍報(bào)警
                }
                else                                  //沒有進(jìn)入報(bào)警
                {
                        BUZZ=1;                          //關(guān)閉蜂鳴器
                }
        }
}
void T1_int(void) interrupt 3{   //產(chǎn)生舵機(jī)所需要的脈沖
  TH1=0xff;
  TL1=0x9c;
  servorTime++;
  if(servorTime<=control)
   servorControl=1;
  else
   servorControl=0;
   if(servorTime>=200)
   servorTime=0;
}

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

使用道具 舉報(bào)

12#
ID:515826 發(fā)表于 2022-4-2 11:00 | 只看該作者
lkc8210 發(fā)表于 2022-4-2 09:38
可以用定時(shí)器1的中斷啊~
每次進(jìn)入中斷就是100us
進(jìn)入10000次就是一秒

有說是定時(shí)器初始化的時(shí)候1把0的參數(shù)破壞了,也有說是方式?jīng)]設(shè)置好,咋弄啊幫我看一下
回復(fù)

使用道具 舉報(bào)

11#
ID:515826 發(fā)表于 2022-4-2 10:54 | 只看該作者
SURUBU1976 發(fā)表于 2022-4-2 09:57
你定時(shí)器1沒開啟

開了 在后面用舵機(jī)的時(shí)候開了
回復(fù)

使用道具 舉報(bào)

10#
ID:515826 發(fā)表于 2022-4-2 10:52 | 只看該作者
lkc8210 發(fā)表于 2022-4-2 09:38
可以用定時(shí)器1的中斷啊~
每次進(jìn)入中斷就是100us
進(jìn)入10000次就是一秒

定時(shí)器1已經(jīng)給舵機(jī)用了
為什么舵機(jī)在用定時(shí)器1的時(shí)候定時(shí)器0好像不能用了,屏蔽1的時(shí)候0就好了
回復(fù)

使用道具 舉報(bào)

9#
ID:507641 發(fā)表于 2022-4-2 09:57 | 只看該作者
你定時(shí)器1沒開啟
回復(fù)

使用道具 舉報(bào)

8#
ID:161164 發(fā)表于 2022-4-2 09:38 來自觸屏版 | 只看該作者
liguohan 發(fā)表于 2022-4-1 18:33
就是計(jì)時(shí)超過一分鐘蜂鳴器響,還有超聲波關(guān)閉后兩個(gè)繼電器延時(shí)三秒后關(guān)閉

可以用定時(shí)器1的中斷啊~
每次進(jìn)入中斷就是100us
進(jìn)入10000次就是一秒
然后用這個(gè)一秒又可以得出三秒和一分鐘
回復(fù)

使用道具 舉報(bào)

7#
ID:515826 發(fā)表于 2022-4-1 18:33 | 只看該作者
lkc8210 發(fā)表于 2022-4-1 18:18
那個(gè)中斷是用來干什么滴?

就是計(jì)時(shí)超過一分鐘蜂鳴器響,還有超聲波關(guān)閉后兩個(gè)繼電器延時(shí)三秒后關(guān)閉
回復(fù)

使用道具 舉報(bào)

6#
ID:161164 發(fā)表于 2022-4-1 18:18 來自觸屏版 | 只看該作者
liguohan 發(fā)表于 2022-4-1 16:04
超聲波模塊計(jì)算距離的時(shí)候用到定時(shí)器0,但是程序還要一個(gè)定時(shí)器來進(jìn)中斷怎么辦?定時(shí)器1給舵機(jī)用了

那個(gè)中斷是用來干什么滴?
回復(fù)

使用道具 舉報(bào)

5#
ID:515826 發(fā)表于 2022-4-1 18:11 | 只看該作者
zhxiufan 發(fā)表于 2022-4-1 17:51
超聲波測(cè)距用一個(gè)定時(shí)器就可以了。使用過程中如果定時(shí)器不夠用,也可以分時(shí)使用的方法來實(shí)現(xiàn)。

這個(gè)分時(shí)使用要怎么寫 通過控制TR0實(shí)現(xiàn)碼?
回復(fù)

使用道具 舉報(bào)

地板
ID:121859 發(fā)表于 2022-4-1 17:51 | 只看該作者
超聲波測(cè)距用一個(gè)定時(shí)器就可以了。使用過程中如果定時(shí)器不夠用,也可以分時(shí)使用的方法來實(shí)現(xiàn)。
回復(fù)

使用道具 舉報(bào)

板凳
ID:515826 發(fā)表于 2022-4-1 16:40 | 只看該作者
進(jìn)定時(shí)器0中斷里的關(guān)閉標(biāo)志位的那個(gè)延時(shí)三秒不行咋搞?
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:515826 發(fā)表于 2022-4-1 16:07 | 只看該作者
為什么定時(shí)器0的中斷進(jìn)不去,可是如果縮短定時(shí)器1的中斷的時(shí)間舵機(jī)就不能啟動(dòng)怎么辦?
回復(fù)

使用道具 舉報(bào)

樓主
ID:515826 發(fā)表于 2022-4-1 16:04 | 只看該作者
超聲波模塊計(jì)算距離的時(shí)候用到定時(shí)器0,但是程序還要一個(gè)定時(shí)器來進(jìn)中斷怎么辦?定時(shí)器1給舵機(jī)用了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表