AVR C:使用按钮

时间:2017-02-20 03:53:57

标签: c avr atmel

我有电路设置,每按一次按钮就会打开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;
}

1 个答案:

答案 0 :(得分: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;
}