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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1939|回復: 26
收起左側

單片機定時器按鍵掃描問題

[復制鏈接]
ID:1114858 發表于 2024-4-7 20:54 | 顯示全部樓層 |閱讀模式
大佬們我想問一下加了if(Temp)這里為什么按鍵就非常不靈敏了,不加判斷返回值是否為0代碼就能正確檢測到按鍵,這個if(Temp)判斷返回值是否為0為什么會導致按鍵操作不靈敏,這個是測試的,后面必須要用到判斷是否為0,不是很理解,求大佬能指點一二

單片機源程序如下:
#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//中斷函數
{
        static unsigned char count;//計數范圍為0-256
        TL0 = 0x66;
        TH0 = 0xFC;        
        count++;
        if(count>=20)
        {
                count=0;
                key_Interrupt();//按鍵中斷
               
        }
        
}



這是Key里面的函數
#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()//按鍵中斷函數
{
        
        static unsigned char Last_Status=0,Now_Status=0;
        Last_Status=Now_Status;
        Now_Status=Key_Timer0();//現態次態檢測
        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;
        
        }
        
        
}

秒表設計.rar

55.56 KB, 下載次數: 4

回復

使用道具 舉報

ID:1114858 發表于 2024-4-7 22:04 | 顯示全部樓層
麻煩各位大佬幫忙看一下,這個問題確實很奇怪,if判斷體里面是可以正常進入的,在里面計數都可以,但是一旦使用按鍵相關的操作,按鍵就變得十分不靈敏,有點想不明白
回復

使用道具 舉報

ID:1114858 發表于 2024-4-7 22:46 | 顯示全部樓層
我將  Temp=Keynum_return()    Delay(1)    if(Temp)中間加了一個延時函數代碼就能正常跑起來,這個是什么原因,確實不大明白問題出在哪,我剛學不久,麻煩大佬們指點一二
回復

使用道具 舉報

ID:1114858 發表于 2024-4-8 09:57 來自手機 | 顯示全部樓層
判斷體可以進去,里面賦值也可以正常操作,但是里面調用按鍵就不行這是為啥啊,
回復

使用道具 舉報

ID:140489 發表于 2024-4-8 11:51 | 顯示全部樓層
if(Temp)就等同于 if(Temp==1),只有if(Temp==1),按鍵才會動作
回復

使用道具 舉報

ID:1114858 發表于 2024-4-8 13:49 來自手機 | 顯示全部樓層
lids 發表于 2024-4-8 11:51
if(Temp)就等同于 if(Temp==1),只有if(Temp==1),按鍵才會動作

謝謝您的回復,if判斷條件只要不是0就應該為真,執行判斷里面的語句,判斷是可以進去的,就是按鍵判斷不靈敏這個問題
回復

使用道具 舉報

ID:961114 發表于 2024-4-8 15:27 | 顯示全部樓層
分享一個簡單的按鍵掃描程序,方便有需要的用戶搜索參考。
例程使用定時器分時調度,定時每毫秒檢測一次按鍵狀態,有按鍵時累加計數器,沒有按鍵時清除計數器。
連續計數50次表明按鍵按下并持續50ms(防抖),設置按鍵有效狀態標志:

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

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

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

此外,推薦一份社區大神分享的按鍵掃描方法介紹的帖子:
分享 按鍵程序,大道至簡,按鍵掃描 + 累計主循環次數去抖動/不占用定時器

回復

使用道具 舉報

ID:1109793 發表于 2024-4-8 16:05 | 顯示全部樓層
下一站過后 發表于 2024-4-8 13:49
謝謝您的回復,if判斷條件只要不是0就應該為真,執行判斷里面的語句,判斷是可以進去的,就是按鍵判斷不 ...

看不懂,這是在硬件上測試的?我記得位變量反轉用!的,字節才是~
回復

使用道具 舉報

ID:1114858 發表于 2024-4-8 17:01 來自手機 | 顯示全部樓層
xiaobendan001 發表于 2024-4-8 16:05
看不懂,這是在硬件上測試的?我記得位變量反轉用!的,字節才是~

謝謝您的回復,程序是在51單片機上面跑的,反轉的操作這樣寫應該沒問題,我在主函數里可以跑
回復

使用道具 舉報

ID:1114858 發表于 2024-4-8 17:03 來自手機 | 顯示全部樓層
STC莊偉 發表于 2024-4-8 15:27
分享一個簡單的按鍵掃描程序,方便有需要的用戶搜索參考。
例程使用定時器分時調度,定時每毫秒檢測一次按 ...

謝謝您的回復,我參考下
回復

使用道具 舉報

ID:1109793 發表于 2024-4-8 17:08 | 顯示全部樓層
本質上 if(Temp)應該么有影響的啊
回復

使用道具 舉報

ID:1114858 發表于 2024-4-8 17:17 來自手機 | 顯示全部樓層
xiaobendan001 發表于 2024-4-8 17:08
本質上 if(Temp)應該么有影響的啊

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

使用道具 舉報

ID:1109793 發表于 2024-4-8 18:37 | 顯示全部樓層
實在搞不清楚
這樣改改試試
  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;                                                //加一個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.                         //按鍵操作放在這個循環里就會不靈敏
  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//中斷函數
  40. {
  41.         static unsigned char count;//計數范圍為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. }
復制代碼
回復

使用道具 舉報

ID:1114858 發表于 2024-4-8 18:50 來自手機 | 顯示全部樓層
xiaobendan001 發表于 2024-4-8 18:37
實在搞不清楚
這樣改改試試

謝謝您的回復,我試試看
回復

使用道具 舉報

ID:161164 發表于 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. }
復制代碼
回復

