Hallo Zusammen, ich bin noch blutiger Anfänger (vor 3 Tagen begonnen) und komm nun mit den Interrupts nicht weiter. Ohne viele Worte mein kleines Programm: #include <avr/io.h> #include <avr/interrupt.h> unsigned int i; unsigned int f; ISR(INT1_vect) { DDRB=0xFF; while(f<=50000) { PORTB=0x08; f=f+1; } f=0; } int main() { DDRB=0xFF; sei(); while(1) { while(i<=50000) { PORTB=0x04; i=i+1; } i=0; while(i<=50000) { PORTB=0x00; i=i+1; } i=0; } } Was hab ich vergessen oder falsch gemacht? Schon mal Danke für Antworten :) mfg Orange
Hallo, habe vor drei Tagen den Führerschein gemacht und bin noch nicht Formel 1 Fahrer.Was habe ich falsch gemacht???. Lern doch erst mal die einfachsten grundlagen. Es fehlt die hälfte und die hälfte die da ist,ist Müll. gruss andy
@OP Kannst du mal in Worten beschreiben, was das Programm machen soll? das ist nämlich nicht wirklich offensichtlich...
1.) statt
1 | while(i<=50000) |
2 | {
|
3 | PORTB=0x04; |
4 | i=i+1; |
5 | }
|
6 | i=0; |
besser for() loop nehmen:
1 | for(i=0; i <= 50000; i = i +1) |
2 | {
|
3 | PORTB = 0x04; |
4 | }
|
Vorteile: Uebersichtlicher, kompakter, ausserdem wird i vor Benutzung initialisiert ! Bei Deinem Code ist die Dauer der ersten Schleife Zufall, denn i wir nicht initializiert, und kann somit irgend einen Wert haben. 2.) Damit in die Interruptroutine verzweigt wird muss irgend ein "Event" konfiguriert sein (z.B. ein Timer), um dass auszuloesen. Bei diesem Programm nicht vorhanden => die Interrupt-Routine wird nie angesprungen.
harte Worte... ;) Ich bin mir dessen bewusst, dass ich doch sehr wild das ganze anfang. In meinem Techniker hab ich die Zeit alles in Ruhe nachzuarbeiten, doch momentan brauch ich zügig ein Programm und wie ich da hinkomm is mir ehrlich gesagt wurschd. Hauptsache es funktioniert irgendwie Wie würde deiner Ansicht diese Aufgabe zu lösen sein? Dass ich seh wie es richtig sein sollte^^ ATtiny2313 LED am Ausgang soll blinken und wenn ich Taster (INT1) betätige soll eine andere LED kurz angehn und danach der normal Rythmus wieder weiter. Und das ganze über Interrupt halt...
Orange schrieb: > ehrlich gesagt wurschd. Hauptsache es funktioniert irgendwie Das ist genau die richtige Einstellung. Nicht. > ATtiny2313 > LED am Ausgang soll blinken und wenn ich Taster (INT1) betätige soll > eine andere LED kurz angehn und danach der normal Rythmus wieder weiter. Dann must Du noch einschalten dass der INT1 Pin einen Interrupt ausloest. Siehe Datenblatt. BTW: Koennte sein dass das Blinken bei der Laenge (Kuerze !) der Schleifen recht hektisch ist. Besser _delay() verwenden.
@Kai S. Danke für den Tipp, werd ich beherzigen. @Jörg G. hab grad dem Gast Andy geantwortet
Wenns nur blinken soll und Du eh nix lernen willst, sondern nur deinen Lehrer verschaukeln, such Dir was fertiges aus dem Internet. Geht am schnellsten und vergelichsweise hirnlos. Besser auf jeden Fall als der Scheiß den Du dir da ausm Hirn drückst.
Hallo, harte Worte müssen manchmal sein. Schau in das tut hier rein und du müsstest einen Interrupt in ca. 1 Stunde hinkriegen und auch halbwegs verstehen. und wie ich da hinkomm is mir ehrlich gesagt wurschd. Hauptsache es funktioniert irgendwie Das ist schon mal eine sehr löbliche einstellung (kopfschüttel). Hausaufgabe ? gruss andy
Also irwie kommen mir die Antworten der Gäste immer etwas hart vor... :P Naja, das is eig gar nich worauf ich hinaus will...^^ Bitte nicht, ich weiß selber dass das sehr utopisch klingt: Bei meim Kumpel hab isch schon vor längerem richtig geil eine Beleuchtung mit RGB_LEDs eingebaut. Zurzeit wird jeder Farbenstrang einzelnd per Schalter 1/0 gemacht. Nun kommt der Controller ins Spiel. Vorstellung: 2 Inkrementgeber, der eine regelt ein Farbspecktrum, der andere die Helligkeit. und wenn ich nen separaten Taster betätige soll alles sofort weiß sein. ...Nix wildes eig.^^
Orange schrieb: > Also irwie kommen mir die Antworten der Gäste immer etwas hart vor... :P > > Naja, das is eig gar nich worauf ich hinaus will...^^ > Bitte nicht, ich weiß selber dass das sehr utopisch klingt: > > Bei meim Kumpel hab isch schon vor längerem richtig geil eine > Beleuchtung mit RGB_LEDs eingebaut. Zurzeit wird jeder Farbenstrang > einzelnd per Schalter 1/0 gemacht. Nun kommt der Controller ins Spiel. > Vorstellung: > 2 Inkrementgeber, der eine regelt ein Farbspecktrum, der andere die > Helligkeit. und wenn ich nen separaten Taster betätige soll alles sofort > weiß sein. > > ...Nix wildes eig.^^ Im Prinzip nicht. Wenn man weiß wies geht. Aber bis man das weiß, vergeht Zeit. Und daher hilft es auch nichts, wenn man mitten drinn einsteigt und die Grundlagen aussen vor lässt. PS: Dazu brauchst du eigentlich gar keinen Interrupt. Tasterabfragen brauchen so gut wie nie einen Interrupt. Aber da muss der Rest des Programmes dann auch dazu passen. Deine vielen while Schleifen werden dir da zum Stolperstein. Im ganzen Programm gibt es nur 1 einzige Schleife und die ist die Hauptschleife in main(). ALles andere wird zeitlich gestaffelt da drinnen erledigt. Mit jedem Durchlauf durch die Schleife immer nur ein kleines bischen Arbeit machen lassen (zb auf die nächste Farbstufe dimmen)
@Karl Heinz Buchegger Ok, Zusatzinfo: die dimmung der einzelnen Farben plan ich über pwm. wenn das Programm sich tatsächich ohne interrupts realisieren lässt wäre toll, weil dann hab ich Zeit um mich noch mehr mit gepflogenheiten und basics zu beschäftigen.
Man kann eigentlich fast alles ohne Interrupts lösen. Dann kommen z.B. Abfragen der Taste etc. einfach in die Hauptschleife. Mache Dinge sind mit Interrupts, wenn man sie denn verstanden hat, einfacher bzw. eleganter zu lösen.
Kai S. schrieb: > Mache Dinge sind mit Interrupts, wenn man sie denn verstanden hat, > einfacher bzw. eleganter zu lösen. Zustimmung. Nur Taster auf Interrupts zu legen, macht nur in Ausnahmefällen Sinn. Wenn der Taster den µC aus dem Tiefschlaf holen muss beispielsweise. Ansonsten macht das mehr Ärger als ein direkter Einbau in die Hauptschleife. Und einen eventbasierten Programmierstil fördert das ausserdem, was dann wiederrum der Bedienbarkeit zu Gute kommt.
Sieht das schon besser aus? #include <avr/io.h> #include <avr/delay.h> #define z 5 void main(void) { DDRB = (1<<DDB2) | (1<<DDB3); DDRD &= ~(1<<DDD3); while(1) { if(PIND & (1<<PIND3)) { PORTB |= (1<<PORTB3); _delay_ms(z); PORTB &= ~(1<<PORTB3); } else { PORTB |= (1<<PORTB2); _delay_ms(z); PORTB &= ~(1<<PORTB2); _delay_ms(z); } } } schon mal danke für eure Beteiligung und Mühen!
Sieht doch schon gut aus. Drei Hinweise: 1. Fünf Millisekunden... da siehtst du nichts mehr blinken. Das ist einfach nur "etwas dunkler". Bei 100 ms sieht man schon ein deutliches (auf)Blitzen. 2. Etwas AVR-GCC/WinAVR spezifisches ist das _delay_ms(). Schon mal gut, dass du nicht versuchst _delay_ms() mit einer Variablen als Parameter auszuführen. Das ist hier im Forum eines der TOP 3 Themen, dass dann "der Flash Speicher nicht mehr ausreicht" und "die Zeiten nicht stimmen". Das kommt davon, dass in diesem Fall die Fließkomma Bibliothek mit eingebunden wird. Variable verzögerungen packt man darum in do/while oder for Schleifen. 3. Was mich auf 2. gebracht hat: Es existiert in C die Konvention, das man per #define definierte Ausdrücke (blöde Formulierung, ist aber so) in Großbuchstaben schreibt. So sieht man sofort wo man nach der Definition des Ausdruckes zu suchen hat. Also besser "#define Z 5", oder noch besser "#define CONST_DELAY_TIME 5". Dem Compiler selbst ist das zwar völlig egal, aber andere Programmierer die den Code in die Finger bekommen wissen sofort um was es geht.
@ Werner B. Vielen Dank für das Feedback, hab den definierten Ausdruck schon angepasst ;) lg Orange
Jetzt darfst du aber auch noch schnell das Forum zu bedienen lernen. ;-) Code fasst man in [ c ] ... [ /c ] (die Leerzeichen dabei weglassen), dann sieht er besser aus:
1 | #include <avr/io.h> |
2 | #include <avr/delay.h> |
3 | |
4 | #define z 5
|
5 | |
6 | void main(void) |
7 | {
|
8 | DDRB = (1<<DDB2) | (1<<DDB3); |
9 | DDRD &= ~(1<<DDD3); |
10 | while(1) |
11 | {
|
12 | if(PIND & (1<<PIND3)) |
13 | {
|
14 | PORTB |= (1<<PORTB3); |
15 | _delay_ms(z); |
16 | PORTB &= ~(1<<PORTB3); |
17 | }
|
18 | else
|
19 | {
|
20 | PORTB |= (1<<PORTB2); |
21 | _delay_ms(z); |
22 | PORTB &= ~(1<<PORTB2); |
23 | _delay_ms(z); |
24 | }
|
25 | }
|
26 | }
|
p.s.: Über "void main(void)" beklagt sich der Compiler regelmäßig, da es nicht C-Standard-konform ist (vereinfacht gesagt). Schreib besser "int main(void)". Ob du dabei am Ende noch eine (nie erreichte, durch die Endlosschleife davor) Anweisung "return 0;" schreibst oder nicht, ist dem Compiler dann relativ egal.
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.