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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

AVR單片機按鍵消抖程序問題請教

[復制鏈接]
跳轉到指定樓層
樓主
ID:881204 發表于 2021-8-23 17:19 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
大佬們好!我用ATTINY24A做一個按鍵控制IO輸出的功能。
原理圖如下:

目前的問題是:
1、我的按鍵消抖好像沒作用(調不同的DELAY時間,有變化,但不解決問題)
2、在我PA0按鍵按下不松手時(也就是按鍵輸入一直為0)。這個時候,PB1口輸出為0.4V,只有我松開按鍵以后,PB1口才會變為0V或3.3V。
原代碼如下:
#include <avr/io.h>
void delay (unsigned int ms);
int main(void)
{
        unsigned char temp=0;
        while(1)
        {
                temp = (PINA & (_BV(DDA0)));  //KEY
        if (!temp)
        {
                delay(200);
                        if(!temp)
                        {
                         DDRB = 0x0F;
                         PORTB = 0x00;
                        }
        }
                                temp = (PINA & (_BV(DDA0))); //KEY
                                if (!temp)
                                {
                                delay(200);
                                        if(!temp)
                                        {
                                        DDRB = 0x0F;
                                        PORTB = 0x02;
                                        }
                                }
        }
          return 0;
}

void delay (unsigned int ms)
        {
                unsigned int i,j;
                for(i=0;i<ms;i++)
                {
                        for(j=0;j<1000;j++);
                }
        }


請各位大佬幫忙看看是什么問題,謝謝!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:752974 發表于 2021-8-24 08:20 | 只看該作者
按鍵消抖常用的兩種方法,電容濾波,軟件延時。和什么單片機無關。
回復

使用道具 舉報

板凳
ID:881204 發表于 2021-8-25 09:12 | 只看該作者
munuc_w 發表于 2021-8-24 08:20
按鍵消抖常用的兩種方法,電容濾波,軟件延時。和什么單片機無關。

大佬好,是和什么單片機沒關系,我只是想把我遇到的問題情況說的全面一點,并不是說和單片機有關。
我發了原代碼,也就是想請大佬們幫我看看有什么問題。
謝謝指導!
回復

使用道具 舉報

地板
ID:161164 發表于 2021-8-25 09:56 | 只看該作者
不明白你的代碼為什么要這樣寫
根據你的代碼,當按下PA0時
PB1會產生2.5Hz的方波(假設delay的時間是ms)
放開PA0后,PB1就會比較隨機的停在0V或3.3V

如果你想點動PA0來控制PB1
大約可以這樣改(沒用過AVR,看了一下手冊):
  1. int main(void)
  2. {
  3.         unsigned char temp=0;
  4.         DDRB = 0x0F;//輸入輸出設定只要設一次
  5.         while(1)
  6.         {
  7.                 temp = (PINA & (_BV(DDA0)));  //KEY
  8.                 if (!temp)
  9.                 {
  10.                         delay(200);
  11.                         if(!temp)
  12.                         {//方法1
  13.                                 if(PORTB & 0x02)
  14.                                 {
  15.                                         PORTB &= 0xFD;
  16.                                 }else{
  17.                                         PORTB |= 0x02;
  18.                                 }
  19.                                 //方法2
  20.                                 //PORTB ^= 0x02;//異或
  21.                         }
  22.                 }
  23.         }
  24.         return 0;
  25. }
復制代碼





回復

使用道具 舉報

5#
ID:881204 發表于 2021-8-25 11:40 | 只看該作者
本帖最后由 灰小伙 于 2021-8-25 15:52 編輯
lkc8210 發表于 2021-8-25 09:56
不明白你的代碼為什么要這樣寫
根據你的代碼,當按下PA0時
PB1會產生2.5Hz的方波(假設delay的時間是ms)

謝謝大佬指點,我的工作目的是:按一次KEY,PB1輸出高;再按一次KEY,PB1輸出低。并且一直這樣檢測是否有按鍵輸入,如果有的話,PB1的輸出就翻轉,并保持到下一次按鍵輸入。
謝謝!
回復

使用道具 舉報

6#
ID:881204 發表于 2021-8-27 10:17 | 只看該作者
lkc8210 發表于 2021-8-25 09:56
不明白你的代碼為什么要這樣寫
根據你的代碼,當按下PA0時
PB1會產生2.5Hz的方波(假設delay的時間是ms)

