PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schreiben in SRAM



Johnny_112
17.12.2005, 23:47
Hallo,

ich wollte ein ganz simples kleines Programm schreiben, jedoch funktioniert es nicht so, wie es soll. Als Mikrocontroller verwende ich einen ATMega32.

hier mal der Code:



ldi r17,1

ldi r16,2

add r16,r17 ; addiere

sts $0050,r16 ; Schreibe in SRAM (geht da auch 0x0050 anstelle von
;$0050)

lds r18,$0050 ; Schreibe von SRAM in Register

im avr Studio kriege ich jedoch in Speicherzelle $0050 des SRAM nur FF angezeigt und nicht 03. SRAM ist ja Programmspeicher, oder? Weiß jemand was ich da falsch mache?

Danke!

linux_80
18.12.2005, 00:15
Hallo,
der Speicher (SRAM) geht in der Regel erst bei $60 an, vorher liegen die Register (Datenblatt Seite 15)
Bei $50 triffst Du das Register SFIOR !
Um den richtigen Start des SRAMs zu erwischen, wird in der .inc-Datei die Variable SRAM_START mit dem entsprechenden Wert gesetzt.

Ratber
18.12.2005, 12:22
SRAM ist ja Programmspeicher, oder?

Nein,das Programm steht im Flash.
Das Sram wird gewöhnlich für Variablen und Register genutzt.

Johnny_112
18.12.2005, 12:37
Ach so. Danke! Dann finde ich die Adresse für den Flash-Anfang im Datenblatt oder in der Inc.Datei?

Noch was anderes, hatte das schon mal gefragt, jedoch keine Antwort gekriegt:

Ich möchte mit Hilfe der Taster am Rn-Control LEDs an/ausschalten. Ich weiß, dass ich dafür den ADC auswerten muss. Jedoch weiß ich nicht wie ich das in Assembler schreiben kann. Ich muss ADEN auf 1 setzen, und weiter? Wollte das ganze mal ohne Interrupt machen, so dass das Programm die ganze Zeit durchläuft und ständig abfragt, ist Wert erreicht, dann schalte LED ein.

Vielen Dank!

PicNick
18.12.2005, 12:45
Bei $50 triffst Du das Register SFIOR !
Trotzdem sind die Befehle gültig und müßten funktionieren.
Wahrscheinlich ist der AVRSimulator auf klugsch.. unterwegs und unterdrückt das (vermute ich mal)

linux_80
18.12.2005, 12:51
Hi Johnny,
ich glaub Du musst doch etwas im Datenblatt in Sachen Speicheraufteilung wühlen,
denn im Flash steht nur das Programm, das man mit zB. PonyProg da rein brennt, wenn Du Werte über einen Reset rüberretten möchtest, kann man das im EEprom hinterlegen.
Ins Flash schreibt man normalerweise nicht, das wird zB. in Bootloadern verwendet, denn man kann im Flash beim schreiben nicht einen einzelne Speicherstelle ansprechen, es muss immer eine ganze Seite(mehrer Bytes), deren grösse im DB steht, geflasht werden !

Johnny_112
19.12.2005, 00:20
Kann mir denn keiner auf den 4. Thread eine Antwort geben, wegen AD-Wandler?

Ich benötige es für die Auswertung der Tasten über ADC am RN-Control mit ATMega32. [-o<

izaseba
19.12.2005, 07:17
Kann mir denn keiner auf den 4. Thread eine Antwort geben, wegen AD-Wandler?

Wo liegt jetzt das Problem?

Ich habe doch einen links auf Asuro Tastenabfrage gepostet, hier nochmal das Programm:



.include "m8def.inc"

;UBRR = Taktfrequenz / 16 * Baudrate -1
.def rBin1L = R1 ;Wird gebraucht um bin -> ascii zu rechnen
.def rbin1H = R2 ;Wird gebraucht um bin -> ascii zu rechnen
.def rbin2H = R3 ;Wird gebraucht um bin -> ascii zu rechnen
.def rbin2L = R4 ;Wird gebraucht um bin -> ascii zu rechnen

.def tmp = R16 ;universalregister
.def statusreg = R17 ;Statusregister um die Interrupts zu signalisieren
.def rmp = R18 ;universalregister für die Umrechnung
.equ sramanfang = 0x0060
.equ bumper = 7 ;Bit 7 von statusreg signalisiert INT1 Interrupt
.equ CLOCK = 8000000
.equ BAUD = 2400
.equ UBRRVAL = CLOCK / (BAUD*16)-1

.org 0x000
rjmp reset
.org INT1addr
rjmp kolision ;Ext Interrupt Vector Address
reset:
;Stackpointer
ldi tmp,LOW(RAMEND)
out SPL,tmp
ldi tmp,HIGH(RAMEND)
out SPH,tmp
;sram pointer
ldi ZH,HIGH(sramanfang)
ldi ZL,LOW(sramanfang)
;Baudrate einstellen
ldi tmp,UBRRVAL
out UBRRL,tmp
;di tmp,HIGH(UBRRVAL)
;ut UBRRL,tmp
;Frameformat 8Bit
ldi tmp,(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
out UCSRC,tmp

sbi UCSRB,TXEN ;TX aktivieren

;AD converter Init
ldi tmp,(1<< ADEN) | (1<<ADPS1) | (1<<ADPS2)
out ADCSRA,tmp
ldi tmp,(1<<REFS0) | (1<<MUX2)
out ADMUX,tmp
;Einstellen Low Level Interrupt für Tastenabfrage
ldi tmp,(1<<INT1)
out GICR,tmp
sei
loop_:
;sram pointer
ldi ZH,HIGH(sramanfang)
ldi ZL,LOW(sramanfang)
loop:
sbrs statusreg,bumper ;prüfe statusregister ob bit 7 -> bumper gesetzt ist wenn ja dann springe
rjmp loop
in tmp,GICR ;Schalte INT1 interrupt ab
andi tmp,0x7f
out GICR,tmp
ldi statusreg,0 ;lösche statusregister bumper
cli ;Interrupts allgemein ausschalten
sbi DDRD,PD3 ;schalte pin PD3 als Ausgang
sbi PORTD,PD3 ;und setze es auf HIGH
ldi R16, $85 ; 10 ms abwarten
L1: ldi R18, $C7
L2: dec R18
brne L2
dec R16
brne L1
sbi ADCSRA,ADSC ;Starte ADC
warte:
sbis ADCSRA,ADIF
rjmp warte
;fertig und lese Ergebnis ein
in rBin1L,ADCL
in rBin1H,ADCH
cbi PORTD,PD3 ;Pin PD3 wieder LOW
cbi DDRD,PD3 ;und wieder als Eingang
sei ;Interrups wieder an
rcall berechne ;Rechne Ergebnis in ascii um und schreibe
;es in sram


rcall serout ;gib das Ergebnis über UART aus
in tmp,GICR ;Schalte Interrupts auf INT1 wieder ein
ori tmp,0x80
out GICR,tmp
rjmp loop_ ;wenn fertig wieder von vorne anfangen

serout:
ldi tmp,0x00 ;Zähler für Anzahl der CHAR
serout_:
cpi tmp,0x05 ;Vergleiche Zähler mit 0x05
breq rausuart ;Wenn gleich springe
ld R0,Z ;Hole ASCII kodierte Zahl aus den SRAM
serout__:
sbis UCSRA,UDRE ;Springe wenn UDR gesetzt ist
rjmp serout__
out UDR,R0 ;schiebe R0 in UDR
adiw ZL,1 ;Z++
inc tmp ;Zähler ++
rjmp serout_
rausuart:
sbis UCSRA,UDRE ;Springe wenn UDR gesetzt ist
rjmp rausuart
ldi tmp,10 ;sende Zeilenvorschub
out UDR,tmp
rausuart_:
sbis UCSRA,UDRE
rjmp rausuart_
ldi tmp,13 ;sende Wagerücklauf
out UDR,tmp
ret

;Diese Routine stammt von Gerd Schmidt http://www.avr-asm-tutorial.net/avr_de/index.html
;Danke dafür
berechne:
rcall Bin2ToBcd5 ; wandle Binärzahl in BCD um
ldi rmp,4 ; Zähler auf 4
mov rBin2L,rmp
Bin2ToAsc5a:
ld rmp,z ; Lese eine BCD-Ziffer
tst rmp ; prüfe ob Null
brne Bin2ToAsc5b ; Nein, erste Ziffer ungleich 0 gefunden
ldi rmp,' ' ; mit Leerzeichen überschreiben
st z+,rmp ; und ablegen
dec rBin2L ; Zähler um eins senken
brne Bin2ToAsc5a ; weitere führende Leerzeichen
ld rmp,z ; Lese das letzte Zeichen
Bin2ToAsc5b:
inc rBin2L ; Ein Zeichen mehr
Bin2ToAsc5c:
subi rmp,-'0' ; Addiere ASCII-0
st z+,rmp ; und speichere ab, erhöhe Zeiger
ld rmp,z ; nächstes Zeichen lesen
dec rBin2L ; noch Zeichen behandeln?
brne Bin2ToAsc5c ; ja, weitermachen
sbiw ZL,5 ; Zeiger an Anfang
ret ; fertig

Bin2ToBcd5:
push rBin1H ; Rette Inhalt der Register rBin1H:L
push rBin1L
ldi rmp,HIGH(10000) ; Lade 10.000 in rBin2H:L
mov rBin2H,rmp
ldi rmp,LOW(10000)
mov rBin2L,rmp
rcall Bin2ToDigit ; Ermittle 5.Stelle durch Abziehen
ldi rmp,HIGH(1000) ; Lade 1.000 in rBin2H:L
mov rBin2H,rmp
ldi rmp,LOW(1000)
mov rBin2L,rmp
rcall Bin2ToDigit ; Ermittle 4.Stelle durch Abziehen
ldi rmp,HIGH(100) ; Lade 100 in rBin2H:L
mov rBin2H,rmp
ldi rmp,LOW(100)
mov rBin2L,rmp
rcall Bin2ToDigit ; Ermittle 3.Stelle durch Abziehen
ldi rmp,HIGH(10) ; Lade 10 in rBin2H:L
mov rBin2H,rmp
ldi rmp,LOW(10)
mov rBin2L,rmp
rcall Bin2ToDigit ; Ermittle 2.Stelle durch Abziehen
st z,rBin1L ; Rest sind Einer
sbiw ZL,4 ; Setze Zeiger Z auf 5.Stelle (erste Ziffer)
pop rBin1L ; Stelle den Originalwert wieder her
pop rBin1H
ret ; und kehre zurück
Bin2ToDigit:
clr rmp ; Zähler auf Null
Bin2ToDigita:
cp rBin1H,rBin2H ; Vergleiche MSBs miteinander
brcs Bin2ToDigitc ; MSB Binärzahl kleiner, fertig
brne Bin2ToDigitb ; MSB Binärzahl größer, subtrahiere
cp rBin1L,rBin2L ; MSB gleich, vergleiche LSBs
brcs Bin2ToDigitc ; LSB Binärzahl kleiner, fertig
Bin2ToDigitb:
sub rBin1L,rBin2L ; Subtrahiere LSB Dezimalzahl
sbc rBin1H,rBin2H ; Subtrahiere Carry und MSB
inc rmp ; Erhöhe den Zähler
rjmp Bin2ToDigita ; Weiter vergleichen/subtrahieren
Bin2ToDigitc:
st z+,rmp ; Speichere das Ergebnis und erhöhe Zeiger
ret ; zurück
kolision:
ori statusreg,0x80
reti

Schmeiß den Quatsch mit int1 raus, pass das Programm leicht an und fertig.

Oder worum geht es hier ?

Gruß Sebastian

Johnny_112
19.12.2005, 13:30
???
@Izaseba

Ich glaube du hast bei dem anderen Thread die User verwechselt. Und zwar Becki mit Johnny_112. (Das war das Thema: Assembler ADC Mega32)

Was ich (Johnny_112) wollte, war einfach ein einfaches Programm mit dem ich die 5 Taster am RN-Control über den ADC auswerten kann. Ohne viel drum rum. So einfach wie möglich, da ich jetzt noch Schwierigkeiten habe alles zu verstehen und erst Anfänger bin.

Werde mir mal das Prgramm vom Asuro anschauen und das Programm versuchen zu verstehen.

Trotzdem Danke!

Ratber
19.12.2005, 14:43
Sorry Johnny112 aber wenn du schon auf andere Topics in anderen Themengruppen hinweist dann ist es eigentlich immer gut dorthin auch gleich eine Brotkrumenspur in Form eines Links zu legen.

Damit vermeidet man ganz einfach Missverständnisse.
Ich habe auch erst hier unter "Atmel AVR Controller" gesucht und die Anderen vermutlich auch.

Also hier der Link zu dem Topic das du angesprochen hast.

Klick mich ! (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=140250&highlight=#140250)

izaseba
19.12.2005, 15:29
:-s

Die Tasten bei Dir sind etwa so angeschlossen, wi beim Asuro, oder, eventuell ohne den int1.

Das ist wohl kein Problem den int1 zu entfernen, Baud und Quarz einzustellen und die m8def.inc abzuändern.

Damit bekommst Du schon angezeigt, welche Werte bei welcher Taste zustande kommen.
Zugegeben, das Programm ist etwas länger, aber 3/4 davon ist bin->ASCII und uart Ausgabe.

Wenn Du noch fragen hast, fragen.



Gruß Sebastian
EDIT:


Ohne viel drum rum




;AD converter Init
ldi tmp,(1<< ADEN) | (1<<ADPS1) | (1<<ADPS2)
out ADCSRA,tmp
ldi tmp,(1<<REFS0) | (1<<MUX2)
out ADMUX,tmp
sbi ADCSRA,ADSC ;Starte ADC

warte:
sbis ADCSRA,ADIF
rjmp warte
;fertig und lese Ergebnis ein
in rBin1L,ADCL
in rBin1H,ADCH


Das wäre dann ohne drum rum.
Ergebnis der Abfrage liegt in rBin1L und rBin1H, die mußt Du Dir noch definieren.
Den ADC Kanal mußt Du auch noch anpassen, ich weiß nicht wo die Tasten angeschlossen sind(schaue ADMUX Register)

Johnny_112
19.12.2005, 15:40
@ Ratber

OK. Das Problem war nur ich wußte nicht wie man einen Link hier im Forum erzeugt. :roll:

Gibt es denn hier im Forum auch so eine Anleitung, wo man die Befehle für das Erzeugen von Links oder Sourcecodes nachlesen kann.
Werde in Zukunft versuchen mich so weit wie möglich an die Forums-Regeln zu halten.

Gruß

@Sebastian

Danke für die Mühe!

Ratber
19.12.2005, 17:37
Nein das ist keine Boardregel aber es ist eben extreem hilfreich wenn man zu einem Hinweis auf ein anderes Topic auch gleich die betreffende Örtlichekit mitliefert.

Schau mal beim schreiben über das Eingabefeld,da sind jedemenge Buttons usw.
Wenn du mit dem Mauscursor drüber fährst dann erscheint in der Zeile direkt über dem Eingabefenster ein kleiner Text der zeigt wie man es anwenden kann.

Da man ja hier seinen Post beliebig editieren kann kannste damit mal rumspielen um ein gefühl dafür zu finden.

Alles Klar ? (Zb. Smilie Creator)

Johnny_112
03.01.2006, 11:41
Das Programm läuft jetzt. :)


Jedoch möchte ich noch wissen, wie kann man den SRAM auslesen (z.B. im Ponyprog2000)? Oder kann ich den SRAM nicht auslesen, da dieser flüchtig ist?
Muss ich dann vielleicht die Werte ins EEPROM speichern. Aber ab welcher Adresse finde ich den EEPROM? Ist das ab Adresse 0x8000?

Es handelt sich um einen ATMEGA32.

.Include "m32def.inc"
.DEF tmp = R16
.DEF lowad = R17
.DEF highad = R18
.EQU wertadlow = 0x60
.EQU wertadhigh = 0x61
ldi tmp, (1<<ADEN)|(1<<ADPS1)|(1<<ADPS2)
out ADCSRA, tmp
ldi tmp, (1<<REFS0)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0)
out ADMUX, tmp
sbi ADCSRA, ADSC

wait:
sbis ADCSRA,ADIF
rjmp wait

in lowad, ADCL
in highad, ADCH
sts wertadlow, lowad
sts wertadhigh, highad

Ratber
03.01.2006, 12:14
wie du schon sagtest,Das Sram ist flüchtig.
Saft Weg = Daten weg.
Beim Softreset bleibt der inhalt aber erhalten.


Muss ich dann vielleicht die Werte ins EEPROM speichern. Aber ab welcher Adresse finde ich den EEPROM? Ist das ab Adresse 0x8000?

Flash,Sram und EEProm sind alle drei Linear Adressiert und getrennt voneinander und über ihre Adressregister erreichbar. (zb. EEprom über EEARH und EEARL)

Schau mal ins Datenblatt da sind alle Informationen dazu drinne (zb. Welche Pausen beim EEProm nach dem Schreibzugriff nötig sind usw.)

Johnny_112
03.01.2006, 23:22
So, nach langem Hin und Her, habe ich nun endlich ein funktionierendes Programm schreiben können. Es liest im Grunde nur die ADC-Werte aus. Aber ich nutze es um herauszufinden in welchem Bereich die Werte für die verschiedenen Tasten liegen.



.Include "m32def.inc"
.DEF tmp = R16
.DEF lowad = R17
.DEF highad = R18

;***************
;Auslesen des ADC
;***************

ldi tmp, (1<<ADEN)|(1<<ADPS1)|(1<<ADPS2)
out ADCSRA, tmp
ldi tmp, (1<<REFS0)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0)
out ADMUX, tmp
sbi ADCSRA, ADSC ;Das Bit ADSC wird gesetzt und der ADC startet.

