- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 34

Thema: ASCII-Zeichen-String auswerten in Assembler

  1. #11
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    03.12.2004
    Ort
    Niederbayern
    Alter
    39
    Beiträge
    248
    Anzeige

    Praxistest und DIY Projekte
    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

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    01.11.2003
    Ort
    Freiburg im Breisgau
    Alter
    35
    Beiträge
    2.624
    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)

  3. #13
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    01.11.2003
    Ort
    Freiburg im Breisgau
    Alter
    35
    Beiträge
    2.624
    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)
    Angehängte Dateien Angehängte Dateien

  4. #14
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    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

  5. #15
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    01.11.2003
    Ort
    Freiburg im Breisgau
    Alter
    35
    Beiträge
    2.624
    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!

    Bei Bedarf kann ich den Schnipsel raussuchen und hier reinsetzen.
    Das wäre natürlich noch besser! ;o)

  6. #16
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    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

  7. #17
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    01.11.2003
    Ort
    Freiburg im Breisgau
    Alter
    35
    Beiträge
    2.624
    Hallo Sebastian!
    Danke für den Code!
    Ich werde ihn mir wohl leider erst Sonntag ansehen können!

  8. #18
    Kagerer
    Gast
    Danke Leute!!!

    Ich werd mir die Codes gleich mal anschauen.

    Zitat Zitat von James
    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.
    So hätte ich es auch selber versucht. Wollt dann nur mal wissen ob es eine elegantere Lösung gibt.

    MfG
    Christian

  9. #19
    Kagerer
    Gast
    Also die Codes sind beide nicht schlecht. Aber um den von izaseba ganz zu kapieren werde ich wohl noch eine weile brauchen .

    MfG
    Christian

  10. #20
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Aber um den von izaseba ganz zu kapieren werde ich wohl noch eine weile brauchen
    Hmmm, was verstehst Du nicht?

    Geh mal den Assemblertutorial auf der von mir oben genannten Seite mal durch,
    dann wirst Du mehr verstehen

    Gruß Sebastian

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen