- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 4 von 4

Thema: über seriell empfangene Zeichen im Speicher ablegen?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200

    über seriell empfangene Zeichen im Speicher ablegen?

    Hallo,

    da es inzwischen mit dem Senden und Empfangen klappt, würde ich mein Programm gern ein bisschenaussbauen und die empfangenen Zeichen speichern.
    Ich nehme an, dass sich hierfür der SRAM am besten eignet. Doch wie bekomme ich die Zeichen da rein? Vielleicht hat ja jemand ein paar Codeschnipsel für mich.

    Später soll dan sowas rauskommen wie: "Sie haben folgenden Text eingegeben: Assembler macht Spass"

    Grüße, JK

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    18.01.2008
    Ort
    Erfurt
    Alter
    42
    Beiträge
    39
    Wie sieht dein momentaner Code aus?

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    das isser:
    Code:
     .NOLIST                    	; List-Output unterdrücken
    ; .INCLUDE <m8def.inc>       	; das gibt es für jeden Controllertyp
     .include "C:\PROGRA~1\VMLAB\include\m8def.inc
    
     .def temp = R16				; für Interrupt
     .def ZEICHEN = R17
    
    
     ;------------------------------------------------------
     ;    Peripherie initialisieren ;------------------------------------------------------
    .equ F_CPU = 7372800                            ; Systemtakt in Hz
    .equ BAUD  = 9600                               ; Baudrate
    .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)	; Berechnen des Teilers für die Baudrate
    
     .LIST                      	; List-Output wieder aufdrehen
     .CSEG                      	; was nun folgt, gehört in den FLASH-Speicher
    
    
     ;------------------------------------------------------
     ;     Start Adresse 0000 /Interruptvektoren
     ;------------------------------------------------------
     .org 0x000			; Interruptvektoren überspringen
    	rjmp Init			
    
      .org 0x00B		; UART Receive Complete Interrupt
        rjmp serin
    
      .org 0x00C		; USART Data Register Empty
        rjmp serout
    
     ;------------------------------------------------------
     ;     INITIALIZE
     ;------------------------------------------------------
    INIT:
    ;Stack Pointer setzen
      ldi temp,high(RAMEND)
      out SPH,temp
      ldi temp,low(RAMEND)
      out SPL,temp
    
    ; Baudrate einstellen
      ldi temp, HIGH(UBRR_VAL)
      out UBRRH, temp
      ldi temp, LOW(UBRR_VAL)
      out UBRRL, temp
    
    ; Frame-Format: 1 Stop-Bits, 8 Bit
      ldi temp, (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
      out UCSRC, temp
    
      sbi UCSRB,RXEN					; Freigabe Empfangen
      sbi UCSRB,RXCIE					; Interrupt für "Zeichen empfangen"
      sbi UCSRB,TXEN           			; Sender aktivieren
    
      sei 								; globale Interruptfreigabe
    
       ldi XL, LOW(input*2)			; Adresse für Ablegen des ersten Zeichens in den
       ldi XH, HIGH(input*2)		; X-Pointer laden
    
    
     ;------------------------------------------------------
     ;   HAUPTSCHLEIFE
     ;------------------------------------------------------
    Hauptschleife:					
    	
    
    rjmp Hauptschleife
    
    
     ;------------------------------------------------------
     ;   Subroutinen / ISRs
     ;------------------------------------------------------
    
    ;Auslesen der Zeichen und bereitstellen in ZEICHEN
    ;Erhöhen des Z-Pointers; bei leerem Zeichen --> Zurücksetzen des Z-Pointers
    
    serout:								; (ISR)
       lpm								; Erstes Byte des Strings nach R0 lesen
    
       mov ZEICHEN,R0
       adiw ZL, 1                       ; Adresse des Z-Pointers um 1 erhöhen
       tst R0							; Inhalt von R0 auf Null testen
    
       brbc 1,sprung_a					; nächten Befehl ausführen wenn kompletter String gesendet
        cbi UCSRB,UDRIE					; Interrupt für "Puffer leer"
    
       sprung_a:
        out UDR, ZEICHEN				; Zeichen auf UART ausgeben
    reti
    
    
    serin: 							; (ISR)
      in temp, UDR					; Zeichen auslesen
      st x+, temp					; im SRAM speichern
    
      cpi temp,0x8D					; prüfen ob Enter gedrückt wurde
      brne no_enter					; ISR beenden wenn nicht Enter gedrückt wurde
    
       ldi ZEICHEN, '>'				; diese Zeichen als Antwort der ISR ausgeben
        out UDR, ZEICHEN
    
       sbi UCSRB,UDRIE				; Interrupt für "Puffer leer" freigeben
       ldi ZL, LOW(Daten*2)			; Adresse des ersten Strings in den
       ldi ZH, HIGH(Daten*2)		; Z-Pointer laden
    
    no_enter:
    reti							; Beim Verlassen wird sofort in die ISR für Senden gewechselt, UDRE=1
    								; und der Interrupt freigegeben ist
    
    
     ;------------------------------------------------------
     ;   Datenbereich
     ;------------------------------------------------------
    Daten:
               .db "du hast folgendes Zeichen eingegeben: " ,10,13,0	
    
    
    .DSEG
    input: .Byte	20					; 20 Byte unter den Namen 'input' reservieren
    soweit funktioniert das Programm ja, allerdings weiß ich nicht, ob die Zeichen korrekt im RAM abgelegt werden. Deshalb würde mich noch interessieren wie ich den Inhalt des RAM-Speichers interpretieren soll. Ich simuliere mit VMLab.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken zwischenablage01_689.jpg  

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    inzwischen läuft es...
    Code:
     .NOLIST                    	; List-Output unterdrücken
     .INCLUDE <m8def.inc>       	; das gibt es für jeden Controllertyp
    ; .include "C:\PROGRA~1\VMLAB\include\m8def.inc
    
     .def temp = R16				; für Interrupt
     .def ZEICHEN = R17
     .def merker_isr = R18			;Merker dass im SRAM gespeicherte Zeichenkette gesendet wurde
    
     ;------------------------------------------------------
     ;    Peripherie initialisieren
     ;------------------------------------------------------
    .equ F_CPU = 7372800                            ; Systemtakt in Hz
    .equ BAUD  = 9600                               ; Baudrate
    .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)	; Berechnen des Teilers für die Baudrate
    
     .LIST                      	; List-Output wieder aufdrehen
     .CSEG                      	; was nun folgt, gehört in den FLASH-Speicher
    
    
     ;------------------------------------------------------
     ;     Start Adresse 0000 /Interruptvektoren
     ;------------------------------------------------------
     .org 0x000			; Interruptvektoren überspringen
    	rjmp Init			
    
      .org 0x00B		; UART Receive Complete Interrupt
        rjmp serin
    
      .org 0x00C		; USART Data Register Empty
        rjmp serout
    
     ;------------------------------------------------------
     ;     INITIALIZE
     ;------------------------------------------------------
    INIT:
    ;Stack Pointer setzen
      ldi temp,high(RAMEND)
      out SPH,temp
      ldi temp,low(RAMEND)
      out SPL,temp
    
    ; Baudrate einstellen
      ldi temp, HIGH(UBRR_VAL)
      out UBRRH, temp
      ldi temp, LOW(UBRR_VAL)
      out UBRRL, temp
    
    ; Frame-Format: 1 Stop-Bits, 8 Bit
      ldi temp, (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
      out UCSRC, temp
    
      sbi UCSRB,RXEN					; Freigabe Empfangen
      sbi UCSRB,RXCIE					; Interrupt für "Zeichen empfangen"
      sbi UCSRB,TXEN           			; Sender aktivieren
    
      sei 								; globale Interruptfreigabe
    
      ldi XL, LOW(input*2)				; Adresse für Ablegen des ersten Zeichens in den
      ldi XH, HIGH(input*2)				; X-Pointer laden
    
      ldi merker_isr,0					;Initialisierung der var, wichtig für vmlab
    
     ;------------------------------------------------------
     ;   HAUPTSCHLEIFE
     ;------------------------------------------------------
    Hauptschleife:					
    	
    rjmp Hauptschleife
    
    
     ;------------------------------------------------------
     ;   Subroutinen / ISRs
     ;------------------------------------------------------
    serin: 							; (ISR)
      in temp, UDR					; Zeichen zwischen speichern
      out UDR, temp					; Zeichen ausgeben
      st x+, temp					; im SRAM speichern
    
      cpi temp,0x0D					; prüfen ob Enter gedrückt wurde
      brne no_enter					; ISR beenden wenn nicht Enter gedrückt wurde
    
    ; --- Block abarbeiten wenn Zeichenkette vollständig gesendet ---------------
       ldi ZEICHEN, '>'				; dieses Zeichen als Antwort der ISR ausgeben
        out UDR, ZEICHEN
       sbi UCSRB,UDRIE				; Interrupt für "Sendepuffer leer" freigeben
       ldi ZL, LOW(Daten*2)			; Z-Pointer zurücksetzen
       ldi ZH, HIGH(Daten*2)
       ldi XL, LOW(input*2)			; X-Pointer zurücksetzen
       ldi XH, HIGH(input*2)		
    
    no_enter: reti					; Sobald Enter gedrückt wurde, wird beim Verlassen der ISR 'serin' sofort in die ISR 'serout' gewechselt, (UDRE=1)
    								; weil Interrupt (UDRIE) freigegeben wird
    
    
    
    serout:							; (ISR)
      cpi merker_isr,1				; wenn Zeichenkette aus Programmspeicher gesendet, dann springen zum nächsten Block
      breq string1_ready
    
    ;  --------- diesen Teil abarbeiten, wenn String im Programmspeicher noch nicht gesendet wurde ----------
       lpm							; nächstes Byte des Strings nach R0 lesen (Z-Pointer)
       mov ZEICHEN,R0
       adiw ZL,1                    ; Adresse des Z-Pointers um 1 erhöhen
       tst R0						; Inhalt von R0 auf Null testen
    
       brbc 1,sprung_a				; nächten Befehl ausführen wenn kompletter String gesendet
    	ldi merker_isr,1
    
     sprung_a:
        out UDR, ZEICHEN			; Zeichen auf UART ausgeben
       rjmp sprung_b				; springe zum Ende, da Zeichenkette noch nicht fertig gesendet
    
    ;  ---------- hier weitermachen wenn String im Programmspeicher gesendet wurde ----------------------
     string1_ready:
       ld  ZEICHEN,X+
      	out UDR, ZEICHEN			; Zeichen auf UART ausgeben
       cpi ZEICHEN,0x0D				; wurde Ende des Strings erreicht? (Enter im Speicher)
       brne sprung_b				; ja -->  beim nächsten Befehlsblock weitermachen; nein --> ISR verlassen für nächstes Zeichen
    
    ;   ---------- wenn String gesendet, diesen Teil abarbeiten ------------------------------------------------------
      wait1:
        sbis    UCSRA,UDRE     		; Warten bis UDR für das nächste Byte bereit ist
        rjmp    wait1
       ldi temp,0x0a				; Line Feed
    	out UDR,temp
    
      wait2:
        sbis    UCSRA,UDRE      	; Warten bis UDR für das nächste Byte bereit ist                                        ;
        rjmp    wait2
       ldi temp,0x0d				; Zeilenumbruch
    	out UDR,temp
    
       cbi UCSRB,UDRIE				; Interrupt für "Sendepuffer leer" sprerren
       ldi XL, LOW(input*2)			; Adresse für Ablegen des ersten Zeichens in den
       ldi XH, HIGH(input*2)		; X-Pointer zurücksetzen
       ldi merker_isr,0				; Merker zurücksetzen
    
     sprung_b: reti
    
    
     ;------------------------------------------------------
     ;   Datenbereich
     ;------------------------------------------------------
    	Daten:  .db "du hast folgende Zeichen eingegeben:",0,0	
    
    .DSEG
    	input: .Byte	20			; 20 Byte unter den Namen 'input' reservieren

Berechtigungen

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

Solar Speicher und Akkus Tests