找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機一鍵啟停程序,請大神看一下哪里出錯了?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:999123 發(fā)表于 2022-2-6 19:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機啟停程序,設(shè)想是:按一下啟動,再按停止。現(xiàn)在是通電后喇叭響,按一下就停了,再按沒反應(yīng)。大家看一下哪里有錯誤,找不出來了。

             #include"reg52.h"
        #define uchar unsigned char
        #define uint unsigned int
        sbit pp=P1^5;
         bit  flag=1;
        void delay(uint x)
        {
                uint i, j;
             for(i=x;i>0;i--)
                         for(j=0;j>0;j--);          


         }

                  void main()
          {         
          
           IT0=0;
                  EX1=1;
                  EA=1;
          
                   while(flag)
          {
          pp=~pp;
          
                   delay(10);
           }

        }         
                void int1_serv() interrupt 2

                {
                            delay(10);
                          if(P3^3==0)
                           {
                                flag=~flag;
                           }

         while(P3^3==1);

                }


                 
         

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

使用道具 舉報

沙發(fā)
ID:743654 發(fā)表于 2022-2-8 09:11 | 只看該作者

延時函數(shù)有問題,時間太短了,第一個for循環(huán)只執(zhí)行一次
    void delay(uint x)
        {
             uint i, j;
             for(i=x;i>0;i--)
                  for(j=0;j>0;j--); //這句根本就不執(zhí)行         
         }
回復(fù)

使用道具 舉報

板凳
ID:161164 發(fā)表于 2022-2-8 10:39 | 只看該作者
1。main內(nèi)的主while一定是while(1)
2。中斷內(nèi)不要用delay
3。一鍵啟停請用下降沿觸發(fā),IT1 = 1;

  1. #include"reg52.h"
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit pp=P1^5;
  5. bit  flag=1, flag_Swap;
  6. uint delay_cnt = 0;
  7. void delay(uint x)
  8. {
  9.         uint i, j;
  10.         for(i=x; i>0; i--)
  11.                 for(j=0; j>0; j--);
  12. }
  13. void main()
  14. {
  15.         IT1=1;
  16.         EX1=1;
  17.         EA=1;
  18.         while(1)
  19.         {
  20.                 if(flag)
  21.                 {
  22.                         pp=~pp;
  23.                 }       
  24.                 if(flag_Swap)
  25.                 {
  26.                         if(delay_cnt == 0)flag=~flag;
  27.                         if(++delay_cnt > 1000)//消抖
  28.                         {
  29.                                 delay_cnt = 0;
  30.                                 flag_Swap = 0;
  31.                         }
  32.                 }
  33.                 delay(10);
  34.         }
  35. }
  36. void int1_serv() interrupt 2
  37. {
  38.         flag_Swap = 1;
  39. }
復(fù)制代碼
回復(fù)

使用道具 舉報

地板
ID:1004367 發(fā)表于 2022-2-8 12:23 | 只看該作者
單片機用什么語言寫的呀
回復(fù)

使用道具 舉報

5#
ID:999123 發(fā)表于 2022-2-8 12:24 | 只看該作者
lkc8210 發(fā)表于 2022-2-8 10:39
1。main內(nèi)的主while一定是while(1)
2。中斷內(nèi)不要用delay
3。一鍵啟停請用下降沿觸發(fā),IT1 = 1;

太感謝了。
回復(fù)

使用道具 舉報

6#
ID:999123 發(fā)表于 2022-2-8 18:30 | 只看該作者
已經(jīng)解決了,不過不是很理想,外中斷程序里不能延時去抖動,造成按鍵仍然有一定的幾率出錯。
回復(fù)

使用道具 舉報

7#
ID:999123 發(fā)表于 2022-2-8 18:40 | 只看該作者
已經(jīng)解決問題了,但是不理想,延時去抖不能用在中斷程序里,造成按鍵不可靠,進入中斷后關(guān)掉中斷效果也不好。大家有什么好辦法嗎?


                             #include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit pp=P1^5;          sbit k8=P3^3;
bit  flag=1, flag1;
uint delay_cnt = 0;
void delay(uint x)
        {
        uint i, j;
        for(i=x; i>0; i--)
                for(j=0; j>0; j--);
        }
                        void main()
        {
        IT1=1;
        EX1=1;
        EA=0;
        while(1)
        {        if(flag==1)
               
                {
                        pp=~pp;
                                                delay(10);
                }  
                               
                        if(k8==0)
                          {         delay(10);
                                  if(k8==0);
                                     
                if(flag1==1)
                {
                   flag=~flag;
                                  
                                   flag1=0;
                                }       
                                       
                  
                                  EA=1;
                                }
               
        }
}
void int1_serv() interrupt 2
{                 EA=0;
        flag1 = 1;
}
                           
回復(fù)

使用道具 舉報

8#
ID:161164 發(fā)表于 2022-2-9 08:03 | 只看該作者
廖振基 發(fā)表于 2022-2-8 18:40
已經(jīng)解決問題了,但是不理想,延時去抖不能用在中斷程序里,造成按鍵不可靠,進入中斷后關(guān)掉中斷效果也不好 ...

請參考我的消抖方法~
其實你這種情況完全沒必要用中斷
回復(fù)

使用道具 舉報

9#
ID:999123 發(fā)表于 2022-2-9 13:49 | 只看該作者
謝謝指點,用中斷主要是考慮到,:如果程序有較長時間的循環(huán)等待時,非中斷暫停鍵就不會快速響應(yīng),當然,這個程序例可以不需要。
回復(fù)

