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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

求一個按鍵閉合后,繼電器延時1分鐘吸合,再延時5分鐘斷開的單片機程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:272609 發表于 2018-10-13 10:19 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
學習單片機有一陣子了,老實說斷斷續續有幾年了,資料也看了一大堆,感覺始終在門口徘徊,現在要寫一個程序,早上花了兩個小時還沒有寫成,程序要求是這樣,K1按鍵按下后,繼電器延時1分鐘后再吸合,吸合后延時5分鐘再斷開,等待下一次K1的按鍵按下。
使用89C52,不用數碼管,也不用24C01等EEPROM,論壇里搜索了很多,要么不能用,要么太復雜,看不懂也用不了那么多功能。
求論壇的大神寫個源程序,讓入門的菜鳥也能活學活用定時器和中斷。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:388197 發表于 2018-10-13 14:33 | 只看該作者
隨便寫的,下載到板子上試了試沒問題,1分鐘 5分鐘時間太長,我改成5秒 25秒,你只要改下數字就行.
#include <reg52.h>
sbit relay = P1^0;              //繼電器,0線圈吸合,1線圈斷開
sbit key = P1^1;                //按鍵,0為按下,1為松開
unsigned char key_timer_cnt;    //檢測按鍵計時變量
unsigned int relay_timer_cnt;    //繼電器吸合斷開計時變量
unsigned char relay_timer_cnt_min;    //繼電器延遲斷開計數器分鐘,因為5分鐘,1ms為單位將超過65535
unsigned char relay_state;       //記錄繼電器狀態 0=未觸發 1=待吸合 2=待斷開
       
void Init_T0(void)                  //定時器中斷初始化,設置為1ms
{
    TMOD = 0x01;
    TH0 = 0xfc;
    TL0 = 0x18;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}
void main(void)
{
        Init_T0();
        relay = 1;                         //斷開繼電器
        relay_state = 0;               //繼電器處于未觸發狀態
        while(1)
        {
             //想實現其他功能,再這里添加代碼
        }
}
void T0_ISR() interrupt 1              //1毫秒
{
        TH0 = 0xfc;
        TL0 = 0x18;
//***************************待觸發狀態,需要做的只是判斷按鍵有沒有按下*******************
        if(relay_state == 0)                //當繼電器處于待觸發狀態
        {
                if(key == 0)                      //按鍵按下,并且繼電器處于未觸發狀態
                {
                        key_timer_cnt++;                                  //按鍵計時器自加,用于消抖
                        if(key_timer_cnt>=5)                              //按鍵超過5毫秒
                        {
                                key_timer_cnt = 0;                          
                                relay_state = 1;                               //將繼電器設成待吸合狀態
                        }
                }else
                {
                        key_timer_cnt = 0;
                }
        }
        //********************待吸合狀態,等計數器加滿就行*****************************
        if(relay_state == 1)
        {
                relay_timer_cnt++;
                if(relay_timer_cnt>=5000)                      //將5000改為60000 即為1分鐘                  
                {
                        relay = 0;                                   //繼電器吸合
                        relay_state = 2;                             //吸合后將狀態轉成待斷開
                        relay_timer_cnt = 0;
                }
        }
        //******************待斷開狀態,跟待吸合一樣加滿就行*******************************
        if(relay_state == 2)
        {
                relay_timer_cnt++;
                if(relay_timer_cnt>=5000)                     //將5000改為60000即為1分鐘
                {
                        relay_timer_cnt = 0;
                        relay_timer_cnt_min++;                      //每60秒加1
                        if(relay_timer_cnt_min>=5)                  //當分鐘數等于5
                        {
                                relay = 1;                                //斷開繼電器
                                relay_timer_cnt_min = 0;
                                relay_timer_cnt = 0;
                                relay_state = 0;                          //斷開后將繼電器狀態轉換成未觸發
                        }
                }
        }
}

評分

