mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Daten empfangen/Eingaben während Mikrocontroller arbeitet


Autor: Thomas H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jens Gerdes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Das gleich gillt für deine Taste, die muss nur einen Int. auslösen, dann 
haut es hin.
Gruß Uwe

Autor: Günter König (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Meiserl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Günter König (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Günter König (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Günter König (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber Hallo Uwe,

probier ich mal aus. Müsste aber laufen.

Danke und Gruß,

Günter

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.