wait:
sbis ADCSRA,ADIF ;Das ADIF wird abgefragt, ob eine Spannung anliegt.
rjmp wait ;Warteschleife bis Spannung anliegt.

in lowad, ADCL ;Das Low-Byte des ADCs wird ausgelesen.
in highad, ADCH ;Das High-Byte wird ausgelesen.

;******************
;Speichern ins EEPROM
;******************

write1:
sbic EECR,EEWE ;Ist der Schreibzyklus beendet, PC = PC +2
rjmp write1

ldi R19, 0xF0 ;Festlegen der Zieladresse.
ldi R20, 0x00

out EEARH, R20 ;Die Zieladresse des EEPROM wird übertragen.
out EEARL, R19

;Als Nächstes wird das Low-Byte des ADCs abgespeichert.

out EEDR, lowad ;Byte in Zwischenspeicher laden.

;Folgende 2 Befehle sorgen dafür, dass der Wert im Zwischenspeicher nun endgültig in der Zieladresse des EEPROMs abgespeichert wird.

sbi EECR,EEMWE
sbi EECR,EEWE

write2:
sbic EECR,EEWE ;Ist der Schreibzyklus beendet, PC = PC +2
rjmp write2

;Nun wird die nächste Zieladresse festgelegt und das High-Byte des ADCs abgespeichert.

