我正在学习 avr,我有一个任务:在 led 8x8 矩阵上创建运行点。从上到下和从下到上两种方式。案例 0:没有 LED 工作(启动微控制器后默认) 案例 1:从上到下 案例 2:从下到上 从上到下:
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;
}
}
从下到上:
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;
}
}
这部分对我来说很好。但我需要通过点击按钮来切换它们。(中断方法)。如果我第一次单击按钮,模式切换到案例 1,但在第二次按下按钮后,它不再对我有用。
完整代码
#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。我正在使用 proteus 8. Proteus 项目