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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機獨立按鍵短按加1,長按連加總是無法實現,問題在哪?

[復制鏈接]
跳轉到指定樓層
樓主
ID:997026 發表于 2022-2-13 19:42 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
最近在做單片機獨立按鍵長按連加,短按加1的功能,網上找了很多例子,都不是很滿意,試了很多都不成功。最后找了一個很多人在用的代碼,不知道什么原因,在我這邊總是無法實現功能,搞了好幾天都不能解決,修修改改無數次,實在是沒思路了。以下是這部分代碼,希望大神賜教!

現在的主要問題是:
1,只能實現短按一次的功能,即數碼管顯示0時,短按一下可以增加到1,再按就沒反應了。
2,應該是KEY_SCAN() 和KEY_PROCESS()這兩個函數的問題,但是找了好久,改了很多也沒解決問題,現在沒有思路了。按鍵掃描函數KEY_SCAN()是在網上找的朱兆琪學習板的程序,我用的單片機是AVR的,在我上面怎么都用不了,不知道啥問題,不知道是程序問題還是硬件問題,感覺硬件沒啥問題,換另一種寫法就沒問題,但是如下寫法總是不行。

單片機源程序如下:
unsigned char   key_number=0;  //觸發的按鍵編號
unsigned short  key_time_delay_cnt_SW1 =0;   // SW1 按鍵去抖動計數器
unsigned char   key_lock_SW1=0;              // SW1 自鎖變量
unsigned short  key_cont_trigg_cnt_SW1 =0;   //SW1連加計數器


unsigned short  key_start_cnt1 =0; //中斷啟動計數器標志位
unsigned short  key_start_cnt2 =0;
unsigned short  key_start_trigg_cnt1 =0;
unsigned short  key_start_trigg_cnt2 =0;




uint8_t KEY_SCAN(void);  // 按鍵掃描函數
void KEY_PROCESS(uint8_t);  //按鍵處理函數



int  main(void)

{
  KEY_PROCESS(P_min_set_temp_ON);  //P_min_set_temp_ON在數碼管上顯示分和秒
}



uint8_t  KEY_SCAN(void)

{
        // 掃描SW1
        if (1==KEY_SW1)  //按鍵沒有被按下(高電平),清零標志位
        {
                key_lock_SW1 =0;  //自鎖標志位清零
                key_time_delay_cnt_SW1=0; //去抖延時清零
                key_start_cnt1=0;  //在中斷中啟動計數
                key_cont_trigg_cnt_SW1 =0;
                key_start_trigg_cnt1=0; //在中斷中啟動計數
        }
        
        else if (0==key_lock_SW1) //如果有按鍵按下,且是第一次按下
        {
                key_start_cnt1=1;  //中斷中啟動計數器,key_time_delay_cnt_SW1開始自加
                if (key_time_delay_cnt_SW1 > KEY_TIME_DELAY_SW1) //自加到10mms去抖動,KEY_TIME_DELAY_SW1為進入中斷10次,約10ms
                {
                        key_time_delay_cnt_SW1 =0;
                        key_start_cnt1=0;
                        key_lock_SW1=1;
                        key_number=1; //觸發 一次SW1單次觸發,如果松手,立即返回到if (KEY_SW1)
               
                }
        }

        else if (key_time_delay_cnt_SW1 < KEY_TIME_ALWAYS_PRESS) //如果按住不放, 在1s內自加,KEY_TIME_ALWAYS_PRESS為1s
        {
                key_start_cnt1=1;
        }
        
        else  //持續按住大于1s時,進入連加狀態
        {
                key_start_trigg_cnt1=1; //啟動key_cont_trigg_cnt_SW1自加
                if (key_cont_trigg_cnt_SW1 > KEY_TIME_SEQ_INTER)  //自加到250ms后,清零,KEY_TIME_SEQ_INTER為250ms
                {
                        key_cont_trigg_cnt_SW1 =0;
                        key_start_trigg_cnt2=0;
                        key_number =2; //觸發SW1連續觸發,實現長按SW1超過1s, 產生每250ms觸發一次按鍵的效果
               
                }
        }

   return  key_number; //返回按鍵編號值

}


