-
        

Ergebnis 1 bis 3 von 3

Thema: werte als spannung ausgeben

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    31.03.2010
    Beiträge
    33

    werte als spannung ausgeben

    Anzeige

    kann mir bitte jemand sagen wo der Fehler ist,
    danke


    ;//////////////////////////////////////////////////////////////////////////
    ;Titel: UART.asm
    ;
    ;
    ;//////////////////////////////////////////////////////////////////////////

    .include "m88def.inc"

    .def z0 = r1 ; Zahl für Integer -> ASCII Umwandlung
    .def z1 = r2
    .def z2 = r3
    .def z3 = r4
    .def temp1 = r16 ; allgemeines Register, zur kurzfristigen Verwendung
    .def temp2 = r17 ; Register für 24 Bit Addition, niederwertigstes Byte (LSB)
    .def temp3 = r18 ; Register für 24 Bit Addition, mittlerers Byte
    .def temp4 = r19 ; Register für 24 Bit Addition, höchstwertigstes Byte (MSB)
    .def adlow = r20 ; Ergebnis vom ADC-Mittelwert der 256 Messungen
    .def adhigh = r21 ; Ergebnis vom ADC-Mittelwert der 256 Messungen
    .def zeichen = r23 ; Zeichen zur Ausgabe auf den UART
    .def temp5 = r24
    .def temp6 = r25






    ;::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::
    ;Baud Rate berechnen
    ;-------------------
    .equ Faktor = 4883
    .equ F_CPU = 3686400 ; Systemtakt in Hz
    .equ BAUD = 9600 ; Baudrate

    ; Berechnungen
    .equ UBRR_VAL = ((F_CPU+BAUD*/(BAUD*16)-1) ; clever runden
    .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
    .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille

    .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
    .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
    .endif

    ; RAM
    .dseg
    .org 0x60
    Puffer: .byte 10


    ; hier geht das Programm los
    .cseg
    .org 0

    ;************************************************* **************************
    ;UART Initalisieren************************************* ********************
    ;************************************************* **************************

    ; Stackpointer initialisieren

    ldi temp1, HIGH(RAMEND)
    out SPH, temp1
    ldi temp1, LOW(RAMEND)
    out SPL, temp1

    ldi temp1, 0x0F
    out DDRB, temp1

    uart_init:

    ldi temp1, LOW(UBRR_VAL) ; Baudrate einstellen
    sts UBRR0L, temp1
    ldi temp1, HIGH(UBRR_VAL)
    sts UBRR0H, temp1

    ldi temp1, (1<<UMSEL01 | 3<<UCSZ00) ;Frame-Format: 8 bit
    sts UCSR0C, temp1

    ldi temp1, (1<<TXEN0);| (1<<RXEN0) ;Empfangen und Senden erlauben
    sts UCSR0B, temp1

    main:
    ldi temp1, low(5600)
    ldi temp2, high(5600)

    mov adlow, temp1
    mov adhigh, temp2

    ldi temp5,low(4883)
    ldi temp6,high(4883)
    rcall mul_16x16

    ldi XL, low(Puffer)
    ldi XH, high(Puffer)
    rcall Int_to_ASCII

    ;an UART Senden

    ldi ZL, low(Puffer+3)
    ldi ZH, high(Puffer+3)
    ldi temp1, 1
    rcall sende_zeichen ; eine Vorkommastelle ausgeben

    ldi zeichen, ',' ; Komma ausgeben
    rcall sende_einzelzeichen

    ldi temp1, 3 ; Drei Nachkommastellen ausgeben
    rcall sende_zeichen

    ldi zeichen, 'V' ; Volt Zeichen ausgeben
    rcall sende_einzelzeichen

    ldi zeichen, 10 ; New Line Steuerzeichen
    rcall sende_einzelzeichen

    ldi zeichen, 13 ; Carrige Return Steuerzeichen
    rcall sende_einzelzeichen






    rjmp main



    ;in ASCII umwandeln
    ; Division durch mehrfache Subtraktion
    ; 32 Bit Zahl in ASCII umwandeln
    ; geschwindigkeitsoptimierte Version
    ; Zahl liegt in temp1..4
    ; Ergebnis ist ein 10stelliger ASCII String, welcher im SRAM abgelegt wird
    ; Adressierung über X Pointer

    Int_to_ASCII:

    push ZL ; Register sichern
    push ZH
    push temp5
    push temp6

    ldi ZL,low(Tabelle*2) ; Zeiger auf Tabelle
    ldi ZH,high(Tabelle*2)
    ldi temp5, 10 ; Schleifenzähler

    Int_to_ASCII_schleife:
    ldi temp6, -1+'0' ; Ziffernzähler zählt direkt im ASCII Code
    lpm z0,Z+ ; Nächste Zahl laden
    lpm z1,Z+
    lpm z2,Z+
    lpm z3,Z+

    Int_to_ASCII_ziffer:
    inc temp6 ; Ziffer erhöhen
    sub temp1, z0 ; Zahl subrahieren
    sbc temp2, z1 ; 32 Bit
    sbc temp3, z2
    sbc temp4, z3
    brge Int_to_ASCII_ziffer ; noch kein Unterlauf, nochmal

    add temp1, z0 ; Unterlauf, eimal wieder addieren
    adc temp2, z1 ; 32 Bit
    adc temp3, z2
    adc temp4, z3
    st X+,temp6 ; Ziffer speichern
    dec temp5
    brne Int_to_ASCII_schleife ; noch eine Ziffer?

    pop temp6
    pop temp5
    pop ZH
    pop ZL ; Register wieder herstellen
    ret





    ;Warteschleife bis wieder ein Byte empfangen werden kann



    mul_16x16:
    push zeichen
    clr temp1 ; 32 Bit Akku löschen
    clr temp2
    clr temp3
    clr temp4
    clr zeichen ; Null, für Carry-Addition

    mul adlow, temp5 ; erste Multiplikation
    add temp1, r0 ; und akkumulieren
    adc temp2, r1

    mul adhigh, temp5 ; zweite Multiplikation
    add temp2, r0 ; und gewichtet akkumlieren
    adc temp3, r1

    mul adlow, temp6 ; dritte Multiplikation
    add temp2, r0 ; und gewichtet akkumlieren
    adc temp3, r1
    adc temp4, zeichen ; carry addieren

    mul adhigh, temp6 ; vierte Multiplikation
    add temp3, r0 ; und gewichtet akkumlieren
    adc temp4, r1

    pop zeichen
    ret


    sende_einzelzeichen:
    lds temp1,UCSR0A
    sbrs temp1,UDRE0
    rjmp sende_einzelzeichen
    sts UDR0, zeichen ; und Zeichen ausgeben
    ret

    ; mehrere Zeichen ausgeben, welche durch Z adressiert werden
    ; Anzahl in temp1

    sende_zeichen:
    lds temp1,UCSR0A
    sbrs temp1,UDRE0
    rjmp sende_zeichen
    ld zeichen, Z+ ; Zeichen laden
    sts UDR0, zeichen ; und Zeichen ausgeben
    dec temp1
    brne sende_zeichen
    ret


    ; Tabelle mit Zahlen für die Berechung der Ziffern
    ; 1 Milliarde bis 1
    Tabelle:
    .dd 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.02.2006
    Beiträge
    982
    Deine Fehlerbeschreibung ist recht duenn...
    Nam et ipsa scientia potestas est..

  3. #3
    Erfahrener Benutzer Begeisterter Techniker Avatar von albundy
    Registriert seit
    16.10.2004
    Beiträge
    282
    nur mal kurz überflogen ...

    ldi temp1, 1
    rcall sende_zeichen
    sende_zeichen:
    lds temp1,UCSR0A
    sbrs temp1,UDRE0
    rjmp sende_zeichen
    ld zeichen, Z+ ; Zeichen laden
    sts UDR0, zeichen ; und Zeichen ausgeben
    dec temp1
    brne sende_zeichen
    ret
    das gibt schon mal eine Endlosschleife.

Berechtigungen

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