PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Programmcode Atmega16



Taddus
23.03.2014, 08:53
Hallo,
ich habe ein Spieler das ich mit dem unterten Programmcode steuere. Einmal ändert sich über eine PWM die Geschwindigkeit meines Spiels,
mittels eines Lichtschrankenpaares soll der aktuelle Spielstand abgefragt werden und daraufhin LED's angesteuert werden.
Es funktioniert alles soweit, ausser das in meiner Interrupt Routine der Controller zwar den PIN auf Low setzt den er soll, den anderen
allerdings nur ganz kurz auf high und danach sofort wieder auf LOW.
Bin ein wenig ratlos woran das liegt, vlt kann mir hierbei jemand weiterhelfen.


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

volatile uint8_t a=0;
volatile uint8_t b=0;
volatile uint8_t c=0;
volatile uint8_t d=0;
volatile uint8_t Eingang;

enum {Spieler_1,Spieler_2,Spieler_3,Spieler_4};

void set_output(void)
{

DDRB = 0x08;
TCCR0 |= (1<<WGM00)|(1<<WGM01) |(1<<COM01)|(1<<CS00);

}

ISR(INT1_vect)
{
if (~PINB & (1<<PB4))
{
Eingang=Spieler_1;
a++;
}
if (~PINB & (1<<PB5))
{
Eingang=Spieler_2;
b++;
}
if (~PINB & (1<<PB6))
{
Eingang=Spieler_3;
c++;
}
if (~PINB & (1<<PB7))
{
Eingang=Spieler_4;
d++;
}
switch (Eingang)
{
case Spieler_1:
switch (a)
{
case 1:
PORTA = (PORTA | (1 << PA4)) & ~(1 << PA0);
break;
case 2:
PORTA &= ~(1<<PA4);
PORTC |= (1<<PC7);
break;
case 3:
PORTC &= (1<<PC7);
break;
default:
break;
}
break;
case Spieler_2:
switch (b)
{
case 1:
PORTA = (PORTA | (1 << PA5)) & ~(1 << PA1);
break;
case 2:
PORTA &= ~(1<<PA5);
PORTC |= (1<<PC6);
break;
case 3:
PORTC &= (1<<PC6);
break;
default:
break;
}
break;
case Spieler_3:
switch (c)
{
case 1:
PORTA = (PORTA | (1 << PA6)) & ~(1 << PA2);
break;
case 2:
PORTA &= ~(1<<PA6);
PORTC |= (1<<PC5);
break;
case 3:
PORTC &= (1<<PC5);
break;
default:
break;
}
break;
case Spieler_4:
switch (d)
{
case 1:
PORTA = (PORTA | (1 << PA7)) & ~(1 << PA3);
break;
case 2:
PORTA &= ~(1<<PA7);
PORTC |= (1<<PC4);
break;
case 3:
PORTC &= (1<<PC4);
break;
default:
break;
}
break;
}
}

int main(void)
{
MCUCR |= (1<<ISC10)|(1<<ISC11);
GICR |= (1<<INT1);
DDRB = 0x00;
DDRA = 0xFF;
DDRC = 0xF0;
PORTA = 0x0F;
PORTC = 0x00;
int max_value=5;
int value = 0;
int max_value_2=5;
int value_2 = 0;
sei ();

while(1)
{
value = (rand()%max_value);

switch (value)
{

case 1: set_output();
OCR0 = 64;
break;

case 2: set_output();
OCR0 = 128;
break;

case 3: set_output();
OCR0 = 192;
break;

case 4: set_output();
OCR0 = 255;
break;

default:
break;

}

value_2 = (rand()%max_value_2);

switch (value_2)
{
case 1:
_delay_ms(1000);
break;

case 2:
_delay_ms(2000);
break;

case 3:
_delay_ms(3000);
break;

case 4:
_delay_ms(4000);
break;

default:
_delay_ms(2500);
break;
}
}
}

Vielen Dank schon mal
Taddus

Taddus
23.03.2014, 16:45
Es handelt sich um den AtMega 16.
An die Eingänge PB4-7 ist jeweils eine Lichtschranke angeschlossen, die auch den externen Interupt ansteuern über ein Logik IC. Heisst also sobald der Interrupt auslöst liegt an einem Eingang low an, der Rest ist high. So soll über die If Abfrage geklärt werden welche Lichtschranke den Interrupt ausgelöst hat.

Hubert.G
24.03.2014, 09:50
Es wird wohl niemand sehr großes Interesse habe sich deinen Programmcode selbst zu dokumentieren um ihn besser zu verstehen.

Taddus
25.03.2014, 07:50
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile uint8_t a=0; // Variablen für den Spielchipstand
volatile uint8_t b=0;
volatile uint8_t c=0;
volatile uint8_t d=0;
volatile uint8_t Eingang; // Variable welche Lichtschranke ausgelöst hat

enum {Spieler_1,Spieler_2,Spieler_3,Spieler_4};

void set_output(void) // Funktion für die PWM
{

DDRB = 0x08; // PB3 auf Ausgang
TCCR0 |= (1<<WGM00)|(1<<WGM01) |(1<<COM01)|(1<<CS00); // Timer Einstellungen

}

ISR(INT1_vect) // Interrupt Routine