謝謝lkc8210大佬的指導,我明白了為什么會產生方波。
只是目前按鍵的靈敏度還是不夠,10次有3-4次按下去沒反應,繼續努力中。
回復

使用道具 舉報

7#
ID:161164 發表于 2021-8-27 10:30 | 只看該作者
灰小伙 發表于 2021-8-27 10:17
謝謝lkc8210大佬的指導,我明白了為什么會產生方波。
只是目前按鍵的靈敏度還是不夠,10次有3-4次按下去 ...

把delay(200);改短一點試試
回復

使用道具 舉報

8#
ID:881204 發表于 2021-8-27 10:41 | 只看該作者
lkc8210 發表于 2021-8-27 10:30
把delay(200);改短一點試試

下面是最新的代碼。
void delay (unsigned int ms);
int main(void)
{
        unsigned char temp=0;
        DDRB = 0x0F;
        PORTB = 0x00;//輸出低
        while(1)
        {
                temp = (PINA & (_BV(DDA0)));  //KEY按下 檢測
        if (!temp)
        {
                delay(20);
                        if(!(PINA & (_BV(DDA0))))
                        {
                        while(!(PINA & (_BV(DDA0))));//KEY釋放 檢測
                        delay(10);
                         DDRB = 0x0F;
                         PORTB = 0x02; //輸出高
                        }
        }
                                temp = (PINA & (_BV(DDA0)));  //_BV是左移一位。
                                if (!temp)
                                {
                                delay(20);
                                        if(!(PINA & (_BV(DDA0))))
                                        {
                                        while(!(PINA & (_BV(DDA0)))); //KEY釋放 檢測
                                        delay(10);
                                        DDRB = 0x0F;
                                        PORTB = 0x00;//輸出低
                                        }
                                }
        }
          return 0;
}

void delay (unsigned int ms)
        {
                unsigned int i,j;
                for(i=0;i<ms;i++)
                {
                        for(j=0;j<1000;j++);
                }
        }
回復

使用道具 舉報

9#
ID:161164 發表于 2021-8-27 11:10 | 只看該作者
灰小伙 發表于 2021-8-27 10:41
下面是最新的代碼。
void delay (unsigned int ms);
int main(void)

???
為什么還是要這樣寫?
雖然加了釋放檢測令PB1不會產生方波
但這種寫法讓PB1 的輸出結果取決于是上半部分代碼先掃到按鍵還是下半部分先掃到
太隨機了
回復

使用道具 舉報

10#
ID:881204 發表于 2021-8-27 11:34 | 只看該作者
lkc8210 發表于 2021-8-27 11:10
???
為什么還是要這樣寫?
雖然加了釋放檢測令PB1不會產生方波

抱歉,可能是我的思路有問題。
我想的是:為了“隨時檢測按鍵輸入值(因為只要開機,用戶可能按無數次按鍵)”
回復

使用道具 舉報

11#
ID:881204 發表于 2021-8-30 09:58 | 只看該作者
換了個思路,情況有所改善,但還是有20%的按鍵不被認識
代碼如下:
int main(void)
{
        unsigned char temp=0;
        unsigned char count = 0;
        unsigned char V6=0;
        DDRB = 0x0F;
        PORTB = 0x00;//初始化,輸出低
        while(1)
        {
                temp = (PINA & (_BV(DDA0)));  //KEY按下 檢測
                delay(10);
             while(!(PINA & (_BV(DDA0))));//KEY釋放 檢測
            delay(10);
                 switch(V6)
                 {
            case 0:
            if(temp==0)
            {
                    V6=1;
                    count++;
                    DDRB = 0x0F;
                    PORTB = 0x02; //輸出高
            }
            else
            {
                    V6=0;
                    count=0;
                    DDRB = 0x0F;
                    PORTB = 0x00; //輸出保持低
            }
            break;
        case 1:
                        if(temp==0)
                        {
                              V6=0;
                               count++;
                               DDRB = 0x0F;
                                PORTB = 0x00; //輸出低
                        }
                        else
                        {
                                V6=1;
                                count=0;
                                DDRB = 0x0F;
                                PORTB = 0x02; //輸出保持高
                        }
                        break;                       
                                        }
                                }
          return 0;
}
回復

使用道具 舉報

12#
ID:161164 發表于 2021-8-30 11:45 | 只看該作者
灰小伙 發表于 2021-8-30 09:58
換了個思路,情況有所改善,但還是有20%的按鍵不被認識
代碼如下:
int main(void)