參與人數 4黑幣 +80 收起 理由
yong761228 + 10
admin + 50 回帖助人的獎勵!
飛線 + 8 回帖助人的獎勵!
YJGG + 12 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:155507 發表于 2018-10-13 16:18 | 只看該作者
我給你來個程序試試


  1. #include "reg52.h"                         //此文件中定義了單片機的一些特殊功能寄存器

  2. typedef unsigned int u16;          //對數據類型進行聲明定義
  3. typedef unsigned char u8;

  4. sbit k1=P3^1;         //定義P31口是k1
  5. sbit led=P2^0;         //定義P20口是led
  6. sbit Relay=P2^1; //定義P21口是繼電器 //繼電器,1線圈吸合,0線圈斷開

  7. u16 Sec=0; //秒鐘
  8. u16 StartSec, StopSec;  //
  9. u8 KeyHit=0, StartRelay=0; //標志位
  10. u16 Relay_on_Interval = 60;    //繼電器延時1分鐘后再吸合
  11. u16 Relay_off_Interval = 300;  //繼電器吸合后延時5分鐘再斷開
  12. /*******************************************************************************
  13. * 函 數 名         : Timer0Init
  14. * 函數功能                   : 定時器0初始化
  15. * 輸    入         : 無
  16. * 輸    出         : 無
  17. *******************************************************************************/
  18. void Timer0Init()
  19. {
  20.         TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。

  21.         TH0=0X3C;        //給定時器賦初值,定時50ms
  22.         TL0=0XB0;       
  23.         ET0=1;//打開定時器0中斷允許
  24.         EA=1;//打開總中斷
  25.         TR0=1;//打開定時器                       
  26. }

  27. /*******************************************************************************
  28. * 函 數 名         : delay
  29. * 函數功能                   : 延時函數,i=1時,大約延時10us
  30. *******************************************************************************/
  31. void delay(u16 i)
  32. {
  33.         while(i--);       
  34. }

  35. /*******************************************************************************
  36. * 函 數 名         : keypros
  37. * 函數功能                   : 按鍵處理函數,判斷按鍵K1是否按下
  38. *******************************************************************************/
  39. void keypros()
  40. {
  41.         if(k1==0)                  //檢測按鍵K1是否按下
  42.         {       
  43.                 delay(1000);   //消除抖動 一般大約10ms
  44.                 if(k1==0)         //再次判斷按鍵是否按下
  45.                 {
  46.                         if(KeyHit==0)
  47.                         {
  48.                                 StartSec=Sec;
  49.                         }
  50.                         KeyHit=1; //按鍵K1按下
  51.                         led=~led;          //led狀態取反
  52.                 }
  53.                 while(!k1);         //檢測按鍵是否松開
  54.         }               
  55. }

  56. /*******************************************************************************
  57. * 函 數 名       : main
  58. * 函數功能                 : 主函數
  59. * 輸    入       : 無
  60. * 輸    出             : 無
  61. *******************************************************************************/
  62. void main()
  63. {       
  64.         Timer0Init();  //定時器0初始化
  65.         Relay = 0;      //斷開繼電器
  66.         while(1)
  67.         {       
  68.                 keypros();  //按鍵處理函數
  69.                 if(KeyHit==1)
  70.                 {
  71.                         if((StartRelay ==0) &&(Sec - StartSec >= Relay_on_Interval))
  72.                         {
  73.                                 Relay=1; //繼電器延時1分鐘后再吸合
  74.                                 StartRelay =1;
  75.                                 StopSec = Sec;
  76.                         }
  77.                         if((StartRelay ==1) &&(Sec - StopSec >= Relay_off_Interval))
  78.                         {
  79.                                 Relay=0; //繼電器吸合后延時5分鐘再斷開
  80.                                 KeyHit=0; //清除標志
  81.                                 StartRelay =0;
  82.                         }
  83.                        
  84.                 }
  85.         }               
  86. }

  87. /*******************************************************************************
  88. * 函 數 名         : void Timer0() interrupt 1
  89. * 函數功能                   : 定時器0中斷函數
  90. * 輸    入         : 無
  91. * 輸    出         : 無
  92. *******************************************************************************/
  93. void Timer0() interrupt 1
  94. {
  95.         static u16 i;
  96.         TH0=0X3C;        //給定時器賦初值,定時50ms
  97.         TL0=0XB0;
  98.         i++;
  99.         if(i==20)
  100.         {
  101.                 i=0;
  102.                 Sec++;
  103.                
  104.                 //led=~led;       
  105.         }       
  106. }
復制代碼

評分

參與人數 1黑幣 +8 收起 理由
飛線 + 8 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

地板
ID:401564 發表于 2018-10-13 19:31 | 只看該作者
C我不會,匯編的話可以教你一下,我也是從什么都不會開始自學的,也是走了很多的彎路

評分

參與人數 1黑幣 +8 收起 理由
飛線 + 8 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

5#
ID:272609 發表于 2018-10-14 15:32 | 只看該作者
Y_G_G 發表于 2018-10-13 19:31
C我不會,匯編的話可以教你一下,我也是從什么都不會開始自學的,也是走了很多的彎路

匯編我不懂,只會點C,謝謝你的分享,讓我們一起努力吧
回復

使用道具 舉報

6#
ID:137736 發表于 2018-10-14 17:47 | 只看該作者
Y_G_G 發表于 2018-10-13 19:31
C我不會,匯編的話可以教你一下,我也是從什么都不會開始自學的,也是走了很多的彎路

會匯編水平就比較高了,再學C很容易了。

評分

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

查看全部評分

回復

使用道具 舉報

7#
ID:123289 發表于 2018-10-14 21:14 | 只看該作者
學了這么久,這么簡單的問題還搞不定,建議改行!改行不是壞事,找一個更合適自己的乃是不錯的選擇。

評分

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

查看全部評分

回復

使用道具 舉報

8#
ID:280876 發表于 2018-10-15 17:14 | 只看該作者
老哥,改行吧。都幾年了還是這樣

評分

參與人數 1黑幣 +8 收起 理由
飛線 + 8 很給力!

查看全部評分

回復

使用道具 舉報

9#
ID:405193 發表于 2018-10-15 20:00 | 只看該作者
cjm82 發表于 2018-10-13 14:33
隨便寫的,下載到板子上試了試沒問題,1分鐘 5分鐘時間太長,我改成5秒 25秒,你只要改下數字就行.
#include
...

非常感謝這位師傅,我雖然年級比較大了,可是最近才開始學單片機編程,我利用您的程序,成功改寫1分鐘吸合5秒斷開循環程序。
#include <reg52.h>
sbit relay = P3^6;              //繼電器,0線圈吸合,1線圈斷開
sbit key = P3^2;                //按鍵,0為按下,1為松開
unsigned char key_timer_cnt;    //檢測按鍵計時變量
unsigned int relay_timer_cnt;    //繼電器吸合斷開計時變量
unsigned char relay_timer_cnt_min;    //繼電器延遲斷開計數器分鐘,因為5分鐘,1ms為單位將超過65535
unsigned char relay_state;       //記錄繼電器狀態 0=未觸發 1=吸合 2=斷開
        
