adc an atmega8

1avr2

Neues Mitglied
21. Jan. 2010
28
0
0
Sprachen
hallo ins forum,

kämpfe schon seit längerem mit meinem ad-wandler. board roland walter.
mit bascom funktioniert es einwandfrei, mit assembler leider nicht.

hier der code:


CodeBox ASM

; ad wandler mit atmega 8

;.nolist
.include "m8def.inc"
.list


; led an portb, pb0 als ausgabe
; ddrb = 1

sbi ddrb,pb0

;port c3 auf eingang
cbi ddrc,pc3



;** herr müller kanal int ref spannung 2,56 v, adc0
ldi r16,(0<<refs1)|(1<<refs0)|(0<<mux3)|(0<<mux2)|(0<<mux1)|(0<<mux0)
out admux,r16

ldi r16,(1<<aden)|(1<<adfr)|(1<<adps2)|(1<<adps1)|(1<<adps0)
out adcsra,r16

;*** hauptprogramm

main_loop:

rcall convert

rjmp main_loop

;ldi r16,(1<<aden)|(1<<adsc)|(1<<adfr)|(1<<adps2)|(1<<adps1)|(1<<adps0)
out adcsra,r16
;adsc wird nicht gesetzt im simulator ????

;warte:

convert:

sbi adcsra,adsc ; start conversion
warte:
sbic adcsra,adsc ; warte bis adc fertig
rjmp warte ; skip if bit in i/o is cleard
in r16,adch ; lese ergebnis




cpi r16,128
brlo convert_led_an

sbi portb,pb0
rjmp main_loop



convert_led_an:
cbi portb, pb0
rjmp main_loop
 
Hi
Wer bringt euch bloß diese grausige Art der Programmierung bei ? Es ist gut, wenn du Kommentare in dein Listing schreibst, aber um dieses Lesbar zu halten, git's ein paar Tricks. Einer davon ist das Einrücken von Codezeilen. Ein weiterer das Absetzen einzelner Programmroutinen. Also:
Code:
;*************************************************************
;* die folgende Schreibweise ist nicht unbedingt mein Ding, aber die                                 *
;* Programmierer schwören darauf und weisen eine Zuweisung ala 0bxxxxxxxx	             *
;* ab. Hinter REFSO,ADLAR, MUX2 und MUX0 stehen konstante Werte, die die	             *
;* Bitstelle beschreiben. Ich bevorzuge für mich einfach 0bxxxxxxxx			             *
;* Hier mal die Beschreibung der Bits im Steuerregister ADMUX                                        *
;* Bit 0- Bit 3	Kanal		Mux3 Mux2 Mux1 Mux0                                                 *
;*				0     0    0    0	= Kanal 0  = Port C0                                              *
;*				0     0    0    1	= Kanal 1	= Port C1                                              *
;*				0     0    1    0	= Kanal 2	= Port C2                                              *
;*				0     0    1    1	= Kanal 3	= Port C3		  			             *
;*				0     1    0    0	= Kanal 4	= Port C4		  			             *
;*				0     1    0    1	= Kanal 5 	= Port C5		  			             *
;* Bit 4 n.belegt										  		             *
;* Bit 5 Ausr. 0 = rechts (000000xx xxxxxxxx) 1 = links (xxxxxxxx xx000000)             *
;* Bit 6 und 7 Auswahl Referenzspannung	Refs1  Refs0					             *
;*					  0      0	= externe Referenz			  		             *
;*					  0      1	= Interne Referenz AVCC			  	             *
;*					  1      0	= n.Benutzt				  		              *
;*					  1      1	= interne Referenz 2,56 V		  		              *
;*												  			               *
;* und das Register mit den Bits 	Bit 0 = ADPS0	= Vorteiler 000 =2    	               *
;*					Bit 1 = ADPS1   = 001-111 = 2,4,8,16,32,64 und 128              *
;*					Bit 2 = ADPS2 						  		                *
;*					Bit 3 = ADIE =ADC Interrupt Enable 1 Interrupt bei ADIF             * 
;*					BIt 4 = ADIF =ADC Interrupt Flag   1 bei Ende Messung              *
;*					Bit 5 = ADFR =ADC Free Running     1 aut.Start n. Wandl.           *
;*					Bit 6 = ADSC =ADC Start Conversion 1 =Start Wandl.0=Ende    * 
;*					Bit 7 = ADEN =ADC Enable 1 = ADC ein			  		* 
;*																	*
;* Ergebnis 10 Bit steht in ADCH (High) und ADCL (Low)						        *
;********************************************************************
Init_ADC:			; Analogkanal initialisieren 
	;LDI	a0, 0b01100000  so würd ich's machen

		
		ldi     a0, (1<<REFS0) | (1<<ADLAR)
		out     ADMUX, a0    
		ldi     a0, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0)   
		out     ADCSRA, a0
	
RET

;---------------------------------------------------------------------------
Soweit die Initialisierung. Der Aufruf ist ebenfalls nicht so kompliziert.
Code:
;****************** ADC Interrupt Vector Address ******************
Read_Analog:	
		Push	Temp_Reg
		in      Temp_Reg, ADCL			; immer zuerst LOW Byte lesen
    	        in      Temp_Reg, ADCH			; danach das mittlerweile gesperrte High Byte
	 	STS		Poti_Wert,Temp_Reg   
		POP		Temp_Reg 
RETI    
;---------------------------------------------------------------------------
Ich will nicht behaupten, das dies der Weisheit letzter Schluß ist, aber so lassen sich Programme lesen. Bei diesem Programm lese ich Kanal 0. Du mußt nur entsprechend anpassen, was aber durch die Kommentare kein Problem sein sollte. Es sollte selbstverständlich sein, das die Initialisierung vor der Programmschleife aufgerufen werden muß und nur 1mal durchlaufen wird.
Gruß oldmax
 
Hallo zusammen,

Wer bringt euch bloß diese grausige Art der Programmierung bei ? Es ist gut, wenn du Kommentare in dein Listing schreibst, aber um dieses Lesbar zu halten, git's ein paar Tricks. Einer davon ist das Einrücken von Codezeilen. Ein weiterer das Absetzen einzelner Programmroutinen.
ich hab den Code mal mit
HTML:
[highlight=ASM]
....
assemblerprogramm
...
[/highlight]
formatiert. Wird zwar etwas lesbarer aber nochnicht wirklich schön.
Spaghetticode ist einfach schwer zu durchschauen ... :rolleyes:

Gruß
Dino
 
Hallo 1avr2,

in main_loop rufst du convert mit rcall auf. Von convert springst du mit rjmp zurück zu main_loop (Achtung: zwei Stellen). Du musst mit ret zurückspringen und am Programmanfang sicherstellen, dass der Stackpointer auf RAMEND steht.

oder

rcall durch rjmp ersetzen (dann macht main_loop aber kein Sinn mehr, bzw. ist dann kein schöner Programmierstil. In main_loop soll ja sicher noch einiges mehr rein, wenn du das Programm mal erweiterst)

Grüße,
Dirk
 
ad_wandler

Code:
; ad wandler mit atmega 8

;.nolist
.include "m8def.inc"
.list


; led an portb, pb0 als ausgabe
; ddrb = 1

sbi ddrb,pb0

;port c3 auf eingang
cbi ddrc,pc3



;** herr müller kanal int ref spannung 2,56 v, adc0
ldi r16,(0<<refs1)|(1<<refs0)|(0<<mux3)|(0<<mux2)|(0<<mux1)|(0<<mux0)
out admux,r16

ldi r16,(1<<aden)|(1<<adfr)|(1<<adps2)|(1<<adps1)|(1<<adps0)
out adcsra,r16



convert:

sbi adcsra,adsc            ; start conversion
warte:
sbic adcsra,adsc        ; warte bis adc fertig
rjmp warte                ; skip if bit in i/o is cleard
in r16,adch                ; lese ergebnis




cpi r16,128
brlo convert_led_an

sbi portb,pb0
rjmp convert



convert_led_an:
cbi portb, pb0
rjmp convert
; mit der antwort von oldmax kann ich noch nichts anfangen.
;diese version ohne rcall und return funktioniert leider immer noch nicht
;möchte eigentlich nur einen ad_wandler der eine led ein bzw ausschaltet
;dürfte eigentlich nicht so schwer sein.
;wo liegt denn jetzt noch der fehler
;gruss bernhard
 
Hallo,

nutze doch bitte den Code-Button oder die Highlight-Funktion, damit der Code besser vom Text im Beitrag getrennt wird und besser zu lesen ist.

Nun zu deinem Programm:

Du hast den FreerunningMode eingestellt Bit ADFR. Das Bit ADSC (StartConversion) bleibt hier immer auf "1", die Resultregister werden permanent aktualisiert. Du bleibst also in deiner Warte-Schleife hängen.

Dann wertest du ADCH aus, das Ergebnis befindet sich aber rechtsbündig in ADCH und ADCL. Du bist also in ADCH immer unter 128. Wenn du nur 8bit nutzen möchtest, die untersten beiden Bits vom Ergebnis also vernachlässigen möchtest, kannst du das Ergebnis linksbündig setzen, dann ist das 8bit Ergebnis in ADCH. Linksbündig stellst du ein, indem du das Bit ADLAR im Register ADMUX setzt.