void KEY_PROCESS (uint8_t min_sec_set_temp)

{  
            KEY= KEY_SCAN(); //根據返回的按鍵編號值處理
                switch (KEY)
                {
                        case 1:  // SW1 單次觸發
                        min_sec_set_temp ++;
                        if (min_sec_set_temp >99)
                        {
                                min_sec_set_temp=0;
                        }
                        //key_number=0;
                        
                        break;
                        
                        case 2: //SW1開始連加觸發
                        min_sec_set_temp --;
                        if (min_sec_set_temp >99)
                        {
                                min_sec_set_temp=99;
                        }
                        
                        break;

                        
                        default: ; break;
                }
               
                min_decade=min_sec_set_temp /10; //數碼管顯示
                min_the_uint=min_sec_set_temp %10;
                sec_decade=min_sec_set_temp /10;
                sec_the_uint=min_sec_set_temp %10;
               
        
                DISPLAY_TIME_SET_MIN_SEC(1); //數碼管顯示函數,通過按鍵加減數字可以顯示出來               
}

        



ISR(TIMER1_OVF_vect) //中斷服務程序, 8M/256分頻,1ms進一次中斷

{
        TIFR1  =0x01; //中斷標志置位
        TIMSK1 =0x00;  //關中斷
        
    if (key_start_cnt1==1)
    {
                key_time_delay_cnt_SW1 ++;
    }
        
        else
        {
                key_time_delay_cnt_SW1=0;
        }
        
         if (key_start_cnt2==1)
         {
                 key_time_delay_cnt_SW2++;
         }
         else
         {
                 key_time_delay_cnt_SW2=0;
         }
         
         if (key_start_trigg_cnt1==1)
         {
                 key_cont_trigg_cnt_SW1 ++;
         }
         else
         {
                 key_cont_trigg_cnt_SW1=0;
         }
         
         if (key_start_trigg_cnt2==1)
         {
                 key_cont_trigg_cnt_SW2 ++;
         }
         else
         {
                 key_cont_trigg_cnt_SW2=0;
         }
        
         
        TCNT1H =0xFF; //計數器重裝初值高八位
        TCNT1L =0xE0; //計數器重裝初值低八位
        TIMSK1=0x01; //開中斷
}


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

使用道具 舉報

沙發
ID:301191 發表于 2022-2-14 01:32 | 只看該作者
頂一下
回復

使用道具 舉報

板凳
ID:213173 發表于 2022-2-14 05:43 | 只看該作者
給你一個應用示例參考
4位數碼管時鐘溫度表仿真.rar (175.42 KB, 下載次數: 32)

回復

使用道具 舉報

地板
ID:57657 發表于 2022-2-14 06:26 | 只看該作者
你可以看下這個框架是怎么實現長按連加的
http://www.zg4o1577.cn/bbs/dpj-214058-1.html
回復

使用道具 舉報

5#
ID:844772 發表于 2022-2-14 08:51 | 只看該作者
不是那兩個函數的問題,是你用它們的問題吧?   
case 2: //SW1開始連加觸發      
           min_sec_set_temp --; //為啥用--呢?明明是++的。
回復

使用道具 舉報

6#
ID:997026 發表于 2022-2-14 10:04 | 只看該作者
glinfei 發表于 2022-2-14 08:51
不是那兩個函數的問題,是你用它們的問題吧?   
case 2: //SW1開始連加觸發      
           min_sec_ ...

不是的,這個貼的時候注釋沒改過來。實際程序不是這樣的。
回復

使用道具 舉報

7#
ID:997026 發表于 2022-2-14 10:08 | 只看該作者
wulin 發表于 2022-2-14 05:43
給你一個應用示例參考

感謝!我研究一下
回復

使用道具 舉報

