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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3408|回復: 13
收起左側

單片機儲物箱檢測程序中斷嵌套程序 請高手幫改一下

[復制鏈接]
ID:280226 發表于 2018-2-12 22:42 | 顯示全部樓層 |閱讀模式
寫了一個儲物箱檢測程序,思路是當物品放置時,壓下微動開關,進入中斷程序,繼電器接通設定的時間;這部分程序測試正常,但現在有個問題搞不定,就是當進入中斷程序后,如果拿開物品,中斷程序還得繼續完成,如何在中斷程序中嵌入一個判斷程序,在K開關復位后自動退出中斷程序回到主程序?謝謝!
  1. #include <reg52.h>
  2. typedef unsigned int u16;
  3. typedef unsigned char u8;
  4. unsigned int s;
  5. sbit k=P1^0;          //微動開關
  6. sbit Relay1 =P0^0;   //繼電器端口
  7. sbit Relay2 =P0^1;
  8. bit  fir=0;           //物品存在標志位
  9. /***********************************************
  10. 定時函數
  11. ************************************************/
  12. void Timer0Init(void)
  13. {
  14.          
  15.          TMOD = 0x01;            
  16.          TL0 = 0xB0;               
  17.          TH0 = 0x3C;               
  18.          EA=1;
  19.          ET0=1;
  20.          TR0 = 1;               
  21. }
  22. /***********************************************
  23. 主函數
  24. ************************************************/
  25. int main()
  26. {
  27.          Relay1=1;
  28.         Relay2=1;
  29.         Timer0Init();
  30.          while(1)
  31. {  
  32.   if((k==1)&&(fir==0))
  33.   {
  34.        TR0=1;                 //有物品時開始計時
  35.        Relay1=0;              //繼電器通電
  36.        Relay2=0;  
  37.                  }
  38.         }
  39. }
  40. /***********************************************
  41. 中斷函數
  42. ************************************************/
  43. void Timer0() interrupt 1   
  44. {
  45.         u16 temp;
  46.         s=1;      //改變S可改變定時時間
  47.          TL0 = 0xB0;               
  48.          TH0 = 0x3C;               
  49.          temp++;
  50.          if(temp==(20*60)*s)      
  51.          {
  52.                  temp=0;
  53.                  Relay1=1;   //繼電器斷電
  54.                  Relay2=1;
  55.                  fir=1;        //標志位置1
  56.            }
  57. }
復制代碼


回復

使用道具 舉報

ID:273292 發表于 2018-2-13 08:57 | 顯示全部樓層
你這箱子壓下去的開關本來就是中斷觸發的信號,如這個信號沒了自然就沒法繼續在中斷呆著了,不知道有沒有高手
回復

使用道具 舉報

ID:282439 發表于 2018-2-13 09:09 | 顯示全部樓層
你需要將TEMP聲明為全局變量。因為TIMER0是中斷程序。退出后不能保持TEMP的數值了。
回復

使用道具 舉報

ID:280226 發表于 2018-2-13 09:45 | 顯示全部樓層
希望高手能直接在程序中幫修改一下,這樣對照就能知道程序缺陷在哪了,謝謝!
回復

使用道具 舉報

