Hallo Christian, hallo Bernhard!
ich müsste gleich fertig sein, ich versehe den Code gerade noch mit Kommentaren!
Ich bin gespannt, was ihr dazu sagt! ;o)
also ich habs so gemacht:
ich hab geschaut was das erste zeichen ist. dann bin ich in die entsprechende unterroutine gesprungen und die hat dann das nächste zeichen angeschaut und dann wieder in die entsprechende unterroutine. wenn die strings nur aus 2 oder 3 bytes bestehen, geht das ganz gut.
ansonsten must du dir halt so vergleichsroutinen schreiben.
mfg
Bernhard
Hallo Christian, hallo Bernhard!
ich müsste gleich fertig sein, ich versehe den Code gerade noch mit Kommentaren!
Ich bin gespannt, was ihr dazu sagt! ;o)
Hallo Christian, hallo Bernhard!
Ich bin endlich fertig! *freu*
Was haltet ihr von dem Code?
Habt ihr Fragen?
Ich habe den Code mehrere Male simuliert, aber noch nicht in Real ausprobiert!
Ich bin gespannt!
Viel Spass damit
Florian
PS: Ich hatte selber daran interessiert den Code zu programmieren, ich brauche ihn nämlich demnächst auch mal wieder!
Außerdem hatte ich ein wenig Zeit übrig und der Spass kam auch nicht zu kurz! ;o)
Hallo Florian,
Ich habe mir Deinen Code angeschaut, und hätte da ein paar Verbeserungsvorschläge,
ich habe bis jetzt keine Routine dieser Art geschrieben, aber erst vor kurzem ein Code analysiert und man hat es folgendermaßen gelöst:
- Kein extra Register für jedes Zeichen sondern ein Puffer im Sram, wo die empfangenen Zeichen verschoben werden.
- In der Interrupt Routine wird nur geprüft, ob ein Wagenrücklauf gesendet wurde oder der Puffer nicht überläuft, was auch das Ende des Befehls bedeuten würde, sollte das eintreffen, wird eine Befehlkomplett Flagge gesetzt, die in dem Hauptprogramm entsprechend überprüft wird,
außerdem wird dort das empfangene Zeichen zurück in UDR geschoben, um es an das Terminalfenster zurückzuschicken (echo)
Vorteil: Kurze Interruptroutine und keine rcalls daraus, was man sowieso nicht machen sollte.
Wenn dann die Befehl komplett Flagge im Hauptprogramm erkannt wird, kann man den Pufferinhalt mit den Befehlen, die in .db , oder wo auch immer liegen vergleichen, und entsprechend verzweigen.
Ich hoffe, ich hab mich verständlich ausgedrückt.
Bei Bedarf kann ich den Schnipsel raussuchen und hier reinsetzen.
Gruß Sebastian
Hallo Sebastian!
Ich werde versuchen demnächst (nach der ganzen Partyzeit) den Code zu verbessern!
Ich habe zwar auch schon davon gehört, dass man keine rcalls in Interruptroutinen verwenden soll, aber ich kann das nicht nachvollziehen!
Das wäre natürlich noch besser! ;o)Bei Bedarf kann ich den Schnipsel raussuchen und hier reinsetzen.
Hallo Florian,
Da ich sowieso nicht schlafen konnte, habe ich hier ein Beispielprogramm geschrieben.
Es arbeiet mit einem sram Puffer, hollt also alle Zeichen, die empfangen werden in den Speicher, und erst nachdem man Return betätigt hat wird der Puffer ausgewertet.
Es hat auch eine kurze interrupt routine, und verwendet Flags bzw. nur eine Flagge, die in der loop routine permanent abgefragt wird.
Zugegeben, so schlau bin ich noch nicht, um mir das ganze so auszudenken,
Den Code habe ich mir hier unter Akkuloader abgeschaut und etwas abgeändert.
Das hat der Gerd richtig gut programmiert.
Als Beispiel empfängt es zeichen , wenn man hilfe eintipt wird ein Text ausgegeben, amsonsten eine Fehlermeldung.
Man kann sehr einfach weitere Befehle interpretieren und nach ein paar kleinen Änderungen auch Parameter übergeben...
Ich hoffe, daß ich es ausreichend kommentiert habe, wenn Fragen auftretten, frag mal ruhig, vielleicht kann ich sie auch beantworten.
Was man für sich ändern muß ist nur der Pfad zu der *.inc Datei, sowie Clock und Baudrate.
Gruß Sebastian
Code:.include "../../m8def.inc" ;Definition für Clock und Baudrate .equ CLOCK = 12000000 ; Processortaktfrequenz .equ BAUD = 9600 ; Serielle Schnittstelle Baudrate .equ UBRRVAL = CLOCK / (BAUD*16)-1 ;Definition für Flagregister und Flaggen .def Flagregister = R16 ; Anzeige Flag Register .def tmp = R17 ;universallregister .equ zeileempfangen = 7 ; Eine vollständige Zeile über UART empfangen ;Definition für Zeichen .equ enter = $0D ; Wagenrücklauf-Zeichen für UART ;Definition für SRAM Puffer .equ pufferzeiger = $0060 ; UART Rx Pufferzeiger .equ pufferanfang = $0061 ; UART Rx Pufferanfang .equ pufferende = $007E ; UART Rx Pufferende ;Interrupt-Vektoren .org 0x000 rjmp reset ;reset Vektor .org URXCaddr rjmp empfangen reset: ;Stack ldi tmp,HIGH(RAMEND) out SPH,tmp ldi tmp,LOW(RAMEND) out SPL,tmp ;UART ;Baudrate einstellen ldi tmp,UBRRVAL out UBRRL,tmp ;Frameformat 8Bit ldi tmp,(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) out UCSRC,tmp ;RX aktivieren sbi UCSRB,RXEN sbi UCSRB,RXCIE ;TX aktivieren sbi UCSRB,TXEN sei loop: ;Hauptschleife tst Flagregister ;Irgendeine Flagge gesetzt? breq loop ;wenn nein langweilen ldi tmp,LOW(loop) ; Schleifenanfang als Rücksprungadresse auf den Stapel push tmp ldi tmp,HIGH(loop) push tmp sbrs Flagregister,zeileempfangen ;teste, ob eine Zeile Komplet ist ret ;wenn nein langweilen befehlauswerten: ldi tmp,LOW(UartRxRet) ; Rueckkehradresse UartRxRet auf Stapel push tmp ldi tmp,HIGH(UartRxRet) push tmp ldi ZH,HIGH(2 * Cmds) ; Z zeigt auf Befehlsliste ldi ZL,LOW(2 * Cmds) befehlauswerten1: lpm ;Hole Zeichen mov tmp,R0 cpi tmp,0xFF ; 0xFF signalisiert das ende der Befehlsliste brne befehlauswerten3 befehlauswerten2: ;Ende der liste, unbekannter Befehl ldi ZH,HIGH(2 * kennenicht) ;Sende Fehlermeldung ldi ZL,LOW(2 * kennenicht) rjmp UARTSend befehlauswerten3: ;hier fangen wir an zu vergleichen ldi XH,HIGH(pufferanfang) ;X auf empfangene Zeile ldi XL,LOW(pufferanfang) befehlauswerten4: lds tmp,pufferzeiger;Pufferzeiger lesen cp XL,tmp ;Ende des Puffers erreicht? brcs befehlauswerten7 ;nein weiter befehlauswerten5: lpm ;lese nächstes Befehlszeichen adiw ZL,1 ;Z auf nächstes zeichen mov tmp,R0 cpi tmp,'#' ;Endzeichen erreicht? brne befehlauswerten5 befehlauswerten6: adiw ZL,3 ;Springe über die Adressen rjmp befehlauswerten1 ;nächster Befehl befehlauswerten7: lpm mov tmp,R0 cpi tmp,'#' ;Ende des Befehls? breq befehlauswerten8 ld tmp,X+ ;lese nächstes Zeichen aus Puffer cp tmp,R0 ;Vergleiche brne befehlauswerten5 adiw ZL,1 ;nächstes Zeichen rjmp befehlauswerten4 befehlauswerten8: lds tmp,pufferzeiger ;ende des Puffers erreicht? cpc XL,tmp brcc befehlauswerten2 adiw ZL,1 lpm push R0 adiw ZL,1 lpm push R0 ret UartSend: lpm;lese aus dem Flash adiw ZL,1 tst R0 brne UartSendR0 ret UartSendR0: mov tmp,R0 rcall UARTSendChar rjmp UartSend UartSendChar: sbis UCSRA,UDRE rjmp UartSendChar out UDR,tmp ret UartRXret: ldi tmp,LOW(pufferanfang) sts pufferzeiger,tmp cbr Flagregister,(1<<zeileempfangen) ret help: ldi ZH,HIGH(2*UartTxtHelp) ; Hilfetext ldi ZL,LOW(2*UartTxtHelp) rjmp UartSend empfangen: push tmp ;rette universallregister in tmp,SREG ;rette SREG push tmp in tmp,UDR ;Hole das empfangene Zeichen out UDR,tmp ;Echo zurück push ZH ;sichere Z-Register push ZL ;dito ldi ZH,HIGH(pufferanfang) ;position fürs nächste Zeichen MSB lds ZL,pufferzeiger st Z+,tmp ;Speichere Zeichen im sram cpi ZL,LOW(pufferende+1) ;Pufferende erreicht ? brcc empfangen_ ;Pufferüberlauf sts pufferzeiger,ZL ;speichere nächste Pufferposition empfangen_: cpi tmp,enter ;Wagenrücklauf? brne empfangen__ sbr Flagregister,(1<<zeileempfangen) empfangen__: pop ZL ;Stelle Z-Register wieder her pop ZH ;dito pop tmp ;Stelle SREG wieder her out SREG,tmp ;dito pop tmp ;stelle tmp wieder her reti ;verlasse Routine und schalte Interrupts wieder ein ;Hier fangen die Befehle an: ;alle Befehle müssen mit # terminiert werden Cmds: .db "hilfe#" .dw help ;0xFFFF muß zum schluß stehen, um ende der liste zu erkennen .dw 0xFFFF ;Ende der Befehldefinition ;Texte UartTxtHelp: .db "Das ist ein Hilfe Text ",0x0D,0x0A,0x00 kennenicht: .db "Ich weiß nicht, was Du von mir willst",0x0D,0x0A,0x00
Hallo Sebastian!
Danke für den Code!
Ich werde ihn mir wohl leider erst Sonntag ansehen können!
Danke Leute!!!
Ich werd mir die Codes gleich mal anschauen.
So hätte ich es auch selber versucht. Wollt dann nur mal wissen ob es eine elegantere Lösung gibt.Zitat von James
MfG
Christian
Also die Codes sind beide nicht schlecht. Aber um den von izaseba ganz zu kapieren werde ich wohl noch eine weile brauchen.
MfG
Christian
Hmmm, was verstehst Du nicht?Aber um den von izaseba ganz zu kapieren werde ich wohl noch eine weile brauchen
Geh mal den Assemblertutorial auf der von mir oben genannten Seite mal durch,
dann wirst Du mehr verstehen![]()
Gruß Sebastian
Lesezeichen