AVR微控制器记忆游戏

时间:2020-07-06 14:52:29

标签: c microcontroller avr atmel

我正在做一个游戏,您需要重复发光二极管的顺序。该顺序由两个LED设置。要重复该序列,请使用操纵杆。

我有一个想法,制作两个布尔数组,其中True表示左LED,而False表示右LED。第一个数组必须包含一个需要重复的随机序列(真/假)。当我推到操纵杆的一侧或另一侧时,我想分别写入第二个数组,True / False,并一直比较它们。

这是我目前所拥有的。 ( AT90USB647

#define F_CPU 2000000UL
#include <avr/io.h>
#include <stdbool.h>

int main(void) {
    MCUCR |= 0x80;
    MCUCR |= 0x80;
    DDRA = 0xFF;
    PORTF = 0x20;
    
    bool seq2[100];
    
    while(1)
    {
        uint8_t x = PINF;
        if(!(x & 0x20)) {
            PORTA = 0x80;   
        }
        else if(!(x & 0x08)) {
            PORTA = 0x01;
        }
        else {
            PORTA = 0x00;
        }
    }
}


主要问题是按下操纵杆时如何向数组写入True或False?

1 个答案:

答案 0 :(得分:0)

一种基本方法是:


#define F_CPU 2000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile unsigned int counter;

static unsigned char pattern_position;
static unsigned char array_position;

static unsigned char pattern[] = {
    0b01010101,
    0b11010101,
    0b10010101
};

ISR(TIMER0_COMPA_vect)
{
    counter++;
}

int main(void)
{
    MCUCR |= 0x80;
    
    DDRA = 0xFF;
    PORTF = 0x20;
    
    // Timer initialization
    // Mode: CTC
    // Prescaler: 1024
    TCCR0A = (1<<WGM01);
    TCCR0B = (1<<CS02) | (1<<CS00);
    
    // Calculate a correct time
    //
    // we want 1 ms -> f_TIMER0 = 1/T = 1/(1 * 10^-3)s = 1 kHz
    //
    //                f_CPU                  f_CPU                20 MHz
    // f_TIMER0 = ------------- -> OCR0A = ---------------- = ------------- = ~ 20 (It is not exactly 1ms but it is ok) 
    //             k_H * OCR0A              k_H * f_TIMER0     256 * 1 kHz
    //
    OCR0A = 20;
    TIMSK0 = (1<<OCF0A);  // Enable Timer0 Overflow Compare Match interrupt
    
    // Show the sequence that the user should input
    for (unsigned char i=0; i < sizeof(pattern)/sizeof(&pattern[0]); i++)
    {
        for (unsigned char j=0; j < 8; j +=2)
        {
            // There is possible a signal missing to show the user that the next pattern occurs!

            PORTA = ((pattern[i]>>(j+1))<<PINA7) | ((pattern[i]>>j)<<PINA0);
            // That the user can see the patterns a delay is necessary!
            _delay_ms(1000);
        }
    }
    
    // Signalize that the game starts
    for (unsigned char i=0; i <8; i++)
    {
        PORTA ^= 0x81;
        _delay_ms(1000);
    }

    TCNT0 = 0x00;
    sei();
    
    while(1)
    {
        // There is possible a signal missing to trigger next pattern input to the user!!!
        
        if(!(PINF & (1<<PINF5)))
        { 
            PORTA |= 0x80;
        }
        
        if(!(PINF & (1<<PINF3)))
        {
            PORTA |= 0x01;
        }
        
        // Time is 4 seconds to match the correct pattern
        if(counter >= 4000)
        {
            if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & PORTA)))
            {
                // Wrong input end of game
            }
            array_position++;
            
            if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & (PORTA>>8))))
            {
                // Wrong input end of game
            }
            array_position++;
            
            if(array_position >= 8)
            {
                array_position = 0;
                pattern_position++;
            }
            
            if(pattern_position >= (sizeof(pattern)/sizeof(&pattern[0])))
            {
                // End of game reached winning!
            }
            
            counter = 0x00;
            PORTA = 0x00;
            TCNT0 = 0x00;
        }
    }
}

我不确定您是否正在尝试这样做,而且我也无法在目标平台上测试代码,但这也许是解决问题的一种基本方法...