Forum: Mikrocontroller und Digitale Elektronik 10-BIT-Wert vergleichen


von Kay B. (newbie)


Lesenswert?

hallo,
ich lese einen wert an ADC0 ein der ist 10-Bit(0-1023) nun wollte ich 
diesen mit einer konstante vergleichen zB..equ MAX=1000 das sind denn 
4,887Volt bei diesem wert sollte die led angehen und darunter sollte sie 
wieder ausgehen aber das funktioniert nicht die led bleibt an.

vielleicht könnte mir einer von ein ein bischen weiterhelfen.

danke

mfg kay





.include "m128def.inc"

.def temp1     = r16         ; allgemeines temp Register, zur 
kurzfristige Verwendung
.def temp2     = r17         ; Register für 24 Bit Addition, Lowest Byte
.def temp3     = r18         ; Register für 24 Bit Addition, Middle Byte
.def temp4     = r19         ; Register für 24 Bit Addition, Highest 
Byte
.def adlow     = r20         ; Ergebnis vom ADC / Mittelwert der 256 
Messungen
.def adhigh    = r21         ; Ergebnis vom ADC / Mittelwert der 256 
Messungen
.def messungen = r22         ; Schleifenzähler für die Messungen
.def zeichen   = r23         ; Zeichen zur Ausgabe auf den UART
.def temp5     = r24
.def temp6     = r25
.def BUFFER     = R26
.def helpreg     = R27      ;hilfsregister


; Faktor für Umrechung des ADC-Wertes in Spannung
; = (Referenzspannung / 1024 ) * 100000
; = 5V / 1024 * 1.000.000
.equ Faktor = 4883

.equ clock = 14745600 ;
.equ BAUD1 = 9600
.equ UBRRVAL = CLOCK/(BAUD1*16)-1

.equ MAX = 1000
;ausgang für alarm led
.equ alarmport=portG
.equ alarmddr=ddrG
.equ alarmbit=pg4



; RAM
.dseg
.org 0x100

Puffer: .byte 10

; hier geht das Programm los
.cseg
.org 0

    ldi     temp1, LOW(RAMEND)                  ; Stackpointer 
initialisieren
    out     SPL, temp1
    ldi     temp1, HIGH(RAMEND)
    out     SPH, temp1


; Port G = Ausgang
; alles auf Ausgang
 ldi    temp1,0xFF
 sts    DDRG,temp1



;UART Initalisierung
   ; Baudrate einstellen
    ldi temp1, LOW(UBRRVAL)
    sts UBRR1L, temp1
    ldi temp1, HIGH(UBRRVAL)
    sts UBRR1H, temp1

    ; TX1 aktivieren
    ldi temp1, (1<<TXEN1)
    sts UCSR1B, temp1

    ; Set frame format: 8data, 2stop bit
    ldi temp1, (1<<USBS1)|(3<<UCSZ10)
    sts UCSR1C, temp1


; ADC initialisieren: Single Conversion, Vorteiler 128
; Kanal 0, interne Referenzspannung AVCC

    ldi     temp1, (1<<REFS0)
    out     ADMUX, temp1
    ldi     temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
    out     ADCSRA, temp1

Hauptschleife:
    clr     temp1
    clr     temp2
    clr     temp3
    clr     temp4

    ldi     messungen, 0        ; 256 Schleifendurchläufe

; neuen ADC-Wert lesen  (Schleife - 256 mal)

adc_messung:
    sbi     ADCSRA, ADSC        ; den ADC starten

adc_warten:
    sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses 
Bit gelöscht
    rjmp    adc_warten

; ADC einlesen:

    in      adlow, ADCL         ; immer zuerst LOW Byte lesen
    in      adhigh, ADCH        ; danach das mittlerweile gesperrte High 
Byte

; alle 256 ADC-Werte addieren
; dazu wird mit den Registern temp4, temp3 und temp2 ein
; 24-Bit breites Akkumulationsregister gebildet, in dem
; die 10 Bit Werte aus adhigh, adlow aufsummiert werden

    add     temp2, adlow        ; addieren
    adc     temp3, adhigh       ; addieren über Carry
    adc     temp4, temp1        ; addieren über Carry, temp1 enthält 0
    dec     messungen           ; Schleifenzähler MINUS 1
    brne    adc_messung         ; wenn noch keine 256 ADC Werte -> 
