AVR C:使用按钮的 8 位计数器

AVR C : 8 Bit Counter using button

我有电路设置,每次按下按钮时都会打开 LED,它从 0 到 255 递增,因此二进制为 0000 0000 到 1111 1111。我的开关配置为 PB2,也就是 D9板.

我遇到了一个问题,正如你从我的coud中看到的那样,我使用了8个引脚,6个来自D寄存器,2个来自B寄存器。当我增加 PORTB 并在某个时候它变成 0b00000100,然后它的值与输入引脚 pb2 相同,所以在我的无限循环中即使我没有按下 PINB 按钮,它也会打开。我尝试将 PORTB 的值重置为 0,但它仍然无法关闭。

我需要一种机制,这样当我递增 PORTB 时它不会影响我的输入引脚 PB2。

非常感谢任何帮助,我尝试发布视频但它太大了。

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

/*
    Board digital I/O pin to atmega328 registers for LEDS
    | d2  | d3  | d4  | d5  | d6  | d7  | d8  | d9  |
    | pd2 | pd3 | pd4 | pd5 | pd6 | pd7 | pb0 | pd1 |

    Input Button
    | d9  |
    | pb2 |


*/


int main(void) {

    int x;

    DDRD = 0b11111100; 
    PORTD = 0b00000000;

    DDRB = 0b00000011; 
    PORTB = 0b00000100;

    while(1) {

        if((PINB & 0b00000100) == 0) {

            if(x < 63) {

                PORTD = PORTD + 0b00000100;
                x++;

            } else if (x == 63) {

                x=0;
                PORTD = 0b00000000;
                PORTB = PORTB + 0b00000001;

                //problem here, when PORTB is incremented to 0b00000100 then the switch turns on automatically
                if((PORTB & 0b00000100) == 0b00000100) {
                    PORTB = 0b00000000;
                    PORTD = 0b00000000;
                }

            } 

            _delay_ms(80);


        }

    }

    return 0;
}

简单的答案是避免使用 PORTB 作为变量。而是使用 x,并适当移动 x 中的值以显示它。

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

/*
Board digital I/O pin to atmega328 registers for LEDS
| d2  | d3  | d4  | d5  | d6  | d7  | d8  | d9  |
| pd2 | pd3 | pd4 | pd5 | pd6 | pd7 | pb0 | pd1 |

Input Button
| d9  |
| pb2 |
*/


int main(void) {

    uint8_t x = 0;

    DDRD = 0b11111100; 
    PORTD = 0b00000000;

    DDRB = 0b00000011; 
    PORTB = 0b00000100;

    while(1) {

        if((PINB & 0b00000100) == 0) {

            ++x;

            PORTD = x << 2;
            PORTB = (PORTB & 0b11111100) | ((x >> 6) & 0b00000011);
        } 

        _delay_ms(80);
    }
    return 0;
}