直接取反不香嗎?
PORTB = PORTB ^ 0x02;
回復

使用道具 舉報

13#
ID:881204 發表于 2021-8-30 12:39 | 只看該作者
lkc8210 發表于 2021-8-30 11:45
直接取反不香嗎?
PORTB = PORTB ^ 0x02;

大佬,你好~
因為我這個按鍵要循環4個狀態,按1次 輸出高。第2次 輸出方波1,第3次輸出方波2,第4次輸出低、
謝謝!
回復

使用道具 舉報

14#
ID:161164 發表于 2021-8-30 13:39 | 只看該作者
灰小伙 發表于 2021-8-30 12:39
大佬,你好~
因為我這個按鍵要循環4個狀態,按1次 輸出高。第2次 輸出方波1,第3次輸出方波2,第4次輸出 ...

方波1和方波2有什么分別?

另外,從你的代碼來看
PINB1 只會按1次 輸出高。第2次 輸出低,如此循環
回復

使用道具 舉報

15#
ID:881204 發表于 2021-8-30 14:05 | 只看該作者
lkc8210 發表于 2021-8-30 13:39
方波1和方波2有什么分別?

另外,從你的代碼來看

占空比不同。
回復

使用道具 舉報

16#
ID:881204 發表于 2021-8-30 14:06 | 只看該作者
lkc8210 發表于 2021-8-30 13:39
方波1和方波2有什么分別?

另外,從你的代碼來看

代碼沒加入。加了以后 程序執行不了。。。
while(1)
        {
                temp = (PINA & (_BV(DDA0)));  //KEY按下 檢測
                delay(2);
             while(!(PINA & (_BV(DDA0))));//KEY釋放 檢測
            delay(2);
                 switch(V6)
                 {
            case 0:
            if((temp==0)&&(V6==0))
            {
                    V6=1;
                                DDRB = 0x0F;
                                PORTB = 0x01; //輸出高
            }
            else
            {
                    V6=0;
                                DDRB = 0x0F;
                                PORTB = 0x00; //輸出保持低
            }
            break;
////////////////////////////////////////////////////////////////////////                       
                        case 1:
                        if((temp==0)&&(V6==1))
                        {
                                V6=2;
                                while (1)//輸出方波
                                {
                                                                DDRB = 0x0F;
                                                                PORTB = 0x00; //輸出低
                                                                delay(10);
                                                                DDRB = 0x0F;
                                                                PORTB = 0x01; //輸出高
                                                                delay(10);       
                                                                if(temp==0)
                                                                break;
                                }
                        }
                        else
                        {
                                V6=1;
                                DDRB = 0x0F;
                                PORTB = 0x01; //輸出保持高
                        }
                        break;
                        ///////////////////////////////////////////////////////////////////////
                        case 2:
                        if((temp==0)&&(V6==2))
                        {
                    V6=0;
                                DDRB = 0x0F;
                                PORTB = 0x00; //輸出低
                        }
                        else
                        {
                                V6=1;
                                DDRB = 0x0F;
                                PORTB = 0x01; //輸出保持高
                        }
                        break;
                                                default:
                                                {
                                                        DDRB = 0x0F;
                                                        PORTB = 0x00; //輸出低
                                                }                       
                                        }                                 
                                }
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区三区久久久久久久久 | 国产乱码精品一区二区三区中文 | 国产高清在线观看 | 日本免费一区二区三区四区 | 免费成人av网站 | 中文字幕亚洲视频 | 国产日韩欧美精品一区二区 | 一区二区视频 | 99精品视频在线 | 黄色片免费 | 日韩精品在线播放 | 国产91精品久久久久久久网曝门 | 黄色成人免费看 | 精品久久av| 亚洲精品一区二区三区中文字幕 | 欧美久久精品 | 国产区视频在线观看 | 可以免费看的毛片 | 久久网国产 | 7799精品视频天天看 | 国产在线观看网站 | 国产专区免费 | 欧美精品网站 | 一区观看 | 亚洲综合国产精品 | 日韩色图在线观看 | 久久精品99久久 | 成人久久18免费网站 | 久草久 | 欧美天堂在线观看 | 欧美日本在线观看 | 超碰97人人人人人蜜桃 | 国产一区二区三区精品久久久 | 久久久久久国产 | 国产高清精品一区二区三区 | 成人精品毛片国产亚洲av十九禁 | 91亚洲免费| 成人福利视频 | av黄色免费 | 天堂素人约啪 | 91原创视频 |