PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Assembler ADC Mega32



Johnny_112
30.11.2005, 21:35
Hallo,

ich habe mir ein RN-Control Mega32 zugelegt. Ich wollte den Controller in Assembler programmieren und habe mir auch schon das Tutorial durchgelesen. Jedoch werde ich daraus nicht richtig schlau. Das Problem ist, ich weiß nicht was ich in den Header schreiben soll (Include, Device ,...). In Assembler habe ich bis jetzt nur mit einem 8085 programmiert.

Was kommt da jetzt alles vor das eigentliche Programm? Und soll ich am Besten das Ende des Programms mit einer Endlosschleife versehen?

Vielen Dank für die Hilfe im voraus!

(SuFu habe ich schon benutzt)

Johnny_112
07.12.2005, 00:09
So, nach mehreren Stunden und Versuchen, habe ich das Board endlich zum Laufen gekriegt. Nur habe ich ein Verständnisproblem.

DDRB : Damit setze ich fest ob Eingang oder Ausgang am Port. Richtig?

PortB: Damit sage ich ob zB. LED an Bitstelle1 leuchten soll, wenn ich 0x01 setze. Richtig?

PINB : Zum Einlesen des Port B. Richtig? Oder wozu dient dieser?

Nur habe ich das Problem, wenn ich eingebe:

ldi R16, 0xFF
out DDRC, R16
ldi R16, 0x00
out PortC, r16

dass dann alle LEDs leuchten. Ich dachte die dürften nur leuchten wenn ich den PortC mit 0xFF beschreibe.

IM AVRStudio wird mir angezeigt, dass nur DDRC 11111111 ist. PORTC und PINC sind alle 0.

Wieso leuchten alle LEDs, wenn ich PORTC mit 0x00 beschreibe??? :-s

askazo
07.12.2005, 07:36
Soweit ist alles richtig.
Dass die LEDs leuchten, wenn Du den Port mit 0x00 beschreibst, leigt daran, dass die LEDs mit der Annode über einen Vorwiderstand fest an +5V liegen und die Kathode am Port angeschlossen ist. Somit schaltest Du mit '0' die LED ein und mit '1' wieder aus. Das ist eine übliche Praxis bei Mikrocontrollern.

askazo

Johnny_112
07.12.2005, 10:34
Ok. Danke!

Aber hat das dann was mit den Pull-ups zu tun, dass die LEDs bei 0 leuchten?

askazo
07.12.2005, 10:44
Nein, mit den Pull-Ups hat das nichts zu tun. Wenn die Ports auf 0 stehen, haben sie quasi Masse-Potential. Der Strom fließt also von +5V über den Vorwiderstand und die LED und dann durch den Mikrocontroller nach Masse.

Johnny_112
07.12.2005, 10:56
Habs verstanden.
Nur habe ich jetzt ein anderes Problem. Wie bewerkstellige ich, dass ich die 5 Taster vom Board nehmen kann um die LEDs damit zu schalten. Mein Problem fängt schon damit an, dass ich nicht weiss wie ich das in Assembler deklarieren kann.
Sind die 5 Taster alle auf einer einzigen I/O-Leitung? Ich kann nämlich eine Spannung von 0,32V vom Taster 5 mit jeweils Schritten von 0,32 V bis Taster 1 am PA7 messen, wenn ich auf die jeweiligen Tasten drücke.

