找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機(jī)定時(shí)器按鍵掃描問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1114858 發(fā)表于 2024-4-7 20:54 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
大佬們我想問一下加了if(Temp)這里為什么按鍵就非常不靈敏了,不加判斷返回值是否為0代碼就能正確檢測到按鍵,這個(gè)if(Temp)判斷返回值是否為0為什么會(huì)導(dǎo)致按鍵操作不靈敏,這個(gè)是測試的,后面必須要用到判斷是否為0,不是很理解,求大佬能指點(diǎn)一二

單片機(jī)源程序如下:
#include <REGX52.H>
#include "LCD1602.H"
#include "AT24C02.H"
#include "Delay.H"
#include "Timer0Init.H"
#include "Key.H"
void main()
{
        unsigned char Temp=0;
        Timer0Init();
        while(1)
        {
                Temp=Keynum_return();
                if(Temp)//加了判斷按鍵就不靈敏,不加就很正常
                {
                        
                                if(Temp==1)
                                        P2_0=~P2_0;
                                if(Temp==2)
                                        P2_1=~P2_1;
                                if(Temp==3)
                                        P2_2=~P2_2;
                                if(Temp==4)
                                        P2_3=~P2_3;
                        
                                
                }
        }
}



void Timer0_Rountine(void) interrupt 1//中斷函數(shù)
{
        static unsigned char count;//計(jì)數(shù)范圍為0-256
        TL0 = 0x66;
        TH0 = 0xFC;        
        count++;
        if(count>=20)
        {
                count=0;
                key_Interrupt();//按鍵中斷
               
        }
        
}



這是Key里面的函數(shù)
#include <REGX52.H>

unsigned char Key_num;


unsigned char Keynum_return()
{
        unsigned char Temp=0;
        
        Temp=Key_num;
        
        Key_num=0;
        
        return Temp;


}


unsigned char Key_Timer0()
{
        
        unsigned char KeyNumber=0;
        
        
        if(P3_1==0){KeyNumber=1;}                        
        if(P3_0==0){KeyNumber=2;}
        if(P3_2==0){KeyNumber=3;}
        if(P3_3==0){KeyNumber=4;}
        
        return KeyNumber;
        
}
        


void key_Interrupt()//按鍵中斷函數(shù)
{
        
        static unsigned char Last_Status=0,Now_Status=0;
        Last_Status=Now_Status;
        Now_Status=Key_Timer0();//現(xiàn)態(tài)次態(tài)檢測
        if(        Last_Status==1 && Now_Status==0)
        {
                        Key_num=1;
        
        }
        if(        Last_Status==2 && Now_Status==0)
        {
                        Key_num=2;
        
        }
               
        if(        Last_Status==3 && Now_Status==0)
        {
                        Key_num=3;
        
        }
               
        if(        Last_Status==4 && Now_Status==0)
        {
                        Key_num=4;
        
        }
        
        
}

秒表設(shè)計(jì).rar

55.56 KB, 下載次數(shù): 4

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

使用道具 舉報(bào)

沙發(fā)
ID:1114858 發(fā)表于 2024-4-7 22:04 | 只看該作者
麻煩各位大佬幫忙看一下,這個(gè)問題確實(shí)很奇怪,if判斷體里面是可以正常進(jìn)入的,在里面計(jì)數(shù)都可以,但是一旦使用按鍵相關(guān)的操作,按鍵就變得十分不靈敏,有點(diǎn)想不明白
回復(fù)

使用道具 舉報(bào)

板凳
ID:1114858 發(fā)表于 2024-4-7 22:46 | 只看該作者
我將  Temp=Keynum_return()    Delay(1)    if(Temp)中間加了一個(gè)延時(shí)函數(shù)代碼就能正常跑起來,這個(gè)是什么原因,確實(shí)不大明白問題出在哪,我剛學(xué)不久,麻煩大佬們指點(diǎn)一二
回復(fù)

使用道具 舉報(bào)

地板
ID:1114858 發(fā)表于 2024-4-8 09:57 來自手機(jī) | 只看該作者
判斷體可以進(jìn)去,里面賦值也可以正常操作,但是里面調(diào)用按鍵就不行這是為啥啊,
回復(fù)

使用道具 舉報(bào)

5#
ID:140489 發(fā)表于 2024-4-8 11:51 | 只看該作者
if(Temp)就等同于 if(Temp==1),只有if(Temp==1),按鍵才會(huì)動(dòng)作
回復(fù)

使用道具 舉報(bào)

6#
ID:1114858 發(fā)表于 2024-4-8 13:49 來自手機(jī) | 只看該作者
lids 發(fā)表于 2024-4-8 11:51
if(Temp)就等同于 if(Temp==1),只有if(Temp==1),按鍵才會(huì)動(dòng)作

謝謝您的回復(fù),if判斷條件只要不是0就應(yīng)該為真,執(zhí)行判斷里面的語句,判斷是可以進(jìn)去的,就是按鍵判斷不靈敏這個(gè)問題
回復(fù)

使用道具 舉報(bào)

7#
ID:961114 發(fā)表于 2024-4-8 15:27 | 只看該作者
分享一個(gè)簡單的按鍵掃描程序,方便有需要的用戶搜索參考。
例程使用定時(shí)器分時(shí)調(diào)度,定時(shí)每毫秒檢測一次按鍵狀態(tài),有按鍵時(shí)累加計(jì)數(shù)器,沒有按鍵時(shí)清除計(jì)數(shù)器。
連續(xù)計(jì)數(shù)50次表明按鍵按下并持續(xù)50ms(防抖),設(shè)置按鍵有效狀態(tài)標(biāo)志:

        if(!KEY1)
        {
            if(!Key1_Flag)
            {
                Key1_cnt++;
                if(Key1_cnt >= 50)                //50ms防抖
                {
                    Key1_Flag = 1;                        //設(shè)置按鍵狀態(tài),防止重復(fù)觸發(fā)
                    Key1_Function = 1;
                }
            }
        }
        else
        {
            Key1_cnt = 0;
            Key1_Flag = 0;
        }

檢測連續(xù)1s為低電平則判定按鍵長按有效;連續(xù)低電平時(shí)間大于50ms并小于1s則判定為按鍵短按有效:

        if(!KEY2)
        {
            if(!Key2_Flag)
            {
                Key2_cnt++;
                if(Key2_cnt >= 1000)                //長按1s
                {
                    Key2_Short_Flag = 0;        //清除短按標(biāo)志
                    Key2_Long_Flag = 1;                //設(shè)置長按標(biāo)志
                    Key2_Flag = 1;                                //設(shè)置按鍵狀態(tài),防止重復(fù)觸發(fā)
                    Key2_Long_Function = 1;
                }
                else if(Key2_cnt >= 50)                //50ms防抖
                {
                    Key2_Short_Flag = 1;                //設(shè)置短按標(biāo)志
                }
            }
        }
        else
        {
            if(Key2_Short_Flag)                        //判斷是否短按
            {
                Key2_Short_Flag = 0;        //清除短按標(biāo)志
                Key2_Short_Function = 1;
            }
            Key2_cnt = 0;
            Key2_Flag = 0;        //按鍵釋放
        }
    }

此外,推薦一份社區(qū)大神分享的按鍵掃描方法介紹的帖子:
分享 按鍵程序,大道至簡,按鍵掃描 + 累計(jì)主循環(huán)次數(shù)去抖動(dòng)/不占用定時(shí)器

回復(fù)

使用道具 舉報(bào)

8#
ID:1109793 發(fā)表于 2024-4-8 16:05 | 只看該作者
下一站過后 發(fā)表于 2024-4-8 13:49
謝謝您的回復(fù),if判斷條件只要不是0就應(yīng)該為真,執(zhí)行判斷里面的語句,判斷是可以進(jìn)去的,就是按鍵判斷不 ...

