简体   繁体   中英

atmega32 8x8 led matrix control

Im learning avr and I have a task: Create running point on led 8x8 matrix. in two ways from top do bottom and from bottom to top. case 0: no leds working (default after launching microcontroller) case 1: top to bottom case 2: bottom to top From top to bottom:

for(int a=0;a<20;a++)
    {
        for (int i=0;i<8;i++)
        {
            PORTC = ~PORT[i];
            for (int i=0;i<8;i++)
            {
                PORTA = (1<<i);
                _delay_ms(200);
            }
            PORTC = PORT[i];

            PORTC = ~PORT[i+1];
            for (int i=7;i>=0;i--)
            {
                PORTA = (1<<i);
                _delay_ms(200);
            }
            i=i+1;
        }
    }

and from bottom to top:

for(int a=0;a<20;a++)
    {
        for (int i=7;i>=0;i--)
        {
            PORTC = ~PORT[i];
            for (int c=7;c>=0;c--)
            {
                PORTA = (1<<c);
                _delay_ms(200);
            }
            PORTC = PORT[i];

            PORTC = ~PORT[i-1];
            for (int c=0;c<8;c++)
            {
                PORTA = (1<<c);
                _delay_ms(200);
            }
            i=i-1;
        }
    }

this part working fine for me. but I need button to switch them by click. (interrupt method). If I click on button for first time, mode switches to case 1, but after pressing button for the second time, it doesn't work for me anymore.

complete code

#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 16000000UL
volatile int state = 0;
volatile int status = 0;
char PORT[8] = {1,2,4,8,16,32,64,128};
int i;

ISR(INT0_vect)
{
    //_delay_ms(200);
    if(status==0)
    {
        state=1;
    }
    else if(status==1) 
    {
        state=2;
    }
    else if(status==2)
    {
        state=1;
    }
}

void init()
{
    DDRA = 0xFF; //PORTA as output
    DDRC = 0xFF; //PORTC as output
    DDRD=0;         /* PORTD as input */
    PORTD=0xFF;
     GICR |= (1<<INT0);
     MCUCR |= (1<<ISC01)|(1<<ISC00);
}

void zigzaglab()
{
    for(int a=0;a<20;a++)
    {
        for (int i=0;i<8;i++)
        {
            PORTC = ~PORT[i];
            for (int i=0;i<8;i++)
            {
                PORTA = (1<<i);
                _delay_ms(200);
            }
            PORTC = PORT[i];

            PORTC = ~PORT[i+1];
            for (int i=7;i>=0;i--)
            {
                PORTA = (1<<i);
                _delay_ms(200);
            }
            i=i+1;
        }
    }
}

void zigzagkreis()
{
    for(int a=0;a<20;a++)
    {
        for (int i=7;i>=0;i--)
        {
            PORTC = ~PORT[i];
            for (int c=7;c>=0;c--)
            {
                PORTA = (1<<c);
                _delay_ms(200);
            }
            PORTC = PORT[i];

            PORTC = ~PORT[i-1];
            for (int c=0;c<8;c++)
            {
                PORTA = (1<<c);
                _delay_ms(200);
            }
            i=i-1;
        }
    }
}

int main(void)
{
    init();
    sei();

    while(1)
    {
        switch(state){
            case 0:
                status=0;
                PORTC = 0;
                PORTA = 0;
                break;
            case 1:
                status=1;
                zigzaglab();
                break;
            case 2:
                status=1;
                zigzagkreis();
                break;
        }
    }
}

PS. Im working with proteus 8. Proteus project

Tried to understand what you are trying to do. Converted your solution to this:

#define F_CPU 16000000UL

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

volatile int status = 0;

ISR(INT0_vect)
{
    // !!!! NEVER PUT A DELAY IN AN INTERRUPT
    //_delay_ms(200);
    
    // If you are using a push-button the interrupt will be called more than one time cause of bouncing
    
    status++;
    
    if(status > 2)
        status = 0;
}

void init()
{
    DDRA = 0xFF;    //PORTA as output
    DDRC = 0xFF;    //PORTC as output
    DDRD = 0x00;    // Not necessary (all ports are setup to input on startup!)
    PORTD = 0xFF;   // Enable pullup resistors on PORTD
    
    // Enable interrupt 0
    GICR |= (1<<INT0);
    MCUCR |= (1<<ISC01)|(1<<ISC00);
    
    // Enable interrupts globally
    sei();
}

void matrix_forward()
{
    // Possible a better solution
    // 8*8 Matrix display can be ordered like a coordinate system (x/y)
    for (unsigned char i=0; i < 20; i++)
    {
        for(unsigned char x=0; x < 8; x += 2)
        {
            // Down
            PORTC = ~(1<<x);
            
            for (unsigned char y=0; y < 8; y++)
            {
                PORTA = (1<<y);
                _delay_ms(200);
            }
            
            PORTC = (1<<x);
            
            // Up
            PORTC = ~(1<<(x + 1));
            
            for (unsigned char y=0; y < 8; y++)
            {
                PORTA = (1<<y);
                _delay_ms(200);
            }
            
            PORTC = (1<<(x + 1));
        }
    }
}

void matrix_reverse()
{
    // Possible a better solution
    // 8*8 Matrix display can be ordered like a coordinate system (x/y)
    for (unsigned char i=0; i < 20; i++)
    {
        for(unsigned char x=0; x < 8; x += 2)
        {
            // Down
            PORTC = ~(1<<(7 - x));
            
            for (unsigned char y=0; y < 8; y++)
            {
                PORTA = (1<<(7 - y));
                _delay_ms(200);
            }
            
            PORTC = (1<<(7 - x));
            
            // Up
            PORTC = ~(1<<(6 - x));
            
            for (unsigned char y=0; y < 8; y++)
            {
                PORTA = (1<<(6 - y));
                _delay_ms(200);
            }
            
            PORTC = (1<<(6 - x));
        }
    }
}

int main(void)
{
    init();

    while(1)
    {
        switch(status){
            case 0:
                PORTC = 0x00;   // for PORTs, PINs, DDRs use HEX or BINARY notation
                PORTA = 0x00;   // cause of better readiness
                break;
            case 1:
                matrix_forward();
                break;
            case 2:
                matrix_reverse();
                break;
        }
    }
}

It is not possible to check the code, but maybe you can extract some code for your solution!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM