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.