看不懂,這是在硬件上測試的?我記得位變量反轉(zhuǎn)用!的,字節(jié)才是~
回復(fù)

使用道具 舉報(bào)

9#
ID:1114858 發(fā)表于 2024-4-8 17:01 來自手機(jī) | 只看該作者
xiaobendan001 發(fā)表于 2024-4-8 16:05
看不懂,這是在硬件上測試的?我記得位變量反轉(zhuǎn)用!的,字節(jié)才是~

謝謝您的回復(fù),程序是在51單片機(jī)上面跑的,反轉(zhuǎn)的操作這樣寫應(yīng)該沒問題,我在主函數(shù)里可以跑
回復(fù)

使用道具 舉報(bào)

10#
ID:1114858 發(fā)表于 2024-4-8 17:03 來自手機(jī) | 只看該作者
STC莊偉 發(fā)表于 2024-4-8 15:27
分享一個(gè)簡單的按鍵掃描程序,方便有需要的用戶搜索參考。
例程使用定時(shí)器分時(shí)調(diào)度,定時(shí)每毫秒檢測一次按 ...

謝謝您的回復(fù),我參考下
回復(fù)

使用道具 舉報(bào)

11#
ID:1109793 發(fā)表于 2024-4-8 17:08 | 只看該作者
本質(zhì)上 if(Temp)應(yīng)該么有影響的啊
回復(fù)

使用道具 舉報(bào)

12#
ID:1114858 發(fā)表于 2024-4-8 17:17 來自手機(jī) | 只看該作者
xiaobendan001 發(fā)表于 2024-4-8 17:08
本質(zhì)上 if(Temp)應(yīng)該么有影響的啊

對(duì)啊,我想了一宿也沒想明白啊,C語言語法書都翻幾遍了,真想不出來哪里的問題
回復(fù)

使用道具 舉報(bào)