if (~PINB & (1<<PB4)) // Abfrage Lichtschranke 1
{
Eingang=Spieler_1;
a++; // Chipstand aktualisieren
}
if (~PINB & (1<<PB5)) // Abfrage Lichtschranke 2
{
Eingang=Spieler_2;
b++; // Chipstand aktualisieren

if (~PINB & (1<<PB6)) // Abfrage Lichtschrane 3
{
Eingang=Spieler_3;
c++; // Chipstand aktualisieren
}
if (~PINB & (1<<PB7)) // Abfrage Lichtschranke 4
{
Eingang=Spieler_4;
d++; // Aktueller Chipstand
}
switch (Eingang)
{
case Spieler_1:
switch (a)
{
case 1: // 1 Spielchip verloren
PORTA = (PORTA | (1 << PA4)) & ~(1 << PA0); // LED gruen aus und LED gelb an
break;
case 2: // 2 Spielchip verloren
PORTA &= ~(1<<PA4); // LED gelb aus
PORTC |= (1<<PC7); // LED rot ein
break;
case 3: // 3 Spielchip
PORTC &= (1<<PC7); // LED rot aus
break;
default:
break;
}
break;
case Spieler_2:
switch (b)
{
case 1: // 1 Spielchip verloren
PORTA = (PORTA | (1 << PA5)) & ~(1 << PA1); // LED gruen aus und LED gelb an
break;
case 2: // 2 Spielchip verloren
PORTA &= ~(1<<PA5); // LED gelb aus
PORTC |= (1<<PC6); // LED rot ein
break;
case 3: // 3 Spielchip verloren
PORTC &= (1<<PC6); // LED rot aus
break;
default:
break;
}
break;
case Spieler_3:
switch (c)
{
case 1: // 1 Spielchip verloren
PORTA = (PORTA | (1 << PA6)) & ~(1 << PA2); // LED gruen aus und LED gelb ein
break;
case 2: // 2 Spielchip verloren
PORTA &= ~(1<<PA6); // LED gelb aus
PORTC |= (1<<PC5); // LED rot ein
break;
case 3: // 3 Spielchip verloren
PORTC &= (1<<PC5); // LED rot aus
break;
default:
break;
}
break;
case Spieler_4:
switch (d)
{
case 1: // 1 Spielchip verloren
PORTA = (PORTA | (1 << PA7)) & ~(1 << PA3); // LED gruen aus und LED gelb ein
break;
case 2: // 2 Spielchip verloren
PORTA &= ~(1<<PA7); // LED gelb aus
PORTC |= (1<<PC4); // LED rot ein
break;
case 3: // 3 Spielchip verloren
PORTC &= (1<<PC4); // LED rot aus
break;
default:
break;
}
break;
}
}

int main(void) // Hauptprogramm
{
MCUCR |= (1<<ISC10)|(1<<ISC11); // Steigende Flanke an INT1 erzeugt Interrupt
GICR |= (1<<INT1); // INT 1 erlaube Interrupt Request
DDRB = 0x00; // PortB auf Eingang
DDRA = 0xFF; // PortA auf Ausgang
DDRC = 0xF0; // PC4-PC7 auf Ausgang
PORTA = 0x0F; // PA0-PA3 auf "high"
PORTC = 0x00; // PortC auf "low"
int max_value=5; // Max. Variable für rand Funktion
int value = 0; // Min. Variable für rand Funktion
int max_value_2=5; // Max. Variable für rand Funktion
int value_2 = 0; // Min. Variable für rand Funktion
sei (); // Globale Interruptfreigabe

while(1) // Hauptschleife
{
value = (rand()%max_value); // Zufallsauswahl für Geschwindigkeit

switch (value)
{

case 1: set_output(); // Geschwindigkeitsstufe 1 (Langsamste)
OCR0 = 64;
break;

case 2: set_output(); // Geschwindigkeitsstufe 2
OCR0 = 128;
break;

case 3: set_output(); // Geschwindigkeitsstufe 3
OCR0 = 192;
break;

case 4: set_output(); // Geschwindigkeitsstufe 4 (Schnellste)
OCR0 = 255;
break;

default:
break;

}

value_2 = (rand()%max_value_2); // Zufallsauswahl für Wartezeit

switch (value_2)
{
case 1: // Wartezeit zum nächsten Wechsel 1 Sekunde
_delay_ms(1000);
break;

case 2: // Wartezeit zum nächsten Wechsel 2 Sekunde
_delay_ms(2000);
break;

case 3:
_delay_ms(3000); // Wartezeit zum nächsten Wechsel 3 Sekunde
break;

case 4:
_delay_ms(4000); // Wartezeit zum nächsten Wechsel 4 Sekunde
break;

default:
_delay_ms(2500); // Wartezeit zum nächsten Wechsel 2,5 Sekunde
break;
}
}
}

askazo
25.03.2014, 08:13
Ich weiß nicht, ob das shcon Dein Fehler ist, aber


case 3: // 3 Spielchip
PORTC &= (1<<PC7); // LED rot aus
break;


muß entsprechend Deiner Dokumentation richtigerweise so aussehen (Tilde!):


case 3: // 3 Spielchip
PORTC &= ~(1<<PC7); // LED rot aus
break;


Diesen Fehler hast Du bei allen Spielern gemacht.

Gruß,
askazo