inc R19

out EEARL, R19 ;Es muss nur das Low-Byte geändert werden.
out EEDR, highad

sbi EECR,EEMWE
sbi EECR,EEWE
;Ende :)


Danke für die Hilfe. Nun verstehe ich endlich wie der AD-Wandler arbeitet und der EEPROM beschrieben werden kann. :)

Ratber
04.01.2006, 02:34
Yo,kein Problem

izaseba
04.01.2006, 15:21
Danke für die Hilfe. Nun verstehe ich endlich wie der AD-Wandler arbeitet und der EEPROM beschrieben werden kann.

Es tut gut solche Beiträge zu lesen, weiter so !

Gruß Sebastian

Johnny_112
05.01.2006, 23:46
Muss noch mal den Thread auswühlen. Dachte bis jetzt das Prorgamm würde richtig funktionieren, jedoch, spuckt der AD-Wandler die ganze Zeit Werte aus, auch wenn ich die Tasten nicht drücke.

Das Programm sollte einfach am PA7 des 1.4 RN-Control Board, dort wo 5 Taster über Spannungsteiler angeschlossen sind, die Spannungswerte in die Speicherzellen des EEPROMs sichern. Habe ich irgendwo einen Fehler gemacht. Ich werde nicht wirklich schlau aus den Werten.

Edit:

Hier noch der Programmcode:


.Include "m32def.inc"
.DEF tmp = R16
.DEF lowad = R17
.DEF highad = R18
.EQU wertadlow = 0x60
.EQU wertadhigh = 0x61

ldi tmp, (1<<ADEN)|(1<<ADPS1)|(1<<ADPS2)
out ADCSRA, tmp
ldi tmp,(1<<MUX2)|(1<<MUX1)|(1<<MUX0)
out ADMUX, tmp
sbi ADCSRA, ADSC ;Das Bit ADSC wird gesetzt und der ADC startet.

wait:
sbis ADCSRA,ADIF ;Das ADIF wird abgefragt, ob eine Spannung anliegt.
rjmp wait ;Warteschleife bis Spannung anliegt.

in lowad, ADCL ;Das Low-Byte des ADCs wird ausgelesen.
in highad, ADCH ;Das High-Byte wird ausgelesen.

write1:
sbic EECR,EEWE ;Ist der Schreibzyklus beendet, PC = PC +2
rjmp write1

ldi R19, 0xF0 ;Festlegen der Zieladresse.
ldi R20, 0x00

out EEARH, R20 ;Die Zieladresse des EEPROM wird übertragen.
out EEARL, R19

;Als Nächstes wird das Low-Byte des ADCs abgespeichert.

out EEDR, highad ;Byte in Zwischenspeicher laden.

;Folgende 2 Befehle sorgen dafür, dass der Wert im Zwischenspeicher nun endgültig in der Zieladresse des EEPROMs abgespeichert wird.

sbi EECR,EEMWE
sbi EECR,EEWE

write2:
sbic EECR,EEWE ;Ist der Schreibzyklus beendet, PC = PC +2
rjmp write2

;Nun wird die nächste Zieladresse festgelegt und das High-Byte des ADCs abgespeichert.

inc R19

out EEARL, R19 ;Es muss nur das Low-Byte geändert werden.
out EEDR, lowad

sbi EECR,EEMWE
sbi EECR,EEWE
;Ende


Habe das REFS0 rausgenommen, da ich mit 2,56 V externer Spannung vergleiche.

Doch der ADC erstellt trotzdem noch immer Werte, ohne dass ich auf eine Taste drücke :-k

Johnny_112
09.01.2006, 15:08
Mein Problem besteht immer noch. Ich weiss nicht was ich falsch mache. Habe es schon mehrmals kontrolliert und geändert, jedoch macht der ADC noch immer eine Wandlung ohne Drücken einer Taste. ](*,)

linux_80
09.01.2006, 15:57
Hallo,
jetzt ohne deinen Code auswendig glernt zu haben, aber ein ADC wandelt immer egal was anliegt, irgend ein Wert kommt immer raus.
Bei 0Volt wird der Wert auch gegen 0 gehen.

Johnny_112
09.01.2006, 16:18
Achso,

klingt logisch. Das heißt, wenn ich keine Spannung anlege, dann wird trotzdem die Spannung um 0V gewandelt. Aber dann macht das ja auch keinen Sinn, dass ich die Werte jeweils nur in dieselben EEPROM-Speicherzellen abspeichere. D.h. auch wenn ich eine Taste gedrückt hatte und ein Wert abgespeichert wurde, wird dieser jedoch sofort wieder durch einen Wert von 0V überschrieben. Oder?

linux_80
09.01.2006, 16:48
Genau, Du müsstest evtl. den Wert abfragen ob ein Mindestwert erreicht wurde, oder ob er innerhalb eines Bereiches liegt, falls nicht, wird nix gemacht.

Ratber
10.01.2006, 03:47
Mein Problem besteht immer noch. Ich weiss nicht was ich falsch mache. Habe es schon mehrmals kontrolliert und geändert, jedoch macht der ADC noch immer eine Wandlung ohne Drücken einer Taste. ](*,)


Verstehe nicht ganz.

Sooft du den Wanlder startest sooft bekommst du einen Wert.

Johnny_112
10.01.2006, 11:16
Habe das Prorgamm nun abgeändert. Jedoch erhalte ich trotzdem unlogische Werte.



.Include "m32def.inc"
.DEF tmp = R16
.DEF lowad = R17
.DEF highad = R18
.EQU wertadlow = 0x60
.EQU wertadhigh = 0x61

ldi tmp, (1<<ADEN)|(1<<ADPS1)|(1<<ADPS2)
out ADCSRA, tmp
ldi tmp,(1<<MUX2)|(1<<MUX1)|(1<<MUX0)
out ADMUX, tmp
sbi ADCSRA, ADSC ;Das Bit ADSC wird gesetzt und der ADC startet.

wait:
sbis ADCSRA,ADIF ;Das ADIF wird abgefragt, ob eine Spannung anliegt.
rjmp wait ;Warteschleife bis Spannung anliegt.

in lowad, ADCL ;Das Low-Byte des ADCs wird ausgelesen.
in highad, ADCH ;Das High-Byte wird ausgelesen.

;Überprüfung ob Werte im sinnvollen Bereich sind.
ldi R21,0x32 ;Es wird erst ab Wert 50 in EEPROM geschrieben.
sub R21,lowad
brpl wait

ldi R21,0x02 ;Es wird erst ab Wert 768 nicht mehr in EEPROM geschrieben.
sub R21,highad
brmi wait

