0

我正在尝试在 Atmel 中编写代码,这样我就可以通过连接到 PINA 的开关控制 atmega32 PORTB 的引脚,它可以工作,但只有一个问题,如果一个开关保持高电平而另一个开关变高,则连接的 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

} }

4

2 回答 2

0

分析你的代码

看这个部分

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已经为假

换句话说,在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; 
    }
}

于 2020-10-23T05:34:19.873 回答
0

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

PORTB = PINA;

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

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

于 2020-10-22T22:53:48.390 回答