8#
ID:997026 發表于 2022-2-14 10:08 | 只看該作者
npn 發表于 2022-2-14 06:26
你可以看下這個框架是怎么實現長按連加的
http://www.zg4o1577.cn/bbs/dpj-214058-1.html

感謝,我研究一下
回復

使用道具 舉報

9#
ID:313048 發表于 2022-2-14 10:14 | 只看該作者
用狀態機不難吧就一個短按狀態和長按狀態,外加一個無按下時的狀態
回復

使用道具 舉報

10#
ID:997026 發表于 2022-2-14 10:19 | 只看該作者
AUG 發表于 2022-2-14 10:14
用狀態機不難吧就一個短按狀態和長按狀態,外加一個無按下時的狀態

我用狀態機試一下,謝謝
回復

使用道具 舉報

11#
ID:161164 發表于 2022-2-14 11:00 | 只看該作者
的確是KEY_PROCESS()的問題
你連基本的C語言函數傳參都沒有弄懂

你這寫法是值傳遞,等于

  1. uint8_t 真實戶口結余 = 1000;

  2. void 手游(uint8_t);
  3. void 顯示(uint8_t);

  4. void 手游(手游戶口結余)
  5. {
  6.         if(有鍵按下)
  7.                 手游戶口結余+1

  8.         顯示(手游戶口結余)
  9. }

  10. void main
  11. {
  12.         while(1)
  13.         {
  14.                 手游(真實戶口結余);
  15.         }
  16. }
復制代碼

只是把"真實戶口結余"的值放進"手游戶口結余"內
然后對"手游戶口結余"+1
手游函數內的操作不會對"真實戶口結余"有任何影響

正確寫法應該是

  1. uint8_t 手游戶口結余 = 1000;

  2. void 手游();
  3. void 顯示(uint8_t);

  4. void 手游()
  5. {
  6.         if(有鍵按下)
  7.                 手游戶口結余+1

  8.         顯示(手游戶口結余)
  9. }

  10. void main
  11. {
  12.         while(1)
  13.         {
  14.                 手游();
  15.         }
  16. }
復制代碼
回復

使用道具 舉報

12#
ID:1005190 發表于 2022-2-14 20:58 | 只看該作者
局部靜態變量static了解一下
回復

使用道具 舉報

13#
ID:997026 發表于 2022-2-14 22:23 | 只看該作者
lkc8210 發表于 2022-2-14 11:00
的確是KEY_PROCESS()的問題
你連基本的C語言函數傳參都沒有弄懂

真的非常感謝你!

你解決了我的問題,我確實犯了這個錯誤,其實這個我是知道的,但有時就是陷入了死胡同。感謝你!我還得多努力,繼續學習!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 色网站入口 | 成人精品系列 | 99热最新| 色综合久久久 | 国产美女福利在线观看 | 夜夜爽夜夜操 | 久久久国产一区二区三区 | 国产99久久久国产精品下药 | 日韩不卡在线 | 午夜免费 | 日韩欧美在线视频 | www.中文字幕av | 国产精品视频一 | 久久人人网 | www.亚洲精品 | 精品久久久一区 | 一区二区三区中文 | 99视频免费 | 中国黄色毛片视频 | 欧美日韩亚洲视频 | 日本xx视频免费观看 | 欧美一区二区三区在线视频 | 亚洲精品免费在线观看 | 国产精品久久久久久中文字 | 亚洲视频免费播放 | 精品亚洲一区二区三区四区五区高 | 久久久久久成人 | 欧美日韩中文国产一区发布 | 亚洲国产精品久久久久婷婷老年 | 天天操伊人 | 天堂中文在线播放 | 草逼网站 | 日韩av看片| 亚洲国产成人精品女人久久久野战 | 国产中文字幕在线观看 | 男人的天堂中文字幕 | 亚洲久在线 | 久久高清免费视频 | 国产成人午夜精品影院游乐网 | 久久久噜噜噜www成人网 | 人人人干|