- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 4 von 4 ErsteErste ... 234
Ergebnis 31 bis 34 von 34

Thema: ASCII-Zeichen-String auswerten in Assembler

  1. #31
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    Fehler lag bei mir , so ist das wenn man den Code nicht genau testet, nur schnell überfliegt....
    also :
    in der Zeile mit ;springe über die Adressen
    steht adiw ZL,3
    soll stehen adiw ZL,2

    sonst landet er ein Byte zu weit und vergleicht nur Dreck
    Außerdem überprüft die routine nicht, ob ein Leerzeichen am Ende ist oder nicht,
    also hilfe + # ergibt 6 Bytes, also 3 Worte, ist ok. test + # ergibt 5 Bytes, der Assembler addiert noch ein null Byte hinten dran (müßte eigentlich als Warnung ausgegeben werden ),
    dann stimmt die Adressierung mit adiw ZL,2 auch nicht mehr...
    Lösungen:
    Befehle benutzen, die ungerade Anzahl, der Bytes haben, damit das mit # wieder gerade gibt,
    oder Befehle mit Leerzeichen am Ende , damit das Ergebnis immer gerade ist z.B.
    "test# " , und dann danach prüfen und entsprechend 1 Byte weiterspringen...
    Ich war heute Faul und habe aus Deinen test teste gemacht

    Hier nochmal Code, der Funktioniert:

    Code:
    .include "../../m8def.inc"
    
    ;Definition für Clock und Baudrate
    .equ CLOCK = 10000000; 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,2   ;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   
    
    test:
       ldi ZH,HIGH(2*test_txt) ; Hilfetext
       ldi ZL,LOW(2*test_txt)
       rjmp UartSend 
    
    nochmal:
    	ldi ZH,HIGH(2*nochmal_txt) ;Befehl3
    	ldi ZL,LOW(2*nochmal_txt)
    	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
    .db "teste#"
    .dw test
    .db "nochmal#"
    .dw nochmal
             ;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
    test_txt:
    .db "Das ist ein Test ",0x0D,0x0A,0x00
    nochmal_txt:
    .db "Ich hoffe, daß alles in Ordnung ist",0x0D,0x0A,0x00
    kennenicht:
    .db "Ich weiss nicht, was Du von mir willst ",0x0D,0x0A,0x00
    So muß es klappen,ändere nur Clock und *inc.

    Achso...
    Willst Du mit dem Befehl, etwas machen, ohne ein Text zurückzuschicken muß am schluß von der entspechenden sprungroutine ein ret stehen und kein rjmp UartSend

    Ich hoffe, daß ich helfen konnte

    Gruß Sebastian

  2. #32
    Kagerer
    Gast
    Danke. Werds gleich mal testen.

    MfG
    Christian

  3. #33
    Kagerer
    Gast
    OK. Funktioniert so weit.

    Wenn ich noch probleme habe rühre ich mich wieder.

    Gruß
    Christian

  4. #34
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    freut mich,
    viel Spaß damit.

    Gruß Sebastian

Seite 4 von 4 ErsteErste ... 234

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress