Forum: Mikrocontroller und Digitale Elektronik Terminal schreiben nur bei "Input"


von DEL (Gast)


Lesenswert?

Hallo,

wenn ich ein Programm auf meinen Atmega8 übertrage, welches in der 
Haupt-Do-Loop-Schleife mit
1
 Input Empfangen
 auf hereinkommende Daten wartet, kann ich im Bascom-Terminal problemlos 
Daten eintragen und durch Enter absenden.

Sobald ich versuche per Interrupt auf die Daten zu warten, kann ich 
nichts mehr in die Konsole eintragen.

Ist das Zufall ? Wie kann ich trotz Interrupt Daten absenden ?


Grüße DEL

von Hannes L. (hannes)


Lesenswert?

DEL schrieb:
> per Interrupt auf die Daten zu warten,

Das ist ein Widerspruch. Ein Interrupt hat nichts mit warten zu tun. Und 
ein Programm sollte man so schreiben, dass es nirgendwo "warten" muss.

Um mehr dazu sagen zu können müsste man Dein Programm sehen.

...

von DEL (Gast)


Lesenswert?

Hannes Lux schrieb:
> Das ist ein Widerspruch.

Das "Warten" war auch weniger im technischen Sinne gemeint; Das Programm 
wartet natürlich beim Interrupt nicht, hast du Recht ;)

Der Test-Code:
1
$regfile = "M8def.dat"
2
$hwstack = 100
3
$swstack = 100
4
$framesize = 100
5
$baud = 9600
6
$crystal = 3686400
7
8
9
Config Portd = Output
10
11
Portd.2 = 0
12
13
14
Config Com1 = 9600 , Parity = None , Stopbits = 1 , Databits = 8
15
16
17
Dim Empfangen As String * 20
18
19
Input Empfangen
20
21
22
   Portd.2 = 1
23
24
End


Lade ich das Programm nun auf meinen Atmega8, kann ich den 
Bascom-AVR-Terminal öffnen, und etwas hineinschreiben. Sende ich dies 
nun durch Drücken von Enter ab, empfängt dies der µC, das Programm läuft 
weiter, die LED an PortD.2 geht an.
Wenn ich nun wieder etwas eingeben will, passiert gar nichts. Ich kann 
nichts schreiben.

Starte ich das Programm auf dem µC neu (LED aus), kann ich wieder etwas 
schreiben. Ziehe ich nun den USB-Stecker (gleichzeitig Stromversorgung), 
kann ich nichts mehr eintragen.


"Prüft" der Terminal ob auf der anderen Seite "jemand wartet", oder wie 
habe ich mir das vorzustellen ?

Gruß

DEL

von kein Bascom-Kenner (Gast)


Lesenswert?

DEL schrieb:
> Portd.2 = 1
>
> End

Was macht das Programm wohl nach dem End? Müßte das nicht in irgendeiner 
Form von Schleife laufen?

von der grübelnde (Gast)


Lesenswert?

...hmmm,programmiere zwar nicht in bascom, aber wo wird hier der 
interrupt initialisiert

von Karl H. (kbuchegg)


Lesenswert?

DEL schrieb:

Warum du nur einmal eingeben kannst wurde ja schon beantwortet:
Weil du das genau so programmiert hast. Geh dein Programm von oben noch 
unten durch, so wie ein Computer das abarbeiten würde. Du kommst nur 
einmal am INPUT vorbei und damit kannst du auch nur 1 Eingabe machen.

> "Prüft" der Terminal ob auf der anderen Seite "jemand wartet", oder wie
> habe ich mir das vorzustellen ?

Das funktioniert ganz einfach.
Das Terminal schreibt nicht von sich aus den jeweiligen Buchstaben hin, 
wenn du eine Taste drückst.
Sondern:
* Du drückst eine Taste
* Der zugehörige Buchstabe wird über die RS232/USB Verindung zum µC
  geschickt, der die Zeichen sammelt. Aber:
* Der µC schickt dasselbe Zeichen über die Rückverbindung gleich wieder
  zum Terminal zurück
* welche dann das empfangene Zeichen anzeigt.

D.h. Das Terminal macht Folgendes:
* ein Tastendruck bewirkt, dass ein entsprechender Code verschickt wird
* ein eingehendes Zeichen wird angezeigt.

Hängt da jetzt am anderen Ende der Leitung der µC, der seinerseits alle 
eingehenden Zeichen zurückschickt, dann sieht das für dich so aus, dass 
du eine Taste drückst und mehr oder weniger unmittelbar auf diesen 
Tastendruck das entsprechende Zeichen auf deinem Terminal erscheint. Ist 
der µC aber nicht da, bzw ausgeschaltet, dann gibt es auch niemanden, 
der das Zeichen zurückschickt (man spricht vom "Echo") und damit kannst 
du auf deiner Tastatur klimpern bis du schwarz wirst, du siehst keine 
Anzeige.