ID:280226 發表于 2018-2-13 10:31 | 顯示全部樓層
第一個程序有個缺陷,就是把物品拿開后再進入,因為物品標志位為1,就再進不了中斷程序。現又把程序完善了一下,在物品拿開后標志位置0,這樣在物品離開再進入時就可以再進入中斷程序了。現在就是在中斷過程中如果物品拿開,無法立即退出中斷程序,這個求教高手。
#include <reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
unsigned int s;
sbit k=P1^0;          //微動開關
sbit Relay1 =P0^0;   //繼電器端口
sbit Relay2 =P0^1;
bit  fir=0;           //物品存在標志位
/***********************************************
定時函數
************************************************/
void Timer0Init(void)
{
         
         TMOD = 0x01;            
         TL0 = 0xB0;               
         TH0 = 0x3C;               
         EA=1;
         ET0=1;
         TR0 = 1;               
}
/***********************************************
主函數
************************************************/
int main()
{
         Relay1=1;
        Relay2=1;
        Timer0Init();
         while(1)
{  
  if((k==1)&&(fir==0))
  {
       TR0=1;                 //有物品時開始計時
       Relay1=0;              //繼電器通電
       Relay2=0;  
                 }
    if((k==0)$$(fir==1))
  {
   fir=0;
   }
        }
}
/***********************************************
中斷函數
************************************************/
void Timer0() interrupt 1   
{
        u16 temp;
        s=5;      //改變S可改變定時時間
         TL0 = 0xB0;               
         TH0 = 0x3C;               
         temp++;
         if(temp==(20*60)*s)      
         {
                 temp=0;
                 Relay1=1;   //繼電器斷電
                 Relay2=1;
                 fir=1;        //標志位置1
           }
}
回復

使用道具 舉報

ID:213173 發表于 2018-2-13 19:38 | 顯示全部樓層
xmcai 發表于 2018-2-13 10:31
第一個程序有個缺陷,就是把物品拿開后再進入,因為物品標志位為1,就再進不了中斷程序。現又把程序完善了 ...

參看我在“請問怎么寫這個10s燈滅的語句 幫下忙解解惑”http://www.zg4o1577.cn/bbs/dpj-107271-1.html中的回復,程序邏輯功能幾乎完全一致。
回復

使用道具 舉報

ID:280226 發表于 2018-2-14 11:32 | 顯示全部樓層
wulin 發表于 2018-2-13 19:38
參看我在“請問怎么寫這個10s燈滅的語句 幫下忙解解惑”http://www.zg4o1577.cn/bbs/dpj-107271-1.html中的 ...

試了您的程序,時間長了就不行了,我需要有個15分鐘左右的時間。
回復

使用道具 舉報

ID:280226 發表于 2018-2-14 12:29 | 顯示全部樓層
wulin 發表于 2018-2-13 19:38
參看我在“請問怎么寫這個10s燈滅的語句 幫下忙解解惑”http://www.zg4o1577.cn/bbs/dpj-107271-1.html中的 ...

參考您的程序,再修改了中斷程序,現在完美解決了,可以延時任意時間了。謝謝解答。
回復

使用道具 舉報

ID:213173 發表于 2018-2-14 14:09 | 顯示全部樓層
xmcai 發表于 2018-2-14 11:32
試了您的程序,時間長了就不行了,我需要有個15分鐘左右的時間。

我是說這個程序邏輯功能幾乎與你的要求完全一致,至于定時時間的長短是可以任意設定的。改成定時15分鐘:
#include <AT89X52.H>
#define uint unsigned int
#define uchar unsigned char
sbit key=P3^4;          //按鍵端口定義        
sbit LED=P1^0;          //發光管端口定義
uchar Cnt50ms=0;        //中斷計數變量
uint Cnt1s=0;           //中斷計數變量
void Timer0Init()       //50毫秒@12.000MHz
{
        TMOD= 0x01;          //設置定時器模式
        TL0 = 0xB0;          //設置定時初值
        TH0 = 0x3C;          //設置定時初值
//  TF0 = 0;            //清除TF0標志
//  TR0 = 1;            //定時器0開始計時
        EA=1;                //開總中斷
        ET0=1;               //開定時器0中斷        
}
void keyscan()
{
        static bit key_sign=0;        //按鍵有效標志
        static uint  count=0;        //計數變量                        
        if(key==0)                    //檢測按鍵如果為0
        {
                count++;                 //消抖計數
                if((count>=500)&&(key_sign==0))
                {                        
                        key_sign=1;           //按鍵有效標志置1
                        Cnt50ms=0;            //中斷計數變量清0
                        Cnt1s=0;              //中斷計數變量清0
                        TR0 = 1;              //啟動定時器
                        LED=0;                //發光管亮
                }
        }
        else                          //按鍵抬起
        {
                key_sign=0;               //按鍵有效標志清0
                count=0;                  //消抖計數清0
                LED=1;                    //發光管滅
                TR0=0;                    //關閉定時器
        }
}
void main()
{
        Timer0Init();              //定時器0初始化
        while(1)
        {
                keyscan();             //按鍵掃描
        }
}
void timer0() interrupt 1        //定時器0中斷
{
        TL0 = 0xB0;                 //設置定時初值
        TH0 = 0x3C;                  //設置定時初值
        Cnt50ms++;
        if(Cnt50ms>=20)             //1秒
        {
                Cnt50ms=0;
                Cnt1s++;
                if(Cnt1s>=900)                        //15分鐘
                {
                        Cnt1s=0;
                        LED=1;           //發光管滅
                        TR0=0;           //關閉定時器
                }
        }
}