Grüße,
Dirk
 
konfiguration

hallo dirk,
vielen dank fuer deine muehe, welchen code button bzw highlight option
muss man benutzen? (erst # dann paste ??)
hab nur mal die konfiguration geschrieben, weist die irgendwelche
fehler bzw unstimmigkeiten auf ?
gruss bernhard.


Code:
;            einfacher ad wandler
;	mit atmega 8
; 	vcc ueber poti an adc0=pin23
;           led an portb0=pin14
;           poti > 50 prozent led an, sonst aus

.include "m8def.inc"
.list

;--------------  konfiguration  -------------

;   portb0 auf ausgabe mit ddrb pb0=1

	sbi ddrb,pb0
	
; portc0 auf eingang

	cbi ddrc,pc0

;  konfig admux
;  bit 0-2=0 -> adc0
;  bit 5=links justiert
;  bit 4 keine ahnung
;  bit 6-7 -> 10 = messspannung vcc

 	ldi r16, 0b01100000
	out admux,r16

;  konfig adcsra
;  bit 7 aden=1
;  bit 6 start=1
;  bit 5-3=isr bzw free_run=0	
;  bit 2-0=prescale 010=quartz/4

	ldi r16,0b11000010
	out adcsra,r16
 
formatierung

ich hatte meinen text eigentlich eingerueckt, aber mit copy und paste
ging das verloren. wie kann man den code den farblich kennzeichnen bzw
zeilennummern angeben?
 
Hallo Bernhard,

ich sehe nun keinen Fehler mehr.

Den Teil ab "convert" hast du ja so gelassen?
Am Pin AREF liegt keine externe Spannung an, bzw. dort ist ein C angeschlossen?
Der ADC Prescaler ist so gewählt, dass der ADC eine Frequenz zwischen 50kHz und 1MHz erhält?

Ich habe jetzt keine Ideen mehr. Kannst du irgendwie prüfen, ob der AVR auch wirklich läuft (loop: LED an, pause, LED aus, pause).

@Dino: kannst du hier mal schauen, vielleicht übersehe ich ja was.

Die Schreibweise mit Bit-Namen läßt sich besser lesen. Du initialisierst nun direkt mit binärer Darstellung, so muss man in das Datenblatt schauen, ob die Bitpositionen stimmen. Bleib bei deiner ersten Version, das läßt sich gut lesen!

Code-Tags:
  • Entweder du drückst den # Button und fügst dann zwischen die Tags deinen Code ein
  • oder du fügst deinen Code ein und makierst ihn, danach drückst du den # Button
Code-Highlighting geht so:
[noparse]


CodeBox asm

; hier dein Assembler-Code

[/noparse]


Dirk
 
Hallo,

@Dino: kannst du hier mal schauen, vielleicht übersehe ich ja was.

Die Schreibweise mit Bit-Namen läßt sich besser lesen. Du initialisierst nun direkt mit binärer Darstellung, so muss man in das Datenblatt schauen, ob die Bitpositionen stimmen. Bleib bei deiner ersten Version, das läßt sich gut lesen!
Im Moment kämpfe ich mit ner Erkältung. Für logisch schlüssige Gedanken ist
es glaube ich noch etwas früh :eek: :eek: Mal sehen wie es morgen aussieht ...
Wundert euch nicht wenn ich mal mitten in der Nacht poste weil ich grad
nicht mehr schlafen kann :rolleyes: Der Rhythmus ist total ausgehebelt. Und
wenn man irgendwas mach kommt man am besten wieder zum Schlafen.

Zu den Bitnamen ... Ich initialisiere auch immer in Binärer Darstellung schreibe
aber immer ein paar Bemerkungen mit den Bitnamen, Positionen und Funktionen
dabei.

Gruß
Dino
 
Off topic:

aber trotzdem mal gute Besserung Dino :nurse:

Dirk
Im Moment kämpfe ich mit ner Erkältung. Für logisch schlüssige Gedanken ist
es glaube ich noch etwas früh :eek: :eek: Mal sehen wie es morgen aussieht ...
Wundert euch nicht wenn ich mal mitten in der Nacht poste weil ich grad
nicht mehr schlafen kann :rolleyes: Der Rhythmus ist total ausgehebelt.
 
adc atmega8

hallo dirk,

meine schaltung funktioniert jetzt.
vielen dank ins forum und an dich. werde mich in zukunft bemuehen,
den text besser zu formatieren.

gruss bernhard.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)