使用道具 舉報

10#
ID:213173 發(fā)表于 2022-2-9 15:43 | 只看該作者
廖振基 發(fā)表于 2022-2-8 18:40
已經(jīng)解決問題了,但是不理想,延時去抖不能用在中斷程序里,造成按鍵不可靠,進入中斷后關(guān)掉中斷效果也不好 ...

簡單的問題不要用復(fù)雜的方法解決
  1. #include"reg52.h"
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit pp=P1^5;
  5. sbit k8=P3^3;
  6. bit  flag=0;
  7. uint delay_cnt=0;
  8. /*
  9. void delay(uint x)
  10. {
  11.         uint i, j;
  12.         for(i=x; i>0; i--)
  13.                 for(j=0; j>0; j--);
  14. }*/
  15. void main()
  16. {
  17. //        IT1=1;
  18. //        EX1=1;
  19. //        EA=0;
  20.         while(1)
  21.         {
  22. //                if(flag==1)
  23. //                {
  24. //                        pp=~pp;
  25. //                        delay(10);
  26. //                }  
  27.                 if(k8==0)
  28.                 {
  29. //                        delay(10);
  30. //                        if(k8==0);
  31.                         if(++delay_cnt>=500 && flag==0)
  32.                         {
  33.                                 flag=1;
  34.                                 pp=~pp;
  35.                         }        
  36. //                        EA=1;
  37.                 }
  38.                 else
  39.                 {
  40.                         flag=0;
  41.                         delay_cnt=0;
  42.                 }
  43.         }
  44. }
  45. /*
  46. void int1_serv() interrupt 2
  47. {
  48.         EA=0;
  49.         flag1=1;
  50. }*/
復(fù)制代碼
回復(fù)

使用道具 舉報

11#
ID:999123 發(fā)表于 2022-2-10 16:29 | 只看該作者
非常感謝回答,將程序下載單片機后,喇叭不響,自己稍微改動一下,仍然不響,可是按照程序推理應(yīng)該可以運行的。確定硬件沒有問題,更換以前程序可以響的,只是不可靠。

                                 #include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit pp=P1^5;
sbit k8=P3^3;
bit  flag=0;
uint delay_cnt=0;
/*
void delay(uint x)
{
        uint i, j;
        for(i=x; i>0; i--)
                for(j=0; j>0; j--);
}*/
void main()
{
//        IT1=1;
//        EX1=1;
//        EA=0;
        while(1)
        {
//                if(flag==1)
//                {
//                        pp=~pp;
//                        delay(10);
//                }  
                if(k8==0)
                {
//                        delay(10);
//                        if(k8==0);
                        if(++delay_cnt>=500 && flag==0)
                        {
                                flag=1;
                                pp=~pp;
                        }        delay_cnt>10; //自己增加的部分
//                        EA=1;
                }
                else
                {
                        flag=0;
                        delay_cnt=0;
                }
        }
}
/*
void int1_serv() interrupt 2
{
        EA=0;
        flag1=1;
}*/        
回復(fù)

使用道具 舉報

12#
ID:161164 發(fā)表于 2022-2-10 20:51 來自觸屏版 | 只看該作者
廖振基 發(fā)表于 2022-2-9 13:49
謝謝指點,用中斷主要是考慮到,:如果程序有較長時間的循環(huán)等待時,非中斷暫停鍵就不會快速響應(yīng),當然,這 ...

正常寫程序應(yīng)避免產(chǎn)生長時間的循環(huán)
見到那些Delay(10)的按鍵消抖/數(shù)碼管顯示和while(!key)松開檢測
就覺得是白白浪費了單片機的速度
就算是最老的51單片機都可以1微秒一條指令
10毫秒可以跑上千條指令
所以你的思路不應(yīng)該去想用中斷快速反應(yīng)按鍵
而是要去想如何減少使用阻塞式延時
回復(fù)

使用道具 舉報

13#
ID:313048 發(fā)表于 2022-2-11 10:13 | 只看該作者
按鍵可以使用狀態(tài)機,能夠有效的去除阻塞延時。
回復(fù)

使用道具 舉報

14#
ID:311903 發(fā)表于 2022-2-11 10:20 | 只看該作者
按鍵按下后,開啟定時器計時消抖
回復(fù)

使用道具 舉報

15#
ID:451718 發(fā)表于 2022-2-11 13:55 | 只看該作者
廖振基 發(fā)表于 2022-2-8 18:40
已經(jīng)解決問題了,但是不理想,延時去抖不能用在中斷程序里,造成按鍵不可靠,進入中斷后關(guān)掉中斷效果也不好 ...

好辦法就是學(xué)會用定時器中斷,通過定時器中斷,在程序中植入毫秒計時,也就是經(jīng)常在例程中看到的 SysTick++操作。程序中所有的延遲,都可以通過對SysTick時鐘的比對來實現(xiàn)。 如你要Delay(20ms);可以對時間變量T1= SysTick;取值,然后判斷 通過判斷 SysTick-T1是否大于20來實現(xiàn)延遲,多看例程。
回復(fù)

使用道具 舉報

16#
ID:999123 發(fā)表于 2022-2-11 16:49 | 只看該作者
謝謝大家的指點,知識量有點多,我先去研究研究了。再次謝謝大家。
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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