von DEL (Gast)


Lesenswert?

Vielen Dank, dass das Echo dafür Verantwortlich ist, dass ich etwas 
sehe, macht Sinn.

Nun bleibt die Frage nach dem Interrupt. Mein Code:
1
$regfile = "M8def.dat"
2
$hwstack = 100
3
$swstack = 100
4
$framesize = 100
5
$baud = 9600
6
$crystal = 3686400
7
8
Declare Sub Serial0charmatch()
9
10
11
Config Serialin = Buffered , Size = 30 , Bytematch = 13
12
Enable Interrupts
13
14
Config Com1 = 9600 , Parity = None , Stopbits = 1 , Databits = 8
15
16
17
Config Portb = Output
18
19
Portb.2 = 0
20
21
22
Do
23
NOP
24
Loop
25
26
27
Sub Serial0charmatch()
28
29
Local Incoming_data As String * 30
30
Input Incoming_data Noecho
31
Print Incoming_data
32
33
Portb.2 = 1
34
35
End Sub
36
End

Wenn ich etwas in den Terminal schreibe sehe ich nichts. -> Vermutlich, 
da "Noecho".
Sende ich dies nun durch Enter ab, geht meine LED an PortB.2 nicht an. 
Genauso wenig, wenn ich etwas per "Send ASCII Character" über die 
serielle Schnittstelle versende.

Setze ich das "Noecho" als Kommentar, sehe ich ebenfalls nichts in der 
Konsole.

Dass ich incoming_data nicht auswerte, ist mir bewusst, aber trotzdem 
sollte doch, wenn etwas beim µC ankommt, der Sub aufgerufen werden. 
Warum sehe ich trotz " 'Noecho (Kommentar)" nichts in der Konsole und 
warum geht meine LED nicht an ?


Viele Grüße

DEL

von DEL (Gast)


Lesenswert?

Hat vllt. jemand einen Tipp zu dem Thema "Interrupt" ?


Viele Grüße

DEL

von Hannes L. (hannes)


Angehängte Dateien:

Lesenswert?

DEL schrieb:
> Hat vllt. jemand einen Tipp zu dem Thema "Interrupt" ?

Also ich werkele nur ganz selten in Bascom, kenne es aber so, dass man 
dem Programm Interrupt-Aufrufe mitteilen muss. Das sieht z.B. so aus:
1
'####################################### Interrupt-Vektoren ###################
2
3
On Urxc Onrxd                           'UART-Empfangs-Interrupt
4
On Oc1a Zeittakt                        'Timer-Compare1A-Interrupt

Dazu gehört dann in der Init noch:
1
Enable Oc1a                             'Timer1-CompareA-Interrupt freigeben
2
Enable Urxc                             'UART-RXC-Interrupt freigeben
3
Enable Interrupts                       'Interrupts global freigeben

Deine Art, mit UART zu arbeiten, mag ja vielleicht ok sein, ich 
bevorzuge es aber etwas hardwarenäher, um Wartezeiten zu vermeiden. In 
der ISR des Interrupts, der vom Empfang eines Zeichens ausgelöst wird, 
wird nur dieses Zeichen "eingesammelt" und in einen Buffer gelegt.
1
Onrxd:                                  'ISR, UART-Byte eingetroffen
2
  Incr Rix                              'Schreibposition im Array erhöhen
3
  Rx_buf(rix) = Udr                     'Empfangsbyte in Buffer legen
4
Return                                  'fertig, zurück...

Die Mainloop prüft dann (in meinem Fall) die Anzahl der Zeichen im 
Buffer und reagiert erst darauf, wenn alle erwarteten Zeichen 
eingesammelt wurden:
1
Do                                      'Hauptschleife
2
  If Rix > 9 Then Neutelegramm          'neues Telegramm eingetroffen? - ja...
3
  ... weitere Aufgaben der Mainloop...
4
Loop

Genausogut könnte die Mainloop aber auch prüfen, ob das zuletzt 
empfangene Zeichen ein "Steuerzeichen" (CR, also 13, Zeilenende-Kennung) 
war.

Ich hänge Dir mal das Programm an, aus dem diese Schnipsel stammen, 
damit Du den Zusammenhang erkennen kannst, den ich meine. Und nein, es 
ist nicht "der Stein der Weisen", ich bin sicher, dass man viele Stellen 
eleganter programmieren könnte. Aber Bascom benutze ich nur ganz selten, 
da kenne ich mich also nur bedingt aus. In ASM fühle ich mich wohler...

...

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
Noch kein Account? Hier anmelden.