標(biāo)題: 單片機(jī)一鍵啟停程序,請(qǐng)大神看一下哪里出錯(cuò)了? [打印本頁(yè)]

作者: 廖振基    時(shí)間: 2022-2-6 19:45
標(biāo)題: 單片機(jī)一鍵啟停程序,請(qǐng)大神看一下哪里出錯(cuò)了?
單片機(jī)啟停程序,設(shè)想是:按一下啟動(dòng),再按停止,F(xiàn)在是通電后喇叭響,按一下就停了,再按沒(méi)反應(yīng)。大家看一下哪里有錯(cuò)誤,找不出來(lái)了。

             #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);

                }


                 
         


作者: cheney03    時(shí)間: 2022-2-8 09:11

延時(shí)函數(shù)有問(wèn)題,時(shí)間太短了,第一個(gè)for循環(huán)只執(zhí)行一次
    void delay(uint x)
        {
             uint i, j;
             for(i=x;i>0;i--)
                  for(j=0;j>0;j--); //這句根本就不執(zhí)行         
         }
作者: lkc8210    時(shí)間: 2022-2-8 10:39
1。main內(nèi)的主while一定是while(1)
2。中斷內(nèi)不要用delay
3。一鍵啟停請(qǐng)用下降沿觸發(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ù)制代碼

作者: maolijiang    時(shí)間: 2022-2-8 12:23
單片機(jī)用什么語(yǔ)言寫(xiě)的呀

作者: 廖振基    時(shí)間: 2022-2-8 12:24
lkc8210 發(fā)表于 2022-2-8 10:39
1。main內(nèi)的主while一定是while(1)
2。中斷內(nèi)不要用delay
3。一鍵啟停請(qǐng)用下降沿觸發(fā),IT1 = 1;

太感謝了。
作者: 廖振基    時(shí)間: 2022-2-8 18:30
已經(jīng)解決了,不過(guò)不是很理想,外中斷程序里不能延時(shí)去抖動(dòng),造成按鍵仍然有一定的幾率出錯(cuò)。
作者: 廖振基    時(shí)間: 2022-2-8 18:40
已經(jīng)解決問(wèn)題了,但是不理想,延時(shí)去抖不能用在中斷程序里,造成按鍵不可靠,進(jìn)入中斷后關(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;
}
                           
作者: lkc8210    時(shí)間: 2022-2-9 08:03
廖振基 發(fā)表于 2022-2-8 18:40
已經(jīng)解決問(wèn)題了,但是不理想,延時(shí)去抖不能用在中斷程序里,造成按鍵不可靠,進(jìn)入中斷后關(guān)掉中斷效果也不好 ...

請(qǐng)參考我的消抖方法~
其實(shí)你這種情況完全沒(méi)必要用中斷
作者: 廖振基    時(shí)間: 2022-2-9 13:49
謝謝指點(diǎn),用中斷主要是考慮到,:如果程序有較長(zhǎng)時(shí)間的循環(huán)等待時(shí),非中斷暫停鍵就不會(huì)快速響應(yīng),當(dāng)然,這個(gè)程序例可以不需要。
作者: wulin    時(shí)間: 2022-2-9 15:43
廖振基 發(fā)表于 2022-2-8 18:40
已經(jīng)解決問(wèn)題了,但是不理想,延時(shí)去抖不能用在中斷程序里,造成按鍵不可靠,進(jìn)入中斷后關(guān)掉中斷效果也不好 ...

簡(jiǎn)單的問(wè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ù)制代碼

作者: 廖振基    時(shí)間: 2022-2-10 16:29
非常感謝回答,將程序下載單片機(jī)后,喇叭不響,自己稍微改動(dòng)一下,仍然不響,可是按照程序推理應(yīng)該可以運(yùn)行的。確定硬件沒(méi)有問(wèn)題,更換以前程序可以響的,只是不可靠。

                                 #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;
}*/        
作者: lkc8210    時(shí)間: 2022-2-10 20:51
廖振基 發(fā)表于 2022-2-9 13:49
謝謝指點(diǎn),用中斷主要是考慮到,:如果程序有較長(zhǎng)時(shí)間的循環(huán)等待時(shí),非中斷暫停鍵就不會(huì)快速響應(yīng),當(dāng)然,這 ...

正常寫(xiě)程序應(yīng)避免產(chǎn)生長(zhǎng)時(shí)間的循環(huán)
見(jiàn)到那些Delay(10)的按鍵消抖/數(shù)碼管顯示和while(!key)松開(kāi)檢測(cè)
就覺(jué)得是白白浪費(fèi)了單片機(jī)的速度
就算是最老的51單片機(jī)都可以1微秒一條指令
10毫秒可以跑上千條指令
所以你的思路不應(yīng)該去想用中斷快速反應(yīng)按鍵
而是要去想如何減少使用阻塞式延時(shí)
作者: AUG    時(shí)間: 2022-2-11 10:13
按鍵可以使用狀態(tài)機(jī),能夠有效的去除阻塞延時(shí)。
作者: xws245925587    時(shí)間: 2022-2-11 10:20
按鍵按下后,開(kāi)啟定時(shí)器計(jì)時(shí)消抖
作者: robinsonlin    時(shí)間: 2022-2-11 13:55
廖振基 發(fā)表于 2022-2-8 18:40
已經(jīng)解決問(wèn)題了,但是不理想,延時(shí)去抖不能用在中斷程序里,造成按鍵不可靠,進(jìn)入中斷后關(guān)掉中斷效果也不好 ...

好辦法就是學(xué)會(huì)用定時(shí)器中斷,通過(guò)定時(shí)器中斷,在程序中植入毫秒計(jì)時(shí),也就是經(jīng)常在例程中看到的 SysTick++操作。程序中所有的延遲,都可以通過(guò)對(duì)SysTick時(shí)鐘的比對(duì)來(lái)實(shí)現(xiàn)。 如你要Delay(20ms);可以對(duì)時(shí)間變量T1= SysTick;取值,然后判斷 通過(guò)判斷 SysTick-T1是否大于20來(lái)實(shí)現(xiàn)延遲,多看例程。
作者: 廖振基    時(shí)間: 2022-2-11 16:49
謝謝大家的指點(diǎn),知識(shí)量有點(diǎn)多,我先去研究研究了。再次謝謝大家。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1