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

標(biāo)題: AVR單片機按鍵消抖程序問題請教 [打印本頁]

作者: 灰小伙    時間: 2021-8-23 17:19
標(biāo)題: AVR單片機按鍵消抖程序問題請教
大佬們好!我用ATTINY24A做一個按鍵控制IO輸出的功能。
原理圖如下:

目前的問題是:
1、我的按鍵消抖好像沒作用(調(diào)不同的DELAY時間,有變化,但不解決問題)
2、在我PA0按鍵按下不松手時(也就是按鍵輸入一直為0)。這個時候,PB1口輸出為0.4V,只有我松開按鍵以后,PB1口才會變?yōu)?V或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++);
                }
        }


請各位大佬幫忙看看是什么問題,謝謝!

作者: munuc_w    時間: 2021-8-24 08:20
按鍵消抖常用的兩種方法,電容濾波,軟件延時。和什么單片機無關(guān)。
作者: 灰小伙    時間: 2021-8-25 09:12
munuc_w 發(fā)表于 2021-8-24 08:20
按鍵消抖常用的兩種方法,電容濾波,軟件延時。和什么單片機無關(guān)。

大佬好,是和什么單片機沒關(guān)系,我只是想把我遇到的問題情況說的全面一點,并不是說和單片機有關(guān)。
我發(fā)了原代碼,也就是想請大佬們幫我看看有什么問題。
謝謝指導(dǎo)!
作者: lkc8210    時間: 2021-8-25 09:56
不明白你的代碼為什么要這樣寫
根據(jù)你的代碼,當(dāng)按下PA0時
PB1會產(chǎn)生2.5Hz的方波(假設(shè)delay的時間是ms)
放開PA0后,PB1就會比較隨機的停在0V或3.3V

如果你想點動PA0來控制PB1
大約可以這樣改(沒用過AVR,看了一下手冊):
  1. int main(void)
  2. {
  3.         unsigned char temp=0;
  4.         DDRB = 0x0F;//輸入輸出設(shè)定只要設(shè)一次
  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. }
復(fù)制代碼






作者: 灰小伙    時間: 2021-8-25 11:40
本帖最后由 灰小伙 于 2021-8-25 15:52 編輯
lkc8210 發(fā)表于 2021-8-25 09:56
不明白你的代碼為什么要這樣寫
根據(jù)你的代碼,當(dāng)按下PA0時
PB1會產(chǎn)生2.5Hz的方波(假設(shè)delay的時間是ms)

謝謝大佬指點,我的工作目的是:按一次KEY,PB1輸出高;再按一次KEY,PB1輸出低。并且一直這樣檢測是否有按鍵輸入,如果有的話,PB1的輸出就翻轉(zhuǎn),并保持到下一次按鍵輸入。
謝謝!
作者: 灰小伙    時間: 2021-8-27 10:17
lkc8210 發(fā)表于 2021-8-25 09:56
不明白你的代碼為什么要這樣寫
根據(jù)你的代碼,當(dāng)按下PA0時
PB1會產(chǎn)生2.5Hz的方波(假設(shè)delay的時間是ms)

謝謝lkc8210大佬的指導(dǎo),我明白了為什么會產(chǎn)生方波。
只是目前按鍵的靈敏度還是不夠,10次有3-4次按下去沒反應(yīng),繼續(xù)努力中。
作者: lkc8210    時間: 2021-8-27 10:30
灰小伙 發(fā)表于 2021-8-27 10:17
謝謝lkc8210大佬的指導(dǎo),我明白了為什么會產(chǎn)生方波。
只是目前按鍵的靈敏度還是不夠,10次有3-4次按下去 ...

把delay(200);改短一點試試
作者: 灰小伙    時間: 2021-8-27 10:41
lkc8210 發(fā)表于 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++);
                }
        }
作者: lkc8210    時間: 2021-8-27 11:10
灰小伙 發(fā)表于 2021-8-27 10:41
下面是最新的代碼。
void delay (unsigned int ms);
int main(void)

???
為什么還是要這樣寫?
雖然加了釋放檢測令PB1不會產(chǎn)生方波
但這種寫法讓PB1 的輸出結(jié)果取決于是上半部分代碼先掃到按鍵還是下半部分先掃到
太隨機了
作者: 灰小伙    時間: 2021-8-27 11:34
lkc8210 發(fā)表于 2021-8-27 11:10
???
為什么還是要這樣寫?
雖然加了釋放檢測令PB1不會產(chǎn)生方波

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

作者: 灰小伙    時間: 2021-8-30 09:58
換了個思路,情況有所改善,但還是有20%的按鍵不被認(rèn)識
代碼如下:
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;
}
作者: lkc8210    時間: 2021-8-30 11:45
灰小伙 發(fā)表于 2021-8-30 09:58
換了個思路,情況有所改善,但還是有20%的按鍵不被認(rèn)識
代碼如下:
int main(void)

直接取反不香嗎?
PORTB = PORTB ^ 0x02;
作者: 灰小伙    時間: 2021-8-30 12:39
lkc8210 發(fā)表于 2021-8-30 11:45
直接取反不香嗎?
PORTB = PORTB ^ 0x02;

大佬,你好~
因為我這個按鍵要循環(huán)4個狀態(tài),按1次 輸出高。第2次 輸出方波1,第3次輸出方波2,第4次輸出低、
謝謝!
作者: lkc8210    時間: 2021-8-30 13:39
灰小伙 發(fā)表于 2021-8-30 12:39
大佬,你好~
因為我這個按鍵要循環(huán)4個狀態(tài),按1次 輸出高。第2次 輸出方波1,第3次輸出方波2,第4次輸出 ...

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

另外,從你的代碼來看
PINB1 只會按1次 輸出高。第2次 輸出低,如此循環(huán)
作者: 灰小伙    時間: 2021-8-30 14:05
lkc8210 發(fā)表于 2021-8-30 13:39
方波1和方波2有什么分別?

另外,從你的代碼來看

占空比不同。
作者: 灰小伙    時間: 2021-8-30 14:06
lkc8210 發(fā)表于 2021-8-30 13:39
方波1和方波2有什么分別?

另外,從你的代碼來看

代碼沒加入。加了以后 程序執(zhí)行不了。。。
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; //輸出低
                                                }                       
                                        }                                 
                                }




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 亚洲欧美在线视频 | 国产9 9在线 | 中文 | 99久久久国产精品 | 国产精品毛片无码 | 免费黄色a级毛片 | 视频在线一区二区 | 国产精品色综合 | 国产高清在线精品一区二区三区 | 亚洲精品国产a久久久久久 午夜影院网站 | 亚洲美乳中文字幕 | 涩涩视频在线看 | 狠狠干美女 | 久久亚洲高清 | 一级日韩 | 国产特级毛片aaaaaa喷潮 | 午夜影院在线播放 | 色天天综合 | 久久综合一区 | 不卡一区二区在线观看 | 国产成人精品一区二区 | 人人人人人爽 | 一区二区三区国产视频 | 日本手机在线 | 国产一区日韩在线 | 日韩欧美一级 | 欧美一级大片免费观看 | 天天干夜夜操 | 亚洲精品乱 | 福利在线观看 | 99久久精品免费视频 | 伊人久久综合 | 亚洲一二三区在线观看 | 国产精品久久久久久久久久久久 | 色天天综合 | a级在线观看 | 久久久成人精品 | 91精品国产91 | 亚洲视频在线观看一区二区三区 | 欧美一级片在线观看 | 欧美2区| 色橹橹欧美在线观看视频高清 |