nächsten Wert einlesen

; Aus den 256 Werten den Mittelwert berechnen
; Bei 256 Werten ist das ganz einfach: Das niederwertigste Byte
; (im Register temp2) fällt einfach weg
;
; allerdings wird der Wert noch gerundet

    cpi     temp2,128           ; "Kommastelle" kleiner als 128 ?
    brlo    nicht_runden        ; ist kleiner ==> Sprung

; Aufrunden
    subi    temp3, low(-1)      ; addieren von 1
    sbci    temp4, high(-1)     ; addieren des Carry

nicht_runden:

;   Ergebnis nach adlow und adhigh kopieren
;   damit die temp Register frei werden

    mov     adlow, temp3
    mov     adhigh, temp4

 ldi helpreg,high(max)
 cpi adlow,low(max)
 cpc adhigh,helpreg
 brcs warn
 brlo warn2
 rjmp weiter


warn:
LDS temp1, PORTG
 SBR temp1,1<<alarmbit  ; setze bit auf 1
 STS PORTG, temp1
rjmp weiter


warn2:
LDS temp1, PORTG
 CBR temp1,1<<alarmbit  ; setze bit auf 0
 STS PORTG, temp1


weiter:

; in Spannung umrechnen

    ldi     temp5,low(Faktor)
    ldi     temp6,high(Faktor)
    rcall   mul16x16

; in ASCII umwandeln

    ldi     ZL, low(Puffer)
    ldi     ZH, 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    Hauptschleife

; Ende des Hauptprogramms

; Unterprogramme

 ; ein Zeichen per UART senden

sende_einzelzeichen:
    ;sbis    UCSRA,UDRE          ; Warten, bis UDR bereit ist ...
    ;rjmp    sende_einzelzeichen
    ;out     UDR, zeichen        ; und Zeichen ausgeben

  ; Wait for empty transmit buffer
    lds BUFFER, UCSR1A
    sbrs BUFFER, UDRE1
    rjmp sende_einzelzeichen

    sts UDR1, zeichen


  ret

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

sende_zeichen:
   ; sbis    UCSRA,UDRE          ; Warten, bis UDR bereit ist ...
   ; rjmp    sende_zeichen
   ; ld      zeichen, Z+         ; Zeichen laden
   ; out     UDR, zeichen        ; und Zeichen ausgeben
    ;dec     temp1
    ;brne    sende_zeichen
    ;ret




 ; Wait for empty transmit buffer

SENDING:
   ld      zeichen, Z+         ; Zeichen laden
    rcall    USART_Transmit        ; und Zeichen ausgeben
    dec     temp1
    brne    SENDING



    ret



USART_Transmit:


    lds BUFFER, UCSR1A
    sbrs BUFFER, UDRE1
    rjmp USART_Transmit

    sts UDR1, zeichen;zeichen
    ret




; 32 Bit Zahl in ASCII umwandeln
; Zahl liegt in temp1..4
; Ergebnis ist ein 10stelliger ASCII String, welcher im SRAM abgelegt 
wird
; Adressierung über Z Pointer

Int_to_ASCII:
    ldi     temp5, -1 + '0'
_a1ser:
    inc     temp5
    subi    temp1,BYTE1(1000000000) ; - 1.000.000.000
    sbci    temp2,BYTE2(1000000000)
    sbci    temp3,BYTE3(1000000000)
    sbci    temp4,BYTE4(1000000000)
    brcc    _a1ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, 10 + '0'
_a2ser:
    dec     temp5
    subi    temp1,BYTE1(-100000000) ; + 100.000.000
    sbci    temp2,BYTE2(-100000000)
    sbci    temp3,BYTE3(-100000000)
    sbci    temp4,BYTE4(-100000000)
    brcs    _a2ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, -1 + '0'
_a3ser:
    inc     temp5
    subi    temp1,low(10000000)     ; - 10.000.000
    sbci    temp2,high(10000000)
    sbci    temp3,BYTE3(10000000)
    brcc    _a3ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, 10 + '0'
_a4ser:
    dec     temp5
    subi    temp1,low(-1000000)     ; + 1.000.000
    sbci    temp2,high(-1000000)
    sbci    temp3,BYTE3(-1000000)
    brcs    _a4ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, -1 + '0'