askazo
07.12.2005, 11:17
Schau Dir am besten mal in Ruhe den Schaltplan (https://www.roboternetz.de/wissen/images/c/c6/Rncontrol1.4schaltplan.gif) an.
Die Taster steuern einen Spannungsteiler, der vom ADC7 (Sonderfunktion von PA7) ausgewertet werden kann. Du musst Dich also ein wenig mit der Funktion des ADCs beschäftigen, um die Taster auswerten zu können.
Ich bin leider nicht so fit in Assembler (programmiere in C) von daher kann ich Dir da leider nicht allzuviel weiterhelfen.

askazo

Johnny_112
07.12.2005, 11:24
Na dann, werde ich mal mein Glück versuchen. Danke für die Hilfe!

becki
08.12.2005, 13:00
Wie kann man denn mit einem Atmel AVR (mega8) einen strom messen? geht um eine wiederstandskette, an der schalter sind und alles an einem I/O pin hängt. wer kann mir da mal ein paar zeilen assembler zu geben?
MfG becki

izaseba
08.12.2005, 17:53
Was willst Du jetzt messen? Strom oder Spannung ?

Gruß Sebastian

becki
08.12.2005, 18:15
ähm, spannung, sry, war mein fehler. aber sonst konntest du mir schon folgen?

izaseba
08.12.2005, 18:30
. aber sonst konntest du mir schon folgen?


Deswegen hab ich jetzt gefragt...
Du meinst also ein Widerstandsnetzwerk, der an einem ADC Port hängt, wo die Taster zwischen den Widerständen hängen?
Schau mal hier (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10101&highlight=asuro+assembler)
habe ich ein Programm in Assembler für den Asuro geschrieben.
Damit werden die Taster am Asuro ausgelesen und über UART die ADC Werte ausgegeben.
Ich denke es ist sowas, was Du suchst, bei Unklarheiten einfachmal fragen.

Gruß Sebastian

becki
08.12.2005, 18:41
ioch würde nur noch gerne wissen, wie man den ADC getzt initialisieren muss. kann ja aml sien, dass die schlater an einem anderem port, etc hängen. das hätte ich gerne nochmla kurz erklärt. ansonsten nützt mir der code denke ich schon.

08.12.2005, 21:23
Der Code beinhaltet vielleicht etwas mehr, als Du haben wolltest, schaue im Datenblatt zu Mega8 mach dem Register ADMUX vor allem die MUX Bits, die sind für den Kanal verantwortlich.
Alles nötige wird in der reset Routine unter AD convertet init eingestellt...

Mit minimalen Anpassungen wird das Programm auch bei Dir laufen und die ADC werte über UART anzeigen.

Gruß Sebastian

izaseba
08.12.2005, 21:32
Der Gast darüber, das bin ich :oops:

Gruß Sebastian

becki
09.12.2005, 17:57
ok, das wollte ich wissen. da werde ich nun mal schauen. thx

Johnny_112
13.12.2005, 23:00
Hallo, ich hätte da doch meine Schwierigkeiten mit dem ADC. Ich möchte gerne mit einer der 5 Tasten eine LED ein-oder ausschalten. Habe mich jetzt durch das Forum gekämpft und das Datenblatt studiert. Ist mir jedoch alles ein wenig zu kompliziert und zu viele Details, bin eben Anfänger.

Kann mir keiner einen guten knappen Code in Assembler (nur das nötigste, wie ADC auswerten und LED zum Leuchten bringen) geben, wo ich mit Hilfe der am Board befindlichen Tasten die LEDs an-und auschalten kann?

Danke!

Johnny_112
14.12.2005, 20:43
Nochmal. Ich möchte gerne mit den Tasten am Board die LEDs an/ausschalten in Assembler.

Weiß denn keiner wie? :(

Vogon
18.12.2005, 23:55
Eventuell so wie beim ASURO ?
Mit "Suchen" findest du hier auch die die asuro.c, asuro.h

Hier ist auch eine neue Version:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=140675#140675

Die Function PollSwitch, StartSwitch, StopSwitch und Interrupt1 sind für die Bearbeitung der Taster zuständig. Das sollte doch als Beispiel für deinen ASM-Code gehen.

https://www.roboternetz.de/phpBB2/files/wandler_.jpg

Johnny_112
19.12.2005, 12:19
Ich werde mir das mal ansehen und testen.

Vielen Dank!

Johnny_112
10.01.2006, 22:00
Ich habe nun ein Programm erstellt, welches den Wert des ADCs in den EEPROM abspeichert. Jedoch erhalte ich die ganze Zeit ungefähr die gleichen Werte, ohne dass ich irgend eine Taste drücke. Diese Werte sind im Bereich 0x0150 bis 0x0180. Wenn ich eine Taste drücke kriege ich auch nur einen Wert dazwischen geliefert. Wo ist der Fehler im Programm?
Wollte eigentlich nur den jeweiligen Wert in den EEPROM speichern, wenn eine Taste gedrückt wird.



.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,(0<<REFS0)|(0<<REFS1)|(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


Als Referenzspannung habe ich AREF mit Jumper angegeben. (Also 2,56 V.)
Wäre auch gut, wenn jemand das Programm mal in seinem RN-Control testen könnte und mir sagen kann, ob dort die gleichen Werte gespeichert werden.

Danke!

linux_80
11.01.2006, 00:03
Hallo,
wenn du die RN-Control hast, solltes Du auch die CD dazu bekommen haben, da ist auch ein C-Beispiel dabei, Dateiname (tastenled.bas ja, stimt schon so !) das lässt sich leicht auf ASM anwenden.

Der Jumper URef sollte gesteckt sein, und als Referenz nur so:
ADMUX = (1<<REFS0)|...


Der Sprung bei den Abfragen zu wait: haut irgendwie nicht hin, denn da wird nix mehr neu gemessen, nur überprüft ob gemessen wurde, also bleibt der Wert immer dergleiche.

Johnny_112
11.01.2006, 12:03
So, habe die Bedingungen verbessert. Nun sollte so zwischen AD-Wert 0x6E und 0x82 die LED1 leuchten. Jedoch leuchtet diese, manchmal ohne Taste 5 gedrückt zu haben, oder sogar wenn ich Taste 4 oder Taste 3 drücke.
Die Werte des ADCs sind ohne irgendeine Taste gedrückt zu haben, so um 0x0140 bis 0x0180. Das sind umgerechnet so 0,9V. Jedoch sollte doch 0V anliegen, wenn keine Taste gedrückt ist?



.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 ;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.
u1:
ldi R21,0x00
sub R21,highad
brmi u2
ldi R21,0x14 ;Es wird 20 vom gesamten ADC-Wert abgezogen.
sub R21,lowad
brmi write1

u2:
ldi R21,0x02 ;Es wird erst ab Wert 768 nicht mehr in EEPROM geschrieben.
sub R21,highad
brpl write1
rjmp wait ;Falls Werte nicht zwischen 20 und 768 -->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

;Abfrage Bereich 110 bis 130
ldi R21,0x00
sub R21,highad
brmi ende
ldi R21,0x5A
sub R21,lowad
brpl ende
ldi R21,0x7D
sub R21,lowad
brmi ende
;LED1 leuchtet bei Taste 5
led1:
ldi R22,0x01
out DDRC,R22
ldi R22,0b11111110
out PORTC,R22
ende:
;Ende


Ich verstehe nicht, wo mein Fehler liegt und wo ich ihn suchen soll.

linux_80
11.01.2006, 15:49
In dem Programm wird aber nur einmal am Anfag der AD-Wandler angeworfen, also nur einmal überhaupt gemessen, danach wird immer mit dem selben Wert gearbeitet (oder irgedwas zufälliges), weil das Label wait: nach dem Start des AD-Wandlers steht !

Johnny_112
11.01.2006, 16:29
Habe das nun geändert und (wait:) übder das (ADCSRA,ADSC) geschrieben. Jedoch macht das Programm noch immer die gleichen Probleme.

Das mit dem (wait:) erklärt jedoch nicht wieso ich immer irgendeine Spannung am ADC liegen habe, wenn keine Taste gedrückt wurde.

Edit: Habe das Problem gefunden.

Es lag nicht direkt am Programm. Habe die ganze Zeit beim Versuchen den ISP-Dongle vom Computer dran gehabt. D.h. es ist irgendwie eine Spannungsschwankung entstanden. Diesen gleichen Effekt, habe ich auch wenn ich mit dem Multimeter am PA7 messe und beim Abnehmen des Messfühlers geht die LED auch an.

Hätte nicht gedacht, dass der ADC so empfindlich auf Spannungsschwankungen und Kriechströme reagiert.

Das einzige was mich noch stört, ist dass es ab und zu vorkommt, dass die LED angeht ohne irgendwas zu machen. Aber das liegt vielleicht daran, dass die Grenze zu nahe bei 0 liegt.

Edit1: Die LED geht auch manchmal an, wenn ich das Board in der Hand halte.

Johnny_112
18.01.2006, 18:23
Das Problem ist auch mit der Stromversorgung über Netzteil noch immer da. Scheint doch nicht die Lösung zu sein.

Weiß denn keiner irgendwie weiter. Komm einfach nicht dahinter.

Wenn ich ein Programm in C schreibe, dann geht das Schalten der LEDs über die Auswertung der Tasten mit dem ADC ohne Problem. Das gleiche mit Bascom.

Dann kann es doch wohl nur am Programm selbst liegen.