void Init_T0(void)                  //定時器中斷初始化,設置為1ms
{
    TMOD = 0x01;
    TH0 = 0xfc;
    TL0 = 0x18;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}
void main(void)
{
        Init_T0();
        relay = 1;                         //斷開繼電器
        relay_state = 0;               //繼電器處于未觸發狀態
        while(1)
        {
             //想實現其他功能,再這里添加代碼
        }
}
void T0_ISR() interrupt 1              //1毫秒
{
        TH0 = 0xfc;
        TL0 = 0x18;
//***************************待觸發狀態,需要做的只是判斷按鍵有沒有按下*******************
        if(relay_state == 0)                //當繼電器處于待觸發狀態
        {
                if(key == 0)                      //按鍵按下,并且繼電器處于未觸發狀態
                {
                                         relay = 0;
                        key_timer_cnt++;                                  //按鍵計時器自加,用于消抖
                        if(key_timer_cnt>=5)                              //按鍵超過5毫秒
                        {
                                key_timer_cnt = 0;                          
                                relay_state = 2;                               //將繼電器設成待吸合狀態
                        }
                }else
                {
                        key_timer_cnt = 0;
                }
        }
        //********************繼電器斷開的時間,等計數器加滿就行*****************************
        if(relay_state == 1)
        {
                relay_timer_cnt++;
                if(relay_timer_cnt>=5000)                      //將5000改為60000 即為1分鐘                  
                {
                        relay = 0;                                   //繼電器將吸合
                        relay_state = 2;                             //吸合后將狀態轉成斷開
                        relay_timer_cnt = 0;
                }
        }
        //******************繼電器吸合的時間,跟待吸合一樣加滿就行*******************************
        if(relay_state == 2)
        {
                relay_timer_cnt++;
                if(relay_timer_cnt>=60000)                     //將5000改為60000即為1分鐘
                {
                                relay = 1;                                //繼電器將斷開
                                relay_timer_cnt = 0;
                                relay_state = 1;                          //斷開后將繼電器狀態轉換成吸合
                        }
                }
        }

評分

參與人數 3黑幣 +143 收起 理由
飛線 + 8 很給力!
admin + 100 回帖助人的獎勵!
angmall + 35 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

10#
ID:405193 發表于 2018-10-15 20:07 | 只看該作者
樓主努力,我也是最近才開始學單片機編程,我都40多歲了,我都不怕,加油!

評分

參與人數 2黑幣 +28 收起 理由
飛線 + 8 很給力!
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

11#
ID:405193 發表于 2018-10-15 21:03 | 只看該作者
angmall 發表于 2018-10-13 16:18
我給你來個程序試試

師傅,您好,您的程序我用STC15W404as 單片機,改了端口sbit relay = P3^6;   sbit key = P3^2;  就是不成功,可能您里面用了特殊寄存器,我這單片機程序可能不對,請指點一下,非常感謝。

評分

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

查看全部評分

回復

使用道具 舉報

12#
ID:388197 發表于 2018-10-16 10:15 | 只看該作者
yong761228 發表于 2018-10-15 21:03
師傅,您好,您的程序我用STC15W404as 單片機,改了端口sbit relay = P3^6;   sbit key = P3^2;  就是不 ...

IO口配置有沒有設置成浮空?
另外單片機IO口不要直接去接繼電器,接個三極管,用三極管去驅動繼電器.如果接的是NPN型的,那么IO口為1時是吸合,為0則斷開.

評分

參與人數 2黑幣 +28 收起 理由
飛線 + 8 很給力!
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

13#
ID:272609 發表于 2018-10-16 14:15 | 只看該作者
本帖最后由 飛線 于 2018-10-16 21:59 編輯
cjm82 發表于 2018-10-13 14:33
隨便寫的,下載到板子上試了試沒問題,1分鐘 5分鐘時間太長,我改成5秒 25秒,你只要改下數字就行.
#include
...

cjm82你好,你寫的程序我都記下了,我不是簡單的復制粘貼,而是每一行都認真的讀了一遍,大概理解后,然后自己寫到Keil里面。
我感覺你寫的程序簡單易懂,條理清晰,嗯,讓我印象比較深刻的是按鍵的延時消抖,原來不光是只有一種消抖的辦法,還有其他的辦法進行消抖。
然后就是按鍵按下去以后的幾個狀態,你這里面聲明了幾個變量,以前我看別人寫的時候,這一部分我是看不懂的,他們這邊寫了一個標志位flag,我感覺你聲明的幾個狀態變量,和這個標志位的意思是相同的,在這里我感覺我是看懂的,再次謝謝你
另外,我把這個程序修改、編譯,然后下載到郭天祥的開發版中,目前是不能正常運行的,估計后續是需要進一步修改,因為他外圍有很多拓展的硬件,謝謝啦,你讓我們這些菜鳥又學到了東西

評分

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

查看全部評分

回復

使用道具 舉報

14#
ID:272609 發表于 2018-10-16 14:16 | 只看該作者
angmall 發表于 2018-10-13 16:18
我給你來個程序試試

謝謝你的分享,前面一位老師已經分享了程序,我這里面正在研究他這個每一行的意思,后續等研究明白了,我再看看你這個程序
回復

