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
@ Kay B. (newbie) Solche langen Quelltexte bitte als Anhang posten. AVR-Tutorial: ADC AVR-Tutorial: Vergleiche MfG Falk
>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?
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!!!!!!!!!
@ 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
@ 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.