使用道具 舉報

ID:384109 發表于 2024-4-8 23:01 | 顯示全部樓層
Key_num沒在頭文件里聲明吧
回復

使用道具 舉報

ID:517951 發表于 2024-4-9 08:41 | 顯示全部樓層
軟件搞得復雜了, 定時器中斷服務函數里面調用按鍵中斷服務函數. 這思路還是有問題. 按鍵中斷可以直接響應其服務函數了, 為什么還要在定時器中斷里面去搞按鍵中斷響應?
回復

使用道具 舉報

ID:192020 發表于 2024-4-9 09:19 | 顯示全部樓層
下一站過后 發表于 2024-4-7 22:46
我將  Temp=Keynum_return()    Delay(1)    if(Temp)中間加了一個延時函數代碼就能正常跑起來,這個是什么 ...

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

使用道具 舉報

ID:1109793 發表于 2024-4-9 09:35 | 顯示全部樓層
下一站過后 發表于 2024-4-8 18:50
謝謝您的回復,我試試看

抱歉,上面代碼16行里面那個tointer輸入錯誤,應該是t0inter
回復

使用道具 舉報

ID:1114858 發表于 2024-4-9 13:49 來自手機 | 顯示全部樓層
lkc8210 發表于 2024-4-8 22:50
太累贅了

謝謝您的回復,您的解決方法確實簡便很多,我在學習學習
回復

使用道具 舉報

ID:1114858 發表于 2024-4-9 13:49 來自手機 | 顯示全部樓層
rayin 發表于 2024-4-9 08:41
軟件搞得復雜了, 定時器中斷服務函數里面調用按鍵中斷服務函數. 這思路還是有問題. 按鍵中斷可以直接響應其 ...

確實,您說的很有道理,我在思考下,謝謝您的回復
回復

使用道具 舉報

ID:1114858 發表于 2024-4-9 13:50 來自手機 | 顯示全部樓層
xiaobendan001 發表于 2024-4-9 09:35
抱歉,上面代碼16行里面那個tointer輸入錯誤,應該是t0inter

謝謝您,我按照這個思路改了下確實可行,謝謝
回復

使用道具 舉報

ID:1114858 發表于 2024-4-9 13:51 來自手機 | 顯示全部樓層
qq475878026 發表于 2024-4-9 09:19
加delay正常的話有可能是中斷已經將按鍵執行兩次判定了,然后主函數剛好將引腳反轉兩次,肉眼看不出來就 ...

這個問題我確實沒考慮到,我回去試試看,謝謝您
回復

使用道具 舉報

ID:1109793 發表于 2024-4-9 14:06 | 顯示全部樓層
下一站過后 發表于 2024-4-9 13:50
謝謝您,我按照這個思路改了下確實可行,謝謝

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

使用道具 舉報

ID:1114858 發表于 2024-4-9 22:32 | 顯示全部樓層
xiaobendan001 發表于 2024-4-9 14:06
那么你根據這個改法,有沒有思考到之前的代碼的問題究竟出在哪兒?

  這個問題我也想了很久,改過之后的代碼邏輯變為只有進入中斷,掃描了按鍵才會在主函數里進行判斷,邏輯上確實更清晰,我的代碼是會一直接收返回值進行判斷,這個我確實沒想明白我的代碼是哪里的原因,我覺得這兩種方法邏輯上都能跑的通的,我想是因為我對機器了解程度還不夠,還望大佬能指點一下是哪里出現的問題。萬分感謝。
回復

使用道具 舉報

ID:1109793 發表于 2024-4-10 07:44 | 顯示全部樓層
下一站過后 發表于 2024-4-9 22:32
這個問題我也想了很久,改過之后的代碼邏輯變為只有進入中斷,掃描了按鍵才會在主函數里進行判斷,邏輯 ...

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

使用道具 舉報

ID:1114858 發表于 2024-4-12 19:43 | 顯示全部樓層
xiaobendan001 發表于 2024-4-10 07:44
我也只是分析,我覺得你增加delay或者使用4個if的結果是會影響到主循環的循環速度,當使用一個if包裹之后 ...

你講的確實是我沒有考慮到的問題,確實是有這個可能性,我都沒忘這方面去考慮,謝謝
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩中文av在线 | 国产传媒在线观看 | 国产在线第一页 | 成人免费在线电影 | 久热久草 | 97免费在线观看视频 | 日韩三级一区 | 欧美精品一二三区 | 久久亚洲一区 | 国产精品电影在线观看 | 精品久久久久久久久久久久 | 久久久久久美女 | 国产高清区| 日本精品视频在线 | 国产美女黄色片 | 成人av一区二区三区 | 精品国产乱码久久久久久蜜臀 | 国产黄色一级片 | 中文字幕一区在线观看视频 | 天天干天天玩天天操 | 在线电影日韩 | 国产日韩精品一区二区 | 国产精品久久久久久久一区二区 | 亚洲人成在线播放 | 欧美综合国产精品久久丁香 | 1区2区3区视频 | 久久精选 | 男女免费视频网站 | 日日夜夜天天 | 欧美一级二级在线观看 | 国产9999精品 | 欧美精品在欧美一区二区少妇 | 亚洲精品中文字幕在线观看 | 男人天堂99| 超碰在线播 | 亚洲成人午夜电影 | 精品国产欧美在线 | 欧美三级电影在线播放 | 91视频在线| 欧美成人a∨高清免费观看 欧美日韩中 | 韩日精品一区 |