soweit ich weiss bei ATMEGA 16 in PD2" ist so eingebaut, wenn der Mikrocontroller eine Flanke(Positiv oder negativ) in PD2 bekommt, löst er eine Interrupt, leider in meinem Code Funktionniert das nicht.. ich bitte um Hilfe -> Hier ist mein Code ISR(INT0_vect) { _delay_ms(10000); PINA = ~ PINA; } int main(void) { cli(); DDRD = 0x00; // use all pins on port D for input DDRB = 0xff; // use all pins on PortB for output PORTB = 0x00; int i = 0; while (1) { for (i = 0; i < 256; i++) { i = i << 1; _delay_ms(10000); PINB = i; PINA = ~ PINA; } } sei(); }
moin, du gibst die interrupts erst nach der while-schleife frei, so wie ich das sehe wird die nur nie beendet. 2. punkt zur interrupt routine selbst schau dir mal ganz dringend das tutoriel an: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Anforderungen_an_Interrupt-Routinen wenn ich mich recht entsinne kannst du dir das cli am anfang auch sparen, da bei programmstart alle interrupts aus sind. hatte damit gestern eine lange nacht, weil ich vergass die alle interrupts mit sli zu aktivieren. mfg Emperor_L0ser
> _delay_ms(10000);
...und das funktioniert überhaupt nicht (bzw. nur bei CPU-Takten unter
26 kHz). Schau Dir mal die Dokumentation der _delay_XX-Funktionen in der
libc-Doku an. Da steht, wieviel maximal geht (ist vom CPU-Takt
abhängig).
> PINB = i; > PINA = ~ PINA; Und das macht beim ATMega16 keinen Sinn, weil PINA und PINB Read-Only-Register sind.
> PINB = i;
...Und außerdem machst Du die Schiebeoperationen in einem int. Die
Portregister sind aber nur 8 Bit breit, wodurch bei der Zuweisung von i
die vorderen 8 Bit von i weggeschmissen werden (selbst wenn Du anstatt
PINB PORTB nimmst).
...Und außerdem musst Du den Interrupt auch freigeben (kleiner Tip: Es gibt ein Bit im Register GICR, dem Du etwas Aufmerksamkeit schenken solltest. Zusätzlich muss eigentlich noch die Flanke, auf die der Interrupt reagieren soll, eingestellt werden). Also, AVR-GCC-Tutorial lesen, v.a. den Abschnitt über (externe) Interrupts. Und vielleicht mal einen Blick ins Datenblatt werfen. Und in die Doku vom Compiler bzw. der Bibliothek...
Und, wenn ich das richtig rate, dann hast du am Port A deinen Mess-Ausgang. Da waere es vernünftig, diese Port dann aber auch tatsächlich als Ausgang zu konfigurieren.
> for (i = 0; i < 256; i++) > { > i = i << 1; Das macht auch nicht viel Sinn. Das "i++" und das "i = i << 1" beeinflussen beide die selbe Variable. Da kommt vermutlich nicht das raus, was Du willst.
Eigentlich ist es ganz einfach die externen Interrupts zu verwenden. Man muss nur die Interruptquelle einschalten und das Event einstellen (also pegelwechsel,low...) und Interrupts allgemein aktivieren (sei()) Hier ein vollständiges Programm, getestet mit atmega8, dürfte aber ähnlich beim 16er gehen.
1 | // Externe Interrupts
|
2 | |
3 | #include <avr/io.h> |
4 | #include <avr/interrupt.h> |
5 | #include <stdint.h> |
6 | |
7 | ISR(INT0_vect) |
8 | {
|
9 | PORTB = ~PORTB; |
10 | }
|
11 | |
12 | |
13 | int main() |
14 | {
|
15 | DDRD = 0x00; // PortD inupt; |
16 | PORTD = 0xff; // interne Pullups aktivieren |
17 | |
18 | DDRB=0xff; // PortB ausgang; |
19 | |
20 | MCUCR |= (1<<ISC00) & ~(1<<ISC01); // Interrupt0 , logical change (an pd2) |
21 | GICR |= 1<<INT0; // ext. Interrupt0 aktivieren |
22 | sei(); // Interrupts allgemein freischalten |
23 | |
24 | while(1); |
25 | |
26 | return 0; |
27 | }
|
Hallo zusammen; kann man überhaupt eine Interrupt mit Winavr simulieren
Interrupts lassen sich natürlich gut mit dem avrstudio simulieren. Den ADC kann man leider nicht so gut simulieren, oder wisst ihr wie das geht? Auch zyklisch kann man nicht so gut debuggen. Wenn ich das mache aktualisiert sich die Register und I/O Ansicht nicht. Erst wenn ich den Stop-Button drücke. Das ist bei Keil besser.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.