使用道具 舉報

15#
ID:272609 發表于 2018-10-16 14:19 | 只看該作者
yzwzfyz 發表于 2018-10-14 21:14
學了這么久,這么簡單的問題還搞不定,建議改行!改行不是壞事,找一個更合適自己的乃是不錯的選擇。

與其批評別人有多菜,不如寫幾行代碼試試,讓別人看看你的水平有多高。
不是干這一行的,完全的業余愛好,再牛的人不也是從菜鳥成長起來的嗎
回復

使用道具 舉報

16#
ID:245473 發表于 2018-10-16 15:55 | 只看該作者
學了這么久,這么簡單的問題還搞不定
回復

使用道具 舉報

17#
ID:47286 發表于 2018-10-16 17:05 | 只看該作者
飛線 發表于 2018-10-16 14:19
與其批評別人有多菜,不如寫幾行代碼試試,讓別人看看你的水平有多高。
不是干這一行的,完全的業余愛好 ...

這人水平不低 雖然我沒見過也不認這人 僅聊過天 反正比我強很多

我開始學單片機比你還晚 我也比你歲數大 能理解學習的艱難 但人確實各有所長 學不會不一定是笨 也許就是不適合搞這方面而已 不管原因是什么 在技術領域 我們不如別人就不能因為別說說了什么而較勁

看你前面回復都很客氣 專門抽時間給你寫了完整的程序 但沒編譯也沒測試 不知道會有什么問題 你試試吧

#include <stc15w.h>                                //包括 stc15w系列頭文件(起動1T模式)

#define uchar unsigned char                //字符型宏
#define uint unsigned int                //整型宏

sbit relay = P?^?;              //定義你所用的端口
                                                                //--!!注意驅動方式 是高有效還是低有效 是否需要置成推挽 硬件電路不同程序會不同!!--
                                                                //--!!所以 有可能你的繼電器不工作!!--
sbit key = P?^?;                //定義你所用的端口 置成準雙向即可 或不設置 復位后默認即準雙向模式

bit flag_on1=0;                                        //聲明 1分鐘延時開始標記
bit flag_on5=0;                                        //聲明 5分鐘延時開始標記
bit flag_key=0;                                        //聲明 按鍵檢測標記

uint numrelay=0;                                //聲明 臨時變量 繼電器延時計數器
uchar numshark=0;                                //聲明 臨時變量 按鍵防抖計數器

void Init_T0(void)                                //定時器中斷初始化 1T/5ms
{
        AUXR |= 0x80;                                //定時器時鐘1T模式        (1000 0000)
        TMOD |= 0x01;                                //設置 定時器模式        (0000 0001)
        TL0 = 0x00;                                        //設置 定時初值                5ms初值
        TH0 = 0x28;                                        //設置 定時初值                5ms初值
        TF0 = 0;                                        //清除 TF0標志
        TR0 = 1;                                        //打開 定時器0計時
        ET0 = 1;                                        //打開 計時器0中斷
        EA  = 1;                                        //打開 總中斷控制
}

void Server_Time0() interrupt 1        //中斷1服務 1T時鐘
{
        static uchar numt01;                //5ms到1s

        TL0 = 0x00;                                        //賦值 T0低位初值
        TH0 = 0x28;                                        //賦值 T0高位初值

        numt01++;                                        //自加 臨時計數器01
        numshark++;                                        //自加 計數器shark

        if(numt01==200)                                //如果 臨時計數器01達到設定值(5ms轉1s)
        {
                numt01=0;                                        //清零 臨時計數器01
                numrelay++;                                        //自加 計數器relay
        }
}

void Delay(uchar x)                //延時函數 按鍵防抖用 1x=1ms 在中斷服務里加個計數器即可
{
        numshark=0;
        while(numshark<x);
}

void main(void)
{
    Init_T0();                                //初始化 定時器中斷
   
        relay = ?;              //繼電器端口是置位還是清零取決于你所用的驅動方式 比如P管是低有效就置位 N管是高有效就應該清零

    while(1)
    {
         if(key==?                        //如果 按鍵按下(不知道你的按鍵是高觸發還是低觸發 高觸發=1 低觸發=0)
                 &&flag_key==0)                //并且 按鍵標記=0
                 {
                         Delay(4);                        //延時20ms
                        if(key==?)                        //如果 按鍵依舊按下(即 防抖)
                        {
                                flag_on1=1;                        //置位 1分鐘延時開始標記
                                flag_key=1;                        //置位 按鍵標記(不再進入按鍵檢測 防止反復按鍵檢測)
                                numrelay=0;                        //清零 計數器relay
                        }
                 }

                 if(flag_on1==1                        //如果 1分鐘延時標記=1
                 &&numrelay>=60)                //并且 計數器relay達到設定值 60s
                 {
                        flag_on1=0;                                //清零 1分鐘延時開始標記 防止再進入
                        flag_on5=1;                                //置位 5分鐘延時開始標記
                        relay=?;                                //打開 繼電器
                        numrelay=0;                                //清零 計數器relay
                 }

                 if(flag_on5==1                        //如果 5分鐘延時標記=1
                 &&numrelay>=300)                //如果 計數器relay達到設定值 300s
                 {
                        relay=~relay;                        //關閉 繼電器
                        flag_on5=0;                                //清零 5分鐘延時開始標記
                        flag_key=0;                                //清零 按鍵檢測標記(可以再次檢測按鍵)
                 }
    }
}