13#
ID:1109793 發(fā)表于 2024-4-8 18:37 | 只看該作者
實(shí)在搞不清楚
這樣改改試試
  1. #include <REGX52.H>
  2. #include "LCD1602.H"
  3. #include "AT24C02.H"
  4. #include "Delay.H"
  5. #include "Timer0Init.H"
  6. #include "Key.H"
  7. #include "Nixie_tube.H"
  8. bit t0inter;                                                //加一個(gè)BIT
  9. void main()
  10. {
  11.         unsigned char i=0;
  12.         unsigned char Temp=0,Temp_1;
  13.         Timer0Init();
  14.         while(1)
  15.         {
  16.                 if(tointer){                                                //這里增加
  17.                         Temp=Keynum_return();
  18.                         t0inter = 0;
  19.                 }
  20.                 if(Temp)
  21.                 {
  22.                         //按鍵操作放在這個(gè)循環(huán)里就會(huì)不靈敏
  23.                         if(Temp==1)
  24.                                                         P2_0=~P2_0;
  25.                         if(Temp==2)
  26.                                                         P2_1=~P2_1;
  27.                         if(Temp==3)
  28.                                                         P2_2=~P2_2;
  29.                         if(Temp==4)
  30.                                                         P2_3=~P2_3;
  31.                 i++;
  32.                        
  33.                 }
  34.                 P2=~(0x80>>i);       

  35.                
  36.                
  37.         }
  38. }



  39. void Timer0_Rountine(void) interrupt 1//中斷函數(shù)
  40. {
  41.         static unsigned char count;//計(jì)數(shù)范圍為0-256
  42.         TL0 = 0x66;
  43.         TH0 = 0xFC;       
  44.         t0inter = 1;                                                //這里增加
  45.         count++;
  46.         if(count>=10)
  47.         {
  48.                 count=0;
  49.                 key_Interrupt();//按鍵中斷
  50.                
  51.         }
  52.        
  53. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

14#
ID:1114858 發(fā)表于 2024-4-8 18:50 來自手機(jī) | 只看該作者
xiaobendan001 發(fā)表于 2024-4-8 18:37
實(shí)在搞不清楚
這樣改改試試

謝謝您的回復(fù),我試試看
回復(fù)

使用道具 舉報(bào)

15#
ID:161164 發(fā)表于 2024-4-8 22:50 | 只看該作者
太累贅了
  1. void main()
  2. {
  3.         Timer0Init();
  4.         while(1)
  5.         {
  6.                 if(Key_num)//加了判斷按鍵就不靈敏,不加就很正常
  7.                 {
  8.                         if(Key_num==1)
  9.                                 P2_0=~P2_0;
  10.                         if(Key_num==2)
  11.                                 P2_1=~P2_1;
  12.                         if(Key_num==3)
  13.                                 P2_2=~P2_2;
  14.                         if(Key_num==4)
  15.                                 P2_3=~P2_3;
  16.                         Key_num = 0;
  17.                 }
  18.         }
  19. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

16#
ID:384109 發(fā)表于 2024-4-8 23:01 | 只看該作者
Key_num沒在頭文件里聲明吧
回復(fù)

使用道具 舉報(bào)

17#
ID:517951 發(fā)表于 2024-4-9 08:41 | 只看該作者
軟件搞得復(fù)雜了, 定時(shí)器中斷服務(wù)函數(shù)里面調(diào)用按鍵中斷服務(wù)函數(shù). 這思路還是有問題. 按鍵中斷可以直接響應(yīng)其服務(wù)函數(shù)了, 為什么還要在定時(shí)器中斷里面去搞按鍵中斷響應(yīng)?
回復(fù)

使用道具 舉報(bào)

18#
ID:192020 發(fā)表于 2024-4-9 09:19 | 只看該作者
下一站過后 發(fā)表于 2024-4-7 22:46
我將  Temp=Keynum_return()    Delay(1)    if(Temp)中間加了一個(gè)延時(shí)函數(shù)代碼就能正常跑起來,這個(gè)是什么 ...

加delay正常的話有可能是中斷已經(jīng)將按鍵執(zhí)行兩次判定了,然后主函數(shù)剛好將引腳反轉(zhuǎn)兩次,肉眼看不出來就感覺是不靈敏,可以試下邏輯分析儀或者示波器量一下翻轉(zhuǎn)的引腳
回復(fù)

使用道具 舉報(bào)

19#
ID:1109793 發(fā)表于 2024-4-9 09:35 | 只看該作者
下一站過后 發(fā)表于 2024-4-8 18:50
謝謝您的回復(fù),我試試看

抱歉,上面代碼16行里面那個(gè)tointer輸入錯(cuò)誤,應(yīng)該是t0inter
回復(fù)

使用道具 舉報(bào)

20#
ID:1114858 發(fā)表于 2024-4-9 13:49 來自手機(jī) | 只看該作者
lkc8210 發(fā)表于 2024-4-8 22:50
太累贅了

謝謝您的回復(fù),您的解決方法確實(shí)簡便很多,我在學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

21#
ID:1114858 發(fā)表于 2024-4-9 13:49 來自手機(jī) | 只看該作者
rayin 發(fā)表于 2024-4-9 08:41
軟件搞得復(fù)雜了, 定時(shí)器中斷服務(wù)函數(shù)里面調(diào)用按鍵中斷服務(wù)函數(shù). 這思路還是有問題. 按鍵中斷可以直接響應(yīng)其 ...

確實(shí),您說的很有道理,我在思考下,謝謝您的回復(fù)
回復(fù)

使用道具 舉報(bào)

22#
ID:1114858 發(fā)表于 2024-4-9 13:50 來自手機(jī) | 只看該作者
xiaobendan001 發(fā)表于 2024-4-9 09:35
抱歉,上面代碼16行里面那個(gè)tointer輸入錯(cuò)誤,應(yīng)該是t0inter

謝謝您,我按照這個(gè)思路改了下確實(shí)可行,謝謝
回復(fù)

使用道具 舉報(bào)

23#
ID:1114858 發(fā)表于 2024-4-9 13:51 來自手機(jī) | 只看該作者
qq475878026 發(fā)表于 2024-4-9 09:19
加delay正常的話有可能是中斷已經(jīng)將按鍵執(zhí)行兩次判定了,然后主函數(shù)剛好將引腳反轉(zhuǎn)兩次,肉眼看不出來就 ...

這個(gè)問題我確實(shí)沒考慮到,我回去試試看,謝謝您
回復(fù)

使用道具 舉報(bào)

24#
ID:1109793 發(fā)表于 2024-4-9 14:06 | 只看該作者
下一站過后 發(fā)表于 2024-4-9 13:50
謝謝您,我按照這個(gè)思路改了下確實(shí)可行,謝謝

那么你根據(jù)這個(gè)改法,有沒有思考到之前的代碼的問題究竟出在哪兒?
回復(fù)

使用道具 舉報(bào)

25#
ID:1114858 發(fā)表于 2024-4-9 22:32 | 只看該作者
xiaobendan001 發(fā)表于 2024-4-9 14:06
那么你根據(jù)這個(gè)改法,有沒有思考到之前的代碼的問題究竟出在哪兒?

  這個(gè)問題我也想了很久,改過之后的代碼邏輯變?yōu)橹挥羞M(jìn)入中斷,掃描了按鍵才會(huì)在主函數(shù)里進(jìn)行判斷,邏輯上確實(shí)更清晰,我的代碼是會(huì)一直接收返回值進(jìn)行判斷,這個(gè)我確實(shí)沒想明白我的代碼是哪里的原因,我覺得這兩種方法邏輯上都能跑的通的,我想是因?yàn)槲覍?duì)機(jī)器了解程度還不夠,還望大佬能指點(diǎn)一下是哪里出現(xiàn)的問題。萬分感謝。