write1:
sbic EECR,EEWE ;Ist der Schreibzyklus beendet, PC = PC +2
rjmp write1

ldi R19, 0xF0 ;Festlegen der Zieladresse.
ldi R20, 0x00

out EEARH, R20 ;Die Zieladresse des EEPROM wird übertragen.
out EEARL, R19

;Als Nächstes wird das Low-Byte des ADCs abgespeichert.

out EEDR, highad ;Byte in Zwischenspeicher laden.

;Folgende 2 Befehle sorgen dafür, dass der Wert im Zwischenspeicher nun endgültig in der Zieladresse des EEPROMs abgespeichert wird.

sbi EECR,EEMWE
sbi EECR,EEWE

write2:
sbic EECR,EEWE ;Ist der Schreibzyklus beendet, PC = PC +2
rjmp write2

;Nun wird die nächste Zieladresse festgelegt und das High-Byte des ADCs abgespeichert.

inc R19

out EEARL, R19 ;Es muss nur das Low-Byte geändert werden.
out EEDR, lowad

sbi EECR,EEMWE
sbi EECR,EEWE
;Ende


Ich erhalte Werte, welche nichts mit dem Drücken der Tasten zu tun haben. Z.B. erhalte ich 0x014E, wenn ich Taste 5 drücke, welche jedoch mit dem Multimeter einen ungefähren Wert von 0,32 V liefert. Logischerweise müsste dort doch etwa 0x0080 herauskommen. Auch bei anderen Tasten kommen ganz andere Werte heraus.
Am besten man überträgt das Programm einmal in den 1.4 RN-Control und schaut sich das selbst an.

Wie soll ich es denn dann bewerkstelligen, die verschiedenen Werte der Tasten richtig herauszulesen.

Ratber
10.01.2006, 11:58
Ja wie gesagt,ich hab keine RN-Control aber ich hab mal eben nachgesehen.

Wenn ich richtig gesehen habe Von 5V runter 1x10K und 5x1K.
Zwischen den Widerständen dann 5 Taster als Schließer die alle auf den ADC7 gehen.

Ich sehe aber nirgens einen Pullup oder Pulldown für den offenen AD-Eingang.
Dh. der Eingang kann Antenne spielen was er vermutlich auch tut.

Häng mal an Port A8 nen 10K nach Masse dann sollte der Eingang ohne gedrückte Taste den Wert 0 (plus einige Digits) liefern.

Die zu erwartenden ADC-Werte kannste dir ja schnell neu berechnen.

Johnny_112
10.01.2006, 12:25
Habe es probiert mit dem Widerstand. Bringt jedoch keine Änderung. Ich denke, dass es nicht daran liegt, da es mit dem Demoprogramm in Bascom ja ohne Problem funktioniert.

Stimmt mein Programm denn überhaupt von der Logik?

Zuerst alle Einstellungen am ADC vornehmen.
Dann den ADC starten.
Dann Warten bis ADIF = 1
Dann übertragen der Werte in EEPROM, wenn diese zwischen 50 und 768 sind.

Oder habe ich am ADC was falsches eingestellt?

Die Werte, welche ich erhalte liegen im Schnitt so zwischen 0x0155 und 0x0170 und ich komme so auf eine umgerechnete Spannung von ungefähr 0,9 V.

Ratber
10.01.2006, 12:58
Hmm,lass mal schauen.

Angeschaltet ist
Prescaler auf 64
Mux auf 7
Und Go

Warten auf Adif (Fertig)
Auslesen des Ergebnisses.



Ja,alles soweit ok aber die Referenz solltest du noch definieren.
Also Bit 6 und 7 (Refs0/1) vom Admux-Register

Johnny_112
10.01.2006, 16:50
REFS0 und REFS1 muss ich doch nicht setzen, wenn ich die Referenzspannung an Pin UREF einstelle (Entweder Jumper drauf, dann 2,5V oder nicht, dann 5 V), oder?

Ratber
10.01.2006, 19:37
Nö,du mußt ihm schon sagen welche Quelle er nutzen soll.

Wenn du ihn mit einer Spannung an Aref beaufshclagst und er auf Intern steht dann riskierst du die Interne Quelle zu killen da die bei dieser Einstellung auf den Pin gelegt wird (Der Kondensator Entstört dabei einwenig)


Welche er per Default nutzt weiß ich nichtmal weil ich se immer mit angebe.

Kannst ja mal aus Jux das Register auslesen und Anzeigen.