評分

參與人數 3黑幣 +48 收起 理由
yong761228 + 10 很給力!
admin + 30 回帖助人的獎勵!
飛線 + 8 很給力!

查看全部評分

回復

使用道具 舉報

18#
ID:405193 發表于 2018-10-17 07:23 | 只看該作者
dzbj 發表于 2018-10-16 17:05
這人水平不低 雖然我沒見過也不認這人 僅聊過天 反正比我強很多

我開始學單片機比你還晚 我也比你歲數 ...

非常感謝師傅
回復

使用道具 舉報

19#
ID:405193 發表于 2018-10-17 07:37 | 只看該作者
cjm82 發表于 2018-10-16 10:15
IO口配置有沒有設置成浮空?
另外單片機IO口不要直接去接繼電器,接個三極管,用三極管去驅動繼電器.如果接 ...

非常謝謝師傅,您的程序沒有任何問題,我還會改寫功能,硬件電路我懂。我只是對 “angmall ” 師傅的程序沒有看懂,實驗沒有成功。
回復

使用道具 舉報

20#
ID:65956 發表于 2018-10-17 08:33 | 只看該作者
這個不是很簡單嗎,用1個定時器就可以搞定了,或不用定時器也可以搞定
回復

使用道具 舉報

21#
ID:405193 發表于 2018-10-17 21:28 | 只看該作者
各位師傅,我這個自鎖程序有問題,遙控器ABCD 按每個按鈕都出現對應的按鍵碼Key-d(相當于波形,短時間里有許多相同的波形),D3 D2 D1 D0 是四個繼電器,按住或者按一下遙控器按鈕A,D3一直吸合,松開遙控器按鈕A,再次按遙控器按鈕A,D3斷開;同理其它BCD也一樣。我現在這樣寫程序出現按住遙控器按鈕A, D3繼電器不停的吸合 斷開。看看哪位師傅幫我修改一下程序,謝謝。

if(key_d == 0x08){D3=~D3;} //當按鍵碼是0x08的時候,D3繼電器取反,問題出現在短時間里有許多個0x08 出現,就出現了不停的吸合 斷開。我用了延時程序,問題是延時程序過了還是出現這問題,因為可以一直按遙控器按鈕,超過延時的時間有出現同樣的問題。
if(key_d == 0x04){D2=~D2;}
if(key_d == 0x02){D1=~D1;}
if(key_d == 0x01){D0=~D0;}       

評分

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

查看全部評分

回復

使用道具 舉報