回復(fù)

使用道具 舉報(bào)

26#
ID:1109793 發(fā)表于 2024-4-10 07:44 | 只看該作者
下一站過后 發(fā)表于 2024-4-9 22:32
這個(gè)問題我也想了很久,改過之后的代碼邏輯變?yōu)橹挥羞M(jìn)入中斷,掃描了按鍵才會(huì)在主函數(shù)里進(jìn)行判斷,邏輯 ...

我也只是分析,我覺得你增加delay或者使用4個(gè)if的結(jié)果是會(huì)影響到主循環(huán)的循環(huán)速度,當(dāng)使用一個(gè)if包裹之后使得Keynum_return()被調(diào)用的頻率明顯的增加,這使中斷發(fā)生在函數(shù)內(nèi)部的可能性增加很多。比如temp在取得key_num的時(shí)候中斷尚未把key_num更新,在更新了以后立刻又被你下一行清零了。這種雖然比較牽強(qiáng),但是可能性還是有的。配合的好就行。
我的習(xí)慣就是要么搞一個(gè)bit,要么把按鍵識(shí)別直接放中斷服務(wù),反正1ms甚至2ms時(shí)間能做很多事情。除了顯示(利用芯片比如1638,或者液晶)放主循環(huán)自由運(yùn)行,其他的都用狀態(tài)或者直接放中斷服務(wù)。
回復(fù)

使用道具 舉報(bào)

27#
ID:1114858 發(fā)表于 2024-4-12 19:43 | 只看該作者
xiaobendan001 發(fā)表于 2024-4-10 07:44
我也只是分析,我覺得你增加delay或者使用4個(gè)if的結(jié)果是會(huì)影響到主循環(huán)的循環(huán)速度,當(dāng)使用一個(gè)if包裹之后 ...

你講的確實(shí)是我沒有考慮到的問題,確實(shí)是有這個(gè)可能性,我都沒忘這方面去考慮,謝謝
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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