_a5ser:
    inc     temp5
    subi    temp1,low(100000)       ; -100.000
    sbci    temp2,high(100000)
    sbci    temp3,BYTE3(100000)
    brcc    _a5ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, 10 + '0'
_a6ser:
    dec     temp5
    subi    temp1,low(-10000)       ; +10,000
    sbci    temp2,high(-10000)
    sbci    temp3,BYTE3(-10000)
    brcs    _a6ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, -1 + '0'
_a7ser:
    inc     temp5
    subi    temp1,low(1000)         ; -1000
    sbci    temp2,high(1000)
    brcc    _a7ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, 10 + '0'
_a8ser:
    dec     temp5
    subi    temp1,low(-100)         ; +100
    sbci    temp2,high(-100)
    brcs    _a8ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, -1 + '0'
_a9ser:
    inc     temp5
    subi    temp1, 10               ; -10
    brcc    _a9ser

    st      Z+,temp5                ; im Puffer speichern
    ldi     temp5, 10 + '0'
_a10ser:
    dec     temp5
    subi    temp1, -1               ; +1
    brcs    _a10ser

    st      Z+,temp5                ; im Puffer speichern
    ret

; 16 Bit Wert in Spannung umrechnen
;
; = 16Bitx16Bit=32 Bit Multiplikation
; = vier 8x8 Bit Multiplikationen
;
; adlow/adhigh * temp5/temp6

mul16x16:
    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

von egon (Gast)


Lesenswert?

cp Reg1low,Reg2low
cpc Reg1high,Reg2high
brxx...

von Falk B. (falk)


Lesenswert?

@ Kay B. (newbie)

Solche langen Quelltexte bitte als Anhang posten.

AVR-Tutorial: ADC
AVR-Tutorial: Vergleiche

MfG
Falk

von Stefan Salewski (Gast)


Lesenswert?

>Solche langen Quelltexte bitte als Anhang posten.

Auch nicht viel besser.

@Autor:  Kay B. (newbie)

Bringst Du auch Deine gesamte Kleidung zum Schneider, wenn bei einem 
Hemd ein Knopf abgerissen ist?

von Kay B. (newbie)


Lesenswert?

Stefan Salewski wrote:
>>Solche langen Quelltexte bitte als Anhang posten.
>
> Auch nicht viel besser.
>
> @Autor:  Kay B. (newbie)
>
> Bringst Du auch Deine gesamte Kleidung zum Schneider, wenn bei einem
> Hemd ein Knopf abgerissen ist?


ich hab doch nur eine höfliche frage gestellt!!!!!!!!!

von Wolfram Q. (quehl)


Lesenswert?

@ Stefan salewski

eins verstehe ich nun nicht. wenn man nur einen Teil schreibt, dann 
heißt das, meine Glaskugel ist gerade beim Glaser. Wenn man alles 
schreibt, ist das auch verkehrt. Was soll denn so ein Anfrager machen, 
wenn das sowieso immer verkehrt ist, egal wieviel man vom Programm 
schreibt. Soll er sich immer beschimpfen lassen, dann hat der Frager 
auch bald keine Lust mehr.

@Falk

ist zwar vom Prinzip richtig, ich persönlich freue mich aber auch, wenn 
das Programm im Text steht. Da ich ein Modem habe, lade ich alle 
interessanten Beiträge zunächst runter und wenn da was im Anhang steht, 
dann muß ich das nächste mal den Beitrag neu suchen, um den Anhang 
runterladen zu können. Hat also alles so seine Vor und Nachteile.

mfg

von Gast (Gast)


Lesenswert?

Was sagt der Debugger?

von Falk B. (falk)


Lesenswert?

@ Wolfram Quehl (quehl)

>ist zwar vom Prinzip richtig, ich persönlich freue mich aber auch, wenn
>das Programm im Text steht. Da ich ein Modem habe, lade ich alle
>interessanten Beiträge zunächst runter und wenn da was im Anhang steht,

Naja, bei aller Rücksicht auf Modenuser, aber soweit glaub ich geht das 
dann doch nicht. Lange Quelltexte gehören in den Anhang.

MFG
Falk

von Kay B. (newbie)


Lesenswert?

Gast wrote:
> Was sagt der Debugger?

die led geht sofort an egal was für ein wert am adc anliegt,led geht 
nicht aus.
mfg
kay

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.