22#
ID:280876 發表于 2018-10-18 09:18 | 只看該作者
yong761228 發表于 2018-10-17 21:28
各位師傅,我這個自鎖程序有問題,遙控器ABCD 按每個按鈕都出現對應的按鍵碼Key-d(相當于波形,短時間里有 ...

你按鍵掃描是怎么樣的,發上來看看
回復

使用道具 舉報

23#
ID:405193 發表于 2018-10-18 18:57 | 只看該作者
wushiye54 發表于 2018-10-18 09:18
你按鍵掃描是怎么樣的,發上來看看

師傅,您好,已經有人幫我改好了,謝謝。
回復

使用道具 舉報

24#
ID:272609 發表于 2018-10-19 17:43 | 只看該作者
angmall 發表于 2018-10-13 16:18
我給你來個程序試試

老大,看了你的代碼,感覺你是計算機專業的科班出身,程序寫的很精練,所要實現的功能也能達到,但是對我們這些初學者來說,還是有一些難度,就比如這一句“if((StartRelay ==0) &&(Sec - StartSec >= Relay_on_Interval))”,我是看了兩分鐘才明白,要不是沒看C語言的書籍,我估計我還看不懂的。
最后感謝你的回復和代碼,我再仔細看看,還是能學到東西的。
回復

使用道具 舉報

25#
ID:272609 發表于 2018-10-19 17:44 | 只看該作者
Y_G_G 發表于 2018-10-13 19:31
C我不會,匯編的話可以教你一下,我也是從什么都不會開始自學的,也是走了很多的彎路

你都會匯編了,那C語言對你來說就是小兒課了
回復

使用道具 舉報

26#
ID:272609 發表于 2018-10-19 17:45 | 只看該作者
本帖最后由 飛線 于 2018-10-19 20:38 編輯
wushiye54 發表于 2018-10-15 17:14
老哥,改行吧。都幾年了還是這樣

弟,哥純屬業余愛好,一邊工作一邊學習單片機。
回復

使用道具 舉報

27#
ID:272609 發表于 2018-10-19 17:54 | 只看該作者
yong761228 發表于 2018-10-15 20:07
樓主努力,我也是最近才開始學單片機編程,我都40多歲了,我都不怕,加油!

加油,我感覺我都快入門了
回復

使用道具 舉報

28#
ID:272609 發表于 2018-10-19 17:57 | 只看該作者
hong19851024 發表于 2018-10-16 15:55
學了這么久,這么簡單的問題還搞不定

哈哈,讓你見笑了
回復

使用道具 舉報

29#
ID:272609 發表于 2018-10-19 18:12 | 只看該作者
dzbj 發表于 2018-10-16 17:05
這人水平不低 雖然我沒見過也不認這人 僅聊過天 反正比我強很多

我開始學單片機比你還晚 我也比你歲數 ...

謝謝你的代碼,寫了這么多行,一定占用了你不少的時間,再次謝謝你。我是初學者,學習的是51的單片機,買的是郭天祥的開發板,從頭到尾看了你的程序,感覺是可行的。
因為我不是STC15系統的開發板,再加上我想加入一些擴展功能,所以沒有下載進去。
if(flag_on1==1  &&numrelay>=60)//如果 1分鐘延時標記=1,這個是也在學了C語言的書后,看到了,另外對標志位flag的用法,也有了一些概念。
                  
回復

使用道具 舉報

30#
ID:47286 發表于 2018-10-20 11:33 | 只看該作者
飛線 發表于 2018-10-19 18:12
謝謝你的代碼,寫了這么多行,一定占用了你不少的時間,再次謝謝你。我是初學者,學習的是51的單片機,買 ...

不用客氣

各人有自己的情況 所以別人寫的東西細節上肯定滿足不了 我提供的也只是個思路 能幫到你就好
回復

使用道具 舉報

31#
ID:405193 發表于 2018-10-21 23:37 | 只看該作者
各位師傅,幫我看看下面的程序怎么寫,我剛學,水平有限,非常感謝。
   //  電機正反轉互鎖的,就是通電一秒電機正轉relay1吸合,到了行程終點或限位開關K2停止,
                   //再通電一秒電機反轉relay2吸合,到了另一邊限位開關K3停止
#include <reg52.h>
sbit relay1 = P1^3;              //繼電器,0線圈吸合,1線圈斷開
sbit relay2 = P1^4;  
sbit key1 = P3^7;                //按鍵,0為按下,1為松開
sbit k2 = P3^1;                                           //relay1 停止;K2=0時,relay1 是斷開的,K2=1時,relay1才能吸合
sbit k3 = P3^0;                                           // relay2 停止;K3=0時,relay2 是斷開的,K3=1時,relay2才能吸合
unsigned char key_timer_cnt;    //檢測按鍵計時變量
unsigned char relay_state;       //記錄繼電器狀態 0=未觸發 1=待吸合 2=待斷開

        

void main(void)
{
        P1=0xFF;
                P3=0xFF;
        Init_T0();
        relay1 = 1;                         //斷開繼電器
        relay2 = 1;   
                relay_state = 0;               //繼電器處于未觸發狀態
        while(1)
        {
                                   //想實現其他功能,再這里添加代碼
        }
}
void T0_ISR() interrupt 1              //1毫秒
{
        TH0 = 0xfc;
        TL0 = 0x18;
//***************************待觸發狀態,需要做的只是判斷按鍵有沒有按下*******************
        if(relay_state == 0)                //當繼電器處于待觸發狀態
        {
                if(key1 == 0)                      //按鍵按下,并且繼電器處于未觸發狀態
                {
                                         key_timer_cnt++;                                  //按鍵計時器自加,用于消抖
                        if(key_timer_cnt>=5)                              //按鍵超過5毫秒
                        {
                            key_timer_cnt = 0;                          
                                 
                        }else
                {
                        key_timer_cnt = 0;
                }
                        }
            }
        //****請教是否下面程序怎么寫,謝謝!*********************************************
               //三種狀態:
                //第一種:  K2=1并且K3=1        (相當于電機不在兩邊,在中間任何位置)
                //    觸發Key1=0    relay1=0,relay2=1,到達限位后停止  K2=0, relay1=1,
            //第二種: K2=0并且K3=1        (相當于電機在一邊限位上)
                //          觸發Key1=0         relay1=1,relay2=0,到達限位后停止  K3=0, relay2=1,
                // 第三種: K2=1并且K3=0        (相當于電機在另外一邊限位上)
                //          觸發Key1=0         relay1=0,relay2=1,到達限位后停止  K2=0, relay1=1,

}      
回復

使用道具 舉報

32#
ID:405193 發表于 2018-10-22 08:16 | 只看該作者
                   //  電機正反轉互鎖的,就是通電一秒電機正轉relay1吸合,到了行程終點或限位開關K2停止,
                   //再通電一秒電機反轉relay2吸合,到了另一邊限位開關K3停止
#include <reg52.h>
sbit relay1 = P1^3;              //繼電器,0線圈吸合,1線圈斷開
sbit relay2 = P1^4;  
sbit key1 = P3^7;                //按鍵,0為按下,1為松開
sbit k2 = P3^1;                                           //relay1 停止;K2=0時,relay1 是斷開的,K2=1時,relay1才能吸合
sbit k3 = P3^0;                                           // relay2 停止;K3=0時,relay2 是斷開的,K3=1時,relay2才能吸合
unsigned char key_timer_cnt;    //檢測按鍵計時變量
unsigned char relay_state;       //記錄繼電器狀態 0=未觸發 1=觸發
void Init_T0(void)                  //定時器中斷初始化,設置為1ms
{
    TMOD = 0x01;
    TH0 = 0xfc;
    TL0 = 0x18;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}

void main(void)
{
        P1=0xFF;
                P3=0xFF;
        Init_T0();
        relay1 = 1;                         //斷開繼電器
        relay2 = 1;   
                relay_state = 0;               //繼電器處于未觸發狀態
        while(1)
        {
                                   //想實現其他功能,再這里添加代碼
        }
}
void T0_ISR() interrupt 1              //1毫秒
{
        TH0 = 0xfc;
        TL0 = 0x18;
//***************************待觸發狀態,需要做的只是判斷按鍵有沒有按下*******************
        if(relay_state == 0)                //當繼電器處于待觸發狀態
        {
                if(key1 == 0)                      //按鍵按下,并且繼電器處于未觸發狀態
                {
                                                  relay1 = 1;                         //斷開繼電器
                          relay2 = 1;   
                                                  key_timer_cnt++;                    //按鍵計時器自加,用于消抖
                        if(key_timer_cnt>=10)                    //按鍵超過10毫秒
                        {
                            key_timer_cnt = 0;                          
                            relay_state = 1;      
                        }
                                               
                                }                else
                {
                        key_timer_cnt = 0;
                }
                         
            }
        //******各位師傅,幫我看看下面程序錯在什么地方,三種情況選擇:
                //狀態1:         K2= 1并且K3=1 ,relay1 = 0;  直到K2=0,relay1 = 1; 并且返回 relay_state = 0;
                //狀態2:          K2= 0并且K3=1 ,relay2 = 0;  直到K3=0,relay2 = 1; 并且返回 relay_state = 0;
                //狀態3:          K2= 1并且K3=0 ,relay1 = 0;  直到K2=0,relay1 = 1; 并且返回 relay_state = 0;
                //*******************************************
      
                   if(         relay_state == 1)
                   {
                  
                       if((k2==1)&& (k3==1))
                                    {  relay1 = 0;  
                           if  (k2==0)
                                  {relay1 = 1; relay_state = 0; }
                                 }
                   else if((k2==0)&& (k3==1))
                                 {  relay2 = 0;   
                           if  (k3==0)
                                    {relay2 = 1; relay_state = 0; }
                          }
                   else if((k2==1)&& (k3==0))
                                 {  relay1 = 0;
                            if  (k2==0)
                                {relay1 = 1; relay_state = 0; }
                         }                                                 
                }
          
         
}      
回復

使用道具 舉報

33#
ID:47286 發表于 2018-10-22 10:11 | 只看該作者
yong761228 發表于 2018-10-22 08:16
//  電機正反轉互鎖的,就是通電一秒電機正轉relay1吸合,到了行程終點或限位開關K2停止,
                   //再 ...

你直接描述要干嘛吧 看別人程序想明白別人思路再給人家改 對我來說太難了 我懶 不如你說明白要干嘛直接重新寫

你后邊這邏輯貌似有問題 所有狀態都返回相同結果 但不管什么時候都會滿足其中一組條件 那就是說任何時候返回的都是相同結果
回復

使用道具 舉報

34#
ID:216962 發表于 2018-10-22 11:21 | 只看該作者
飛線 發表于 2018-10-19 17:45
弟,哥純屬業余愛好,一邊工作一邊學習單片機。

說真的,我也是業余學習的。好多謝你們的分享,論壇有你們會更精彩!
回復

使用道具 舉報

35#
ID:405193 發表于 2018-10-22 11:35 | 只看該作者
dzbj 發表于 2018-10-22 10:11
你直接描述要干嘛吧 看別人程序想明白別人思路再給人家改 對我來說太難了 我懶 不如你說明白要干嘛直接重 ...

師傅,您好,要實現的是這樣的狀態

//狀態1:         K2= 1并且K3=1 ,relay1 = 0;  直到K2=0,relay1 = 1; 并且返回 relay_state = 0;
                //狀態2:          K2= 0并且K3=1 ,relay2 = 0;  直到K3=0,relay2 = 1; 并且返回 relay_state = 0;
                //狀態3:          K2= 1并且K3=0 ,relay1 = 0;  直到K2=0,relay1 = 1; 并且返回 relay_state = 0;
                //*******************************************
      
            
回復

使用道具 舉報

36#
ID:405193 發表于 2018-10-22 11:41 | 只看該作者
dzbj 發表于 2018-10-22 10:11
你直接描述要干嘛吧 看別人程序想明白別人思路再給人家改 對我來說太難了 我懶 不如你說明白要干嘛直接重 ...

謝謝師傅: 電機正反轉互鎖的,就是通電一秒(key=0)電機正轉(relay1=0)吸合,到了行程終點或限位開關(K2=0)停止,再通電一秒(key=0)電機反轉(relay2=0)吸合,到了另一邊限位開關(K3=0)停止
K2 K3 有三種狀態:
//狀態1:          K2= 1并且K3=1 ,relay1 = 0;  直到K2=0,relay1 = 1;
//狀態2:          K2= 0并且K3=1 ,relay2 = 0;  直到K3=0,relay2 = 1;               
//狀態3:          K2= 1并且K3=0 ,relay1 = 0;  直到K2=0,relay1 = 1;
回復

使用道具 舉報

37#
ID:357520 發表于 2018-10-22 22:20 | 只看該作者
Y_G_G 發表于 2018-10-13 19:31
C我不會,匯編的話可以教你一下,我也是從什么都不會開始自學的,也是走了很多的彎路

可以寫一下,最近也想學習一下匯編
回復

使用道具 舉報

38#
ID:47286 發表于 2018-10-23 01:29 | 只看該作者
yong761228 發表于 2018-10-22 11:41
謝謝師傅: 電機正反轉互鎖的,就是通電一秒(key=0)電機正轉(relay1=0)吸合,到了行程終點或限位開關(K2=0 ...

//謝謝師傅: 電機正反轉互鎖的,就是通電一秒(key=0)電機正轉(relay1=0)吸合,
//到了行程終點或限位開關(K2=0)停止,再通電一秒(key=0)電機反轉(relay2=0)吸合,到了另一邊限位開關(K3=0)停止
//K2 K3 有三種狀態:

uchar status=0;                //聲明 狀態變量
uchar bakup=0;                //聲明 備份變量

bit flag_key=0;                //聲明 按鍵標記
bit flag_run=0;                //聲明 繼電器運行標記

void key_status()        //止點掃描
{
//狀態1:K2= 1并且K3=1 ,relay1 = 0;直到K2=0,relay1 = 1;
        if(key2==1                //如果 止點2=1
        &&key3==1)                //并且 止點3=1
        {
                status=1;                //賦值 狀態=1
        }
//狀態2:K2= 0并且K3=1 ,relay2 = 0;直到K3=0,relay2 = 1;
        if(k2==0                //如果 止點2=0
        &&k3==1)                //如果 止點3=1
        {
                status=2;                //賦值 狀態=2
        }
//狀態3:K2= 1并且K3=0 ,relay1 = 0;直到K2=0,relay1 = 1;
        if(k2==1                //如果 止點2=1
        &&k3==0)                //如果 止點3=0
        {
                status=3;                //賦值 狀態=3
        }
}

void key_down()                //按鍵檢測
{
        if(key==0                        //如果 按鍵按下
        &&flag_key==0)                //并且 按鍵標記=0
        {
                Delay(200);                        //延時1s
                if(key==0)                        //如果 按鍵依舊按下
                {
                        flag_key=1;                        //置位 按鍵標記
                        backup=status;                //賦值 備份變量=狀態變量
                        flag_run=1;                        //置位 繼電器運行標記
                }
        }
}

void  jk_run()                //繼電器工作
{
        if(backup==status                //如果 備份變量=狀態變量
        &&flag_run==1)                        //并且 繼電器運行標記=1
        {
                switch (status)                //選擇 狀態
                {
                        case 1:                //狀態1:正轉
                                relay1=0;                //繼電器1吸合
                                relay2=1;                //繼電器2釋放
                        break;
       
                        case 2:                //狀態2:反轉
                                relay1=1;                //繼電器1釋放
                                relay2=0;                //繼電器2吸合
                        break;
       
                        case 3:                //狀態3:正轉
                                relay1=0;                //繼電器1吸合
                                relay2=1;                //繼電器2釋放
                        break;
                }
        }
        else                                        //否則 即 備份變量!=狀態變量(狀態改變)
        {
                Delay(4);                                //延時20ms防抖
                if(backup!=status)                //如果 狀態依舊改變中
                {
                        backup=0;                                //清零 備份變量
                        relay1=1;                                //繼電器1釋放
                        relay2=1;                                //繼電器2釋放
                        flag_key=0;                                //清零 按鍵標記
                        flag_run=0;                                //清零 繼電器運行標記
                }
        }
}

void main()
{
        //初始化T0計時器(應該寫成每5ms一個中斷)

        while(1)
        {
                key_status();        //止點掃描
                key_down();                //按鍵檢測
                jk_run();                //繼電器工作
        }
}

評分

參與人數 1黑幣 +10 收起 理由
yong761228 + 10 贊一個!

查看全部評分

回復

使用道具 舉報

39#
ID:405193 發表于 2018-10-23 08:51 | 只看該作者
dzbj 發表于 2018-10-23 01:29
//謝謝師傅: 電機正反轉互鎖的,就是通電一秒(key=0)電機正轉(relay1=0)吸合,
//到了行程終點或限位開 ...

非常感謝師傅。
回復

使用道具 舉報

40#
ID:405193 發表于 2018-10-23 20:23 | 只看該作者
dzbj 發表于 2018-10-23 01:29
//謝謝師傅: 電機正反轉互鎖的,就是通電一秒(key=0)電機正轉(relay1=0)吸合,
//到了行程終點或限位開 ...

師傅您好,我測試了一下,K2=0或者K3=0的時候觸發key,繼電器應該一直工作,到達對面開關,現在問題是繼電器吸合離開K2或者K3就斷開,沒有一直運行到對面開關才斷開,非常感謝您。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91xx在线观看 | 欧美日韩亚洲视频 | 免费看国产a | 亚洲成年在线 | 天天操夜夜操 | 国产精品91久久久久久 | 天天插天天射天天干 | 日本久久久一区二区三区 | 欧美激情精品久久久久久变态 | 黄色成人在线观看 | 北条麻妃99精品青青久久主播 | 精品国产精品一区二区夜夜嗨 | 久久亚洲欧美日韩精品专区 | jizjizjiz中国护士18 | 国产精品免费在线 | 国产一区二区三区日韩 | 亚洲精品久久久久久久久久久久久 | 亚洲高清三级 | 一区影视| 亚洲国产aⅴ成人精品无吗 国产精品永久在线观看 | 欧美在线国产精品 | 91成人小视频| 国产精品夜夜春夜夜爽久久电影 | 国产精品一区二区三区久久久 | 亚洲二区视频 | 高清国产一区二区 | 久久曰视频 | 国产成人福利 | h视频免费在线观看 | 成人深夜福利 | 成人av在线大片 | 亚洲va欧美va天堂v国产综合 | www.色综合 | 亚洲精品1 | 看片网站在线 | 国产欧美综合在线 | 日韩精品一区二区三区四区 | 亚洲精品国产成人 | 伊人网站 | 一区二区日韩 | 国产精品亚洲第一 |