0tes_Gesetz
27.03.2006, 16:19
Hi.
- ATmega168
- AVR-Studio 4.12 SP1
- AVR-GCC 3.4.5
- AVR-DUDE 1.72 mit GUI 0.2.0
Mit folgendem Code wird Pin13 bei Programm-Start eingeschaltet und bei einem externen Interrupt - INT0 (mit steigender Flanke an Pin32) ausgeschaltet und bleibt dann auch da..
Verhält sich also genau wie erwartet.
/*
* Testprogramm um über Externen Interrupt ein Pin zu ändern...
* - ATmega168
* - AVR-Studio 4.12 SP1
* - AVR-GCC 3.4.5
* - AVR-DUDE 1.72 mit GUI 0.2.0
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
volatile char done = 0;
ISR (INT0_vect) /* Externer Interrupt 0 löst aus.. */
{
PORTB = (0<<PB1); /* Pin 13 ausschalten für Interrupt-Test*/
}
int main (void)
{
if ( done == 0 ) /* "sicherstellen", dass Initialisierung nur 1 MAL stattfindet!!! */
{
/* clk_IO auf 8MHz setzen.. */
CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
CLKPR = (0<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
DDRD = (1<<DDD3)|(0<<DDD2); /* PinD3 als Ausgang */
DDRC = (0<<DDC0); /* PinC0 als Eingang */
DDRB = (1<<DDB3)|(1<<DDB1); /* PinB3 und B1 als Ausgang */
/* INT0 LevelChange, INT1 auf falling Edge scharf machen */
EICRA = (1<<ISC00)|(0<<ISC01)|(0<<ISC10)|(1<<ISC11);
/* INT0 enablen, INT1 disablen - da nicht benötigt */
EIMSK = (0<<INT1)|(1<<INT0);
// PCICR = (1<<PCIE2); /* PinChangeInterrupt 16-23 enabled */
// PCMSK2 = (1<<PCINT18);
PORTB = (1<<PB1); /* Pin 13 anschalten, für Interrupt-Test */
done = 1; /* Initialisierung abhaken */
sei(); /* Interrupts ON */
}
while (1 == 1) { } /* Loop forever */
return (0);
}
Wenn ich nun aber Timer2 (8Bit) in dem Initilisierungsteil auf Fast PWM setze mit einem Compare Wert von 0, dann wird der Pin13 spätestens nach 256 Taktzyklen wieder auf High gesetzt, nachdem INT0 funktioniert hat..
Hat jemand ne Idee, wodurch das verursacht wird?
/*
* Testprogramm um über Externen Interrupt ein Pin zu ändern...
* - ATmega168
* - AVR-Studio 4.12 SP1
* - AVR-GCC 3.4.5
* - AVR-DUDE 1.72 mit GUI 0.2.0
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
volatile char done = 0;
ISR (INT0_vect) /* Externer Interrupt 0 löst aus.. */
{
PORTB = (0<<PB1); /* Pin 13 ausschalten für Interrupt-Test*/
}
int main (void)
{
if ( done == 0 ) /* "sicherstellen", dass Initialisierung nur 1 MAL stattfindet!!! */
{
/* clk_IO auf 8MHz setzen.. */
CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
CLKPR = (0<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
/* Timer2: CompareMatch A/B, FastPWM, Prescaler = 1 */
TCCR2A = (1<<COM2A1)|(0<<COM2A0)|(1<<COM2B1)|(1<<COM2B0)|(1<<WGM21)|(1<<WGM20);
TCCR2B = (0<<FOC2A)|(0<<FOC2B)|(0<<WGM22)|(0<<CS22)|(0<<CS21)|(1<<CS20);
TIMSK2 = (1<<OCIE2A)|(1<<OCIE2B)|(0<<TOIE2); /* Capture Overflow A/B Enablbe */
OCR2A = 0; /* Compare Match Values = 0 */
OCR2B = 0;
DDRD = (1<<DDD3)|(0<<DDD2); /* PinD3 als Ausgang */
DDRC = (0<<DDC0); /* PinC0 als Eingang */
DDRB = (1<<DDB3)|(1<<DDB1); /* PinB3 und B1 als Ausgang */
/* INT0 LevelChange, INT1 auf falling Edge scharf machen */
EICRA = (1<<ISC00)|(0<<ISC01)|(0<<ISC10)|(1<<ISC11);
/* INT0 enablen, INT1 disablen - da nicht benötigt */
EIMSK = (0<<INT1)|(1<<INT0);
// PCICR = (1<<PCIE2); /* PinChangeInterrupt 16-23 enabled */
// PCMSK2 = (1<<PCINT18);
PORTB = (1<<PB1); /* Pin 13 anschalten, für Interrupt-Test */
done = 1; /* Initialisierung abhaken */
sei(); /* Interrupts ON */
}
while (1 == 1) { } /* Loop forever */
return (0);
}
Für mich sieht das immer so aus, als ob der Chip einen Reset erfährt - besonders als ich in AVR-Studio den Code mal getestet hab.. da springt er nachdem der Timer (TCNT2) auf 256 gelaufen ist wieder an den Anfang von main {}.. genau deshalb hab ich ja die if-Abfrage fürs initialisieren eingfügt.. aber sie nutzt nichts.
Hilfe..
Und dann hab ich noch 2 Fragen
- AVRDUDE-Gui betreffend..
Wo muss ich rumstellen, damit der ATmega168 oben links in der Auswahl erscheint und ich ihn nicht immer selber unten in die Commandozeile eintragen muss?
-Worin besteht der Unterschied, wenn ich ein Register mit:
TIMSK2 |= (...
oder mit
TIMSK2 = (...
beschreibe?!
Vielen Dank
0tes_Gesetz
- ATmega168
- AVR-Studio 4.12 SP1
- AVR-GCC 3.4.5
- AVR-DUDE 1.72 mit GUI 0.2.0
Mit folgendem Code wird Pin13 bei Programm-Start eingeschaltet und bei einem externen Interrupt - INT0 (mit steigender Flanke an Pin32) ausgeschaltet und bleibt dann auch da..
Verhält sich also genau wie erwartet.
/*
* Testprogramm um über Externen Interrupt ein Pin zu ändern...
* - ATmega168
* - AVR-Studio 4.12 SP1
* - AVR-GCC 3.4.5
* - AVR-DUDE 1.72 mit GUI 0.2.0
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
volatile char done = 0;
ISR (INT0_vect) /* Externer Interrupt 0 löst aus.. */
{
PORTB = (0<<PB1); /* Pin 13 ausschalten für Interrupt-Test*/
}
int main (void)
{
if ( done == 0 ) /* "sicherstellen", dass Initialisierung nur 1 MAL stattfindet!!! */
{
/* clk_IO auf 8MHz setzen.. */
CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
CLKPR = (0<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
DDRD = (1<<DDD3)|(0<<DDD2); /* PinD3 als Ausgang */
DDRC = (0<<DDC0); /* PinC0 als Eingang */
DDRB = (1<<DDB3)|(1<<DDB1); /* PinB3 und B1 als Ausgang */
/* INT0 LevelChange, INT1 auf falling Edge scharf machen */
EICRA = (1<<ISC00)|(0<<ISC01)|(0<<ISC10)|(1<<ISC11);
/* INT0 enablen, INT1 disablen - da nicht benötigt */
EIMSK = (0<<INT1)|(1<<INT0);
// PCICR = (1<<PCIE2); /* PinChangeInterrupt 16-23 enabled */
// PCMSK2 = (1<<PCINT18);
PORTB = (1<<PB1); /* Pin 13 anschalten, für Interrupt-Test */
done = 1; /* Initialisierung abhaken */
sei(); /* Interrupts ON */
}
while (1 == 1) { } /* Loop forever */
return (0);
}
Wenn ich nun aber Timer2 (8Bit) in dem Initilisierungsteil auf Fast PWM setze mit einem Compare Wert von 0, dann wird der Pin13 spätestens nach 256 Taktzyklen wieder auf High gesetzt, nachdem INT0 funktioniert hat..
Hat jemand ne Idee, wodurch das verursacht wird?
/*
* Testprogramm um über Externen Interrupt ein Pin zu ändern...
* - ATmega168
* - AVR-Studio 4.12 SP1
* - AVR-GCC 3.4.5
* - AVR-DUDE 1.72 mit GUI 0.2.0
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
volatile char done = 0;
ISR (INT0_vect) /* Externer Interrupt 0 löst aus.. */
{
PORTB = (0<<PB1); /* Pin 13 ausschalten für Interrupt-Test*/
}
int main (void)
{
if ( done == 0 ) /* "sicherstellen", dass Initialisierung nur 1 MAL stattfindet!!! */
{
/* clk_IO auf 8MHz setzen.. */
CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
CLKPR = (0<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
/* Timer2: CompareMatch A/B, FastPWM, Prescaler = 1 */
TCCR2A = (1<<COM2A1)|(0<<COM2A0)|(1<<COM2B1)|(1<<COM2B0)|(1<<WGM21)|(1<<WGM20);
TCCR2B = (0<<FOC2A)|(0<<FOC2B)|(0<<WGM22)|(0<<CS22)|(0<<CS21)|(1<<CS20);
TIMSK2 = (1<<OCIE2A)|(1<<OCIE2B)|(0<<TOIE2); /* Capture Overflow A/B Enablbe */
OCR2A = 0; /* Compare Match Values = 0 */
OCR2B = 0;
DDRD = (1<<DDD3)|(0<<DDD2); /* PinD3 als Ausgang */
DDRC = (0<<DDC0); /* PinC0 als Eingang */
DDRB = (1<<DDB3)|(1<<DDB1); /* PinB3 und B1 als Ausgang */
/* INT0 LevelChange, INT1 auf falling Edge scharf machen */
EICRA = (1<<ISC00)|(0<<ISC01)|(0<<ISC10)|(1<<ISC11);
/* INT0 enablen, INT1 disablen - da nicht benötigt */
EIMSK = (0<<INT1)|(1<<INT0);
// PCICR = (1<<PCIE2); /* PinChangeInterrupt 16-23 enabled */
// PCMSK2 = (1<<PCINT18);
PORTB = (1<<PB1); /* Pin 13 anschalten, für Interrupt-Test */
done = 1; /* Initialisierung abhaken */
sei(); /* Interrupts ON */
}
while (1 == 1) { } /* Loop forever */
return (0);
}
Für mich sieht das immer so aus, als ob der Chip einen Reset erfährt - besonders als ich in AVR-Studio den Code mal getestet hab.. da springt er nachdem der Timer (TCNT2) auf 256 gelaufen ist wieder an den Anfang von main {}.. genau deshalb hab ich ja die if-Abfrage fürs initialisieren eingfügt.. aber sie nutzt nichts.
Hilfe..
Und dann hab ich noch 2 Fragen
- AVRDUDE-Gui betreffend..
Wo muss ich rumstellen, damit der ATmega168 oben links in der Auswahl erscheint und ich ihn nicht immer selber unten in die Commandozeile eintragen muss?
-Worin besteht der Unterschied, wenn ich ein Register mit:
TIMSK2 |= (...
oder mit
TIMSK2 = (...
beschreibe?!
Vielen Dank
0tes_Gesetz