PORTB 的 LED 通过 AVR 中的输入 PINA 进行控制

PORTB's LEDs controlling via input PINA in avr

我正在尝试在 Atmel 中编写代码,以便我可以通过连接的开关控制 atmega32 PORTB 的引脚 对于 PINA,它可以工作,但只有一个问题,如果一个开关保持高电平而另一个开关 变高时,连接(相关)到第二个引脚的 LED 没有改变,我哪里出错了?

#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL                         //Setting the CPU frequency to 1MHz
toggle(void){                               //Creating a toggle function to call it within the main function
    unsigned char input = 0x00;                 //Creating an 8-bit variable so we can save the input port
    int t = 1;                              //Loop variable
    while(PINA != 0x00){
    t = t + 1;
    _delay_ms(1);
    if(t == 100) break;
    }
    while(t != 100){
        if((PINA != 0x00) && (input !=PINA))
        {
            input = PINA;
            PORTB = PORTB^input;
            t = t + 1;
            _delay_ms(1);
        }
        else if(input == PINA)
        {
            t = t + 1;
            _delay_ms(1);
        }
        else if(PINA == 0x00){
            t = t + 1;
            _delay_ms(1);
            input = PINA;
        }
    }
}

int main(void)
{
DDRA = 0x00;                                //Setting PORTA as input
DDRB = 0xFF;                                //Setting PORTB as output
DDRC = 0xFF;                                //Setting PORTC as output
DDRD = 0x02;                                //Setting PORTD.2 as output
PORTB= 0x00;                                //Setting PORTB's output to zero
PORTC= 0x00;                                //Setting PORTC's output to zero
PORTD= 0x02;                                //Setting PORTD.2's output to one
while (1) 
{
PORTD= 0x02;                                //Turning on the PORTD LED
toggle();                                   //Toggling the PORTB's LEDs
PORTD= 0x00;                                //Turning off the PORTD LED
toggle();                                   //Toggling the PORTB's LEDs

} }

当您尝试根据另一个端口输入来控制输出时,您可以简单地执行类似

的操作
PORTB = PINA;

当然,如果您不需要完整的端口,您可以随时屏蔽整个端口中您需要的位。 此外,如果您在两个端口中没有配对相同的引脚编号(即:如果一个端口的引脚 3 控制另一个端口的 pint 6 的行为,则这不是这样做的方法,因为例子) 这样你就可以避免很多丑陋和复杂的逻辑

如果您想继续前进的道路,请尝试从“else if”中删除“else”,它们不是必需的,据我所知,条件是互斥的

分析您的代码

看这一段

while(PINA != 0x00){
    t = t + 1;
    _delay_ms(1);
    if(t == 100) break;
    }
while(t != 100){
    //your algorithm body processed here
}

如果其中一个开关(连接到 PORTA)保持高电平,则第一个 while 循环条件 PINA != 0x00 始终 true 循环仅在 t==100 时结束,然后,当你去第二个while循环它不会激发因为条件t != 100已经是false

换句话说,您的 toggle() 函数将不会处理任何数据,直到您释放所有开关

解决方案

我已经为你想做的做了一个简单的代码

int main(void)
{
    DDRA = 0x00;                                //Setting PORTA as input
    DDRB = 0xFF;                                //Setting PORTB as output
    DDRC = 0xFF;                                //Setting PORTC as output
    DDRD = 0x02;                                //Setting PORTD.2 as output
    PORTB= 0x00;                                //Setting PORTB's output to zero
    PORTC= 0x00;                                //Setting PORTC's output to zero
    PORTD= 0x02;                                //Setting PORTD.2's output to one
    
    unsigned char currentInput=PINA;            
    unsigned char previousInput=PINA;
    unsigned char changedBitsMusk = 0;
    while (1)
    {
        currentInput = PINA; //update current reading
        
        changedBitsMusk = currentInput ^ previousInput; // calculate what is changed from previous reading 
        if (changedBitsMusk)        // if there is change happen
        {
            if (currentInput&changedBitsMusk) // only process the data if change is HIgh (i.e only when button is pressed)
            {
                PORTB^=changedBitsMusk; // toggle the corresponding pins
            }
        }
        previousInput = currentInput; 
    }
}