Hallo liebe Forenmitglieder, ich habe da einmal eine simple aber trotzdem fuer mich nicht klare Frage: Wenn mein Controller gerade arbeitet, z. B. Daten berechnet oder Schleifen durchlaeuft, und ich Signale ueber einen Eingabeport oder einen UART sende dann bemerkt er die Signale doch nicht? also konkret: Wenn mein Controller beschaeftigt ist und ich in der Zeit z. B. einen Taster druecke der an einen Port angeschlossen ist, merkt er sich das Signal und bearbeitet es wenn er fertig ist oder muss ich das so machen, dass er dauernd immer meine Port abfragen muss waehrend er rechnet? Das ist doch recht aufwendig, wenn ich in mein Programm dauernd Abfrageschleifen einbauen muss wenn er eigentlich rechnet!? Gibt es da Alternativen? Z. B. gibt es einen Port, den man so konfigurieren kann, dass wenn da ein Signal anliegt und er gerade rechnet trotzdem zu einer andern Stelle springt und anschliessend wieder zurueck? Dazu gliech noch eine analoge Frage. Wenn ich Signale zu UART sende muss mein Controller gerade diese abfragen, damit er die Signale empfaengt - sonst laufen sie doch ins leere? Viele Fragen zum gleichen Thema, die vielleicht sonnenklar sind, aber mir leider nicht klar sind. Trotzdem danke fuer jede Antwort, Thomas H.
Hallo Thomas, Du musst deinen UART so programmieren, dass er einen Interrupt auslöst, wenn er ein Zeichen empfangen hat. In der Interrupt-Routine liest Du dieses Zeichen aus dem UART und schreibst es in einen Ringpuffer. Den Ringpuffer kann Dein Controller dann auslesen, wenn er Zeit dazu hat. mfg Jens
Hi, Das gleich gillt für deine Taste, die muss nur einen Int. auslösen, dann haut es hin. Gruß Uwe
Moin Jens, das ist interessant. Ich habe ein ähnliches Problem, es sollen an den UART insgesamt 4 Bytes gesendet werden. Der UART löst einen Interrupt aus und soll nun das erste Byte speichern dann das zweite usw. und nach Empfang der 4 Bytes die Empfangsroutine verlassen. Ich habe damit gestern angefangen und der Stand ist nun folgender: Nach auslösen des Interrupts Sprung nach: in temp2,udr st x+,temp2 reti Der X-Pointer zeigt auf lowbyte $60 und highbyte $00, liegt also beim 4414 im RAM-Bereich. Logischerweise klappt das natürlich nicht. Es ist so, das sich das letzte empfangene Byte in $60 befindet. Die anderen Speicherstellen sind leer ($FF). Mit nur einem Byte klappt es prima....... in guter Hoffnung, Günter
Hallo, ich habe mich heute etwas in der Bibliothek umgesehen und bin zu dem selben Ergebnis gekommen wie ihr. Tortzdem danke fuer euere Bemuehungen. Jetzt muss ich die gelesene Theorie nur noch in die Praxis umsetzten. Ciao, Thomas H.
Hallo Um mehrere Aufgaben quasi parallel laufen zu lassen könnte man auch ein Multitaskinsystem verwenden. Habe vor ca. 10 Jahren mal auf einem 51er solch ein System ausprobiert. Hat gut funktioniert. Aber wenn es sich nur um UART und Tasten handelt bist mit der alleinigen Interruptlösung besser dran.
Hallo Thomas, ich habe heute doch noch die Routine fertig bekommen. Es war so richtig wie ich begonnen habe. Das Problem lag im auslesen. Wenn du dir im Tutorial mal das Kapitel über den UART anschaust, findest du dort ein interruptgesteuerte Empfangsroutine für den 2313. Hier kannst du folgende Änderungen vornehmen: nach .def temp = r16 füge ein: .def kontrolo = r17; Kontrollvariable für empfangene Bytes Die Routine rx_com muss geändert werden in rx_com: in temp,udr st x+,temp ;erstes Byte in $60 speichern, Pointer um 1 erhöhen inc kontrolo ;Bytezähler um 1 hochzählen cpi kontrolo,$80 ;Größe des Pufferspeichers z.B. $80 = 128Byte breq res_count ;Ende Puffer erreicht,wenn ja, Pointer auf Anfang setzen reti ;Ende der Routine, nächstes Byte empfangen res_count: clr kontrolo ;Bytezähler auf 0 setzen ldi r26,$60 ;Pointer auf RAM-Anfang ldi r27,$00 reti ;Ende der Routine, die nächsten 128byte empfangen Jetzt noch in der "Start" Routine vor sei ;Interrupts einschalten" clr kontrolo ; Bytezähler auf 0 ldi r26,$60 ; Adresse Lowbyte RAM ldi r27,$00 ; Adresse Highbyte RAM Der X-Pointer ist jetzt initialisiert und zeigt auf die unterste RAM Adresse. Es stehen jetzt folgende Informationen zur Verfügung: 1. die empfangenen Bytes stehen im RAM 2. die Anzahl der empfangenen Bytes Werden mehr als 128 Bytes empfangen, beginnt der Zyklus wieder bei der untersten RAM-Adresse. Ich benutze einen 4414 /8515 und der erhält für diese Zwecke noch ein externes RAM (64KByte). Probiers mal aus. Gruß, Günter
Hallo auch, die von mir vorgeschlagene Routine ist vermutlich nicht fehlerfrei und soll ja auch nur als Grundlage dienen. Verbesserungen sind daher immer gut und interessieren mich natürlich da mit Sicherheit irgendwo noch ein Gedankenfehler liegt. Es grüßt ein weiterprobierender Günter
Hallo, danke fuer die Mithilfe. Jetzt kann ich einmal in Ruhe die Codes ansehen und versuchen. Ihr habt euch da ja richtig Muehe gegeben. Viele Gruesse, Thomas H.
Hi Günter, Du kannst noch eine Zeile einsparen wenn du kontrolo auf $80 setzt und dann (dec)rementierst dabei wird Z-Flag gesetzt und die Zeile breq res_count ;Ende Puffer erreicht,wenn ja, Pointer auf Anfang setzen haut auch hin. Gruß Uwe
Aber Hallo Uwe, probier ich mal aus. Müsste aber laufen. Danke und Gruß, Günter
Hi, und es geht noch kürzer ISR's und Sub's können ja im Prog. auch oben stehen (nach den INT-Sprüngen) .def temp = r16 füge ein: .def kontrolo = r17; Kontrollvariable für empfangene Bytes Die Routine rx_com muss geändert werden in rx_com: in temp,udr st x+,temp ;erstes Byte in $60 speichern, Pointer um 1 erhöhen dec kontrolo ;Bytezähler um 1 runterzählen brne ende rcall res_count ;Ende Puffer erreicht, Pointer auf Anfang setzen ende:reti ;Ende der Routine, nächstes Byte empfangen res_count: ldi kontrolo,$80 ;Bytezähler auf$80 setzen ldi r26,$60 ;Pointer auf RAM-Anfang ldi r27,$00 ret ;Ende der Routine, die nächsten 128byte empfangen Jetzt noch in der "Start" Routine vor sei ;Interrupts einschalten" ;clr kontrolo ; Bytezähler auf 0 ;ldi r26,$60 ; Adresse Lowbyte RAM ;ldi r27,$00 ; Adresse Highbyte RAM ersetzt durch rcall res_count Der X-Pointer ist jetzt initialisiert und zeigt auf die unterste RAM Adresse. Gruß Uwe
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.