Alles klar. :D
Druckbare Version
So, im Nachhinein betrachtet ohnehin klar:
Man muss/darf (wenn man INKEY() verwenden will) natürlich nur das speichern, was NICHT 0 ist. Als Endeerkennung einer Nachricht ist "0" wenig geeignet.
Wenn man z.b <CR> als Nachricht-Ende nimmt ( was Bascom-PRINT freiwillig tut, wenn man ihn nicht hindert), müsste die Receive-Schleife lauten:
unter der Annahme, dass das Speichern nicht zu langsam ist. Müsst man ausrechnen, bis zu welcher baudrate es reicht.Code:DO
inchar= inkey(#2)
if inchar > 0
incr myidx
myarr(myidx) = inchar
end if
LOOP until inchar = 27
myarr(myidx) = 0 ' ev. ein String-ende aus dem <CR> machen
Sonst ist wohl eher "INPUT #" oder GET # geeignet
Wen es interessiert, so sieht INKEY() von innen aus:
Der Unterschied von Waitkey ist minimalCode:open comb.4:9600,8,n,1
L_0x00DE: ' delay 1/2 bit --------------------------
PUSH r24
PUSH r25
LDI r24,0x08
LDI r25,0x00
L_0x00E6:
SBIW r24,0x0001
BRNE L_0x00E6
POP r25
POP r24
RET
' inkey (#1) ---------------------------------
L_0x00F0:
SBIS 0x0016,4 ' check PortB.4
RJMP L_0x00F8 ' start
CLR r24 ' return 0
RET
L_0x00F8:
LDI r18,0x09 ' counter = 9 (8 + 1 )
L_0x00FA: ' loop until PortB.4 = 0
SBIC 0x0016,4 '
RJMP L_0x00FA
RCALL L_0x00DE ' delay 1/2 bit
L_0x0100:
RCALL L_0x00DE ' delay 1/2 bit
RCALL L_0x00DE ' delay 1/2 bit
CLC ' clear carry
SBIC 0x0016,4 ' PortB.4 = ?
SEC ' = 1---> set Carry
DEC r18 ' decr counter
BREQ L_0x0114 ' counter= 0 --> exit
ROR r24 ' shift carry into r24:r25
ROR r25
RJMP L_0x0100 ' next bit
L_0x0114:
RET ' R24 = inbyte (that's it)
Code:' waitkey (#1) ---------------------------------
L_0x00F0:
SBIS 0x0016,4 ' wait PortB.4 = 0
RJMP L_0x00F6 ' start
RJMP L_0x00F0 ' cont'd wait Das ist der einzige Unterschied
9600 Baud = 9600 Bit/Sek, bei 16 MHz sind dann 1667 Takte pro Bit, da kann er viel speichern. Auch bei 76800 Baud, welche bei 16 MHz nur 0.2% Fehler hätten, wären's noch 208 Takte, sollte auch noch locker reichen. Voraussetzung ist, dass keine Interrupts unterbrechen.
Code:' inkey (#1) ---------------------------------
L_0x00F0:
SBIS 0x0016,4 ' check PortB.4
RJMP L_0x00F8
CLR r24 ' return 0
RET
Zitat:
Der Unterschied von Waitkey ist minimal
Code:' waitkey (#1) ---------------------------------
L_0x00F0:
SBIS 0x0016,4 ' wait PortB.4 = 0
RJMP L_0x00F6 ' start
RJMP L_0x00F0 ' cont'd wait
Zitat:
Das ist der einzige Unterschied
Aber der Entscheidende.
"der kleine Unterschied", in der Tat.
bei INKEY() kann man leicht eine Timeout-kontrolle einbauen, dafür muss man sich aber über die Fehlerbehandlung in so einem Fall Gedanken machen.
Bei WAITKEY() hilft ohnehin nur der reset-knopf oder der Watchdog.
pS: mit so Sachen wie Frame-control etc. hat sich Mark offenbar nicht auseinandergesetzt.
Softuart ist nicht gepuffert. Ein "wait 3" in der Hauptschleife ist also fehl am Platze. Wenn ich Softuart nutze, dann packe ich die Routine in ein Sub und rufe dieses öfter mal aus der Hauptschleife auf. So funktioniert zuverlässig meine per Softuart angebundene Fernbedienung an meinem Radio. Einen wait-Befehl gibt es bei mir so gut wie gar nicht nach Beginn der Hauptschleife. Wenn, dann mal im Millisekundenbereich (waitms / waitus). Alles Andere wird per selbstgestrickter "Tickcount" API aufgerufen. Z.B. DS1820 sagen, er solle die Temperatur aufbereiten, den ticktemp auf 0 und wenn er 100 erreicht hat (mein Tickcount läuft im 10 ms Takt) wird die Temperatur abgeholt. Größere Projekte haben meist noch eine Uhr mit "an Board". Da kann man schön die Sekunden vergleichen.