評分

參與人數 1黑幣 +100 收起 理由
admin + 100 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:280226 發表于 2018-2-14 14:41 | 顯示全部樓層
wulin 發表于 2018-2-14 14:09
我是說這個程序邏輯功能幾乎與你的要求完全一致,至于定時時間的長短是可以任意設定的。改成定時15分鐘: ...

謝謝您的幫忙,已完美解決。
回復

使用道具 舉報

ID:280226 發表于 2018-2-14 16:19 | 顯示全部樓層
wulin 發表于 2018-2-14 14:09
我是說這個程序邏輯功能幾乎與你的要求完全一致,至于定時時間的長短是可以任意設定的。改成定時15分鐘: ...

在此基礎上,如果用三個按鍵分別控制三個LED,能否共用一個中斷程序各自定時15分鐘?
回復

使用道具 舉報

ID:123289 發表于 2018-2-14 16:49 | 顯示全部樓層
沒有真正的理解或認識,單片機中斷是干什么用的。中斷的流程是什么?先補一下課,再做。
回復

使用道具 舉報

ID:213173 發表于 2018-2-15 08:59 | 顯示全部樓層
xmcai 發表于 2018-2-14 16:19
在此基礎上,如果用三個按鍵分別控制三個LED,能否共用一個中斷程序各自定時15分鐘?

當然可以!定時器只是一個時基,可以提供N個定時服務,即可以是相同的定時時間,也可以是不同的定時時間。雖然新型單片機內置多個定時器,但只要規劃得合理,一個定時器幾乎可以完成所有定時任務。如果使用多個定時器且規劃失當,定時中斷間相互干擾是不容忽視的問題。
回復

使用道具 舉報

ID:280226 發表于 2018-2-15 15:37 | 顯示全部樓層
wulin 發表于 2018-2-15 08:59
當然可以!定時器只是一個時基,可以提供N個定時服務,即可以是相同的定時時間,也可以是不同的定時時間 ...

您的編程思路和方法值得學習和借鑒,謝謝解答!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品入口蜜桃 | 免费av在线 | 久久综合一区 | 欧美h视频| 91干b| 久久成人综合 | 国产精品久久久久一区二区 | 一本在线 | 日韩精品一区二区三区中文字幕 | 久久免费国产 | 丁香婷婷久久久综合精品国产 | 免费国产视频在线观看 | 亚洲欧美激情精品一区二区 | 国产一二区在线 | 免费黄色录像片 | 日本免费网 | 一本大道久久a久久精二百 国产成人免费在线 | 国产精品一二三区在线观看 | 日本在线视频不卡 | 91久操视频 | 激情网站在线 | 九一在线观看 | av天天看 | 国产黄视频在线播放 | 日韩成人在线网站 | 久久久久久久电影 | 日韩中文字幕2019 | 日韩在线一区二区三区 | 久久久综合网 | 麻豆精品国产91久久久久久 | 一级毛片免费视频观看 | 日本午夜视频 | 亚洲人成人一区二区在线观看 | 日韩欧美一区二区三区四区 | 午夜免费观看体验区 | 日韩精品一区二区三区四区 | 亚洲经典一区 | 亚洲国产成人精品女人 | 日韩国产在线观看 | 亚洲一区久久 | 久久性色 |