Forum: Mikrocontroller und Digitale Elektronik PORT-B des ATMEGA168 und auch des ATMEGA48 immer $00


von Electronicfox (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!
Ich hab ein kleines Problem mit 2 µC. Betrifft hierbei den ATMEGA168 und 
auch den ATMEGA48. Bei beiden funktioniert das PORT-B nicht als Ausgang. 
Als Eingang gibts keine Probleme. JTAG hab ich ausgeschlossen, da diese 
AVRs angeblich kein JTAG haben und in den Fuses fand ich meiner Meinung 
nach kein falsches Häkchen ( AVR-Studio4 ). Nun gehe ich davon aus, dass 
der Fehler im Sourcecode liegt. Mit dem Mega32 funktioniert die 
Schaltung übrigens einwandfrei. Im Prinzip sollte das doch einfaches 
Projekt werden, dachte ich zumindest ;)

Schönen Gruß!

von Reinhard R. (reirawb)


Lesenswert?

Ändere mal

> ldi speca, LOW(RAMEND)
> out SPH, speca

in

ldi speca, HIGH(RAMEND)
out SPH, speca

wer weiß, wo sonst Dein Stack hängt :-)

Reinhard

von Steffen H. (avrsteffen)


Lesenswert?

>Ändere mal

>> ldi speca, LOW(RAMEND)
>> out SPH, speca

>in

>ldi speca, HIGH(RAMEND)
>out SPH, speca

Genau das ist mir auch aufgefallen. Ansonsten scheint in deinem 
geposteten Code nichts weiter verdächtig. Das laden und speichern über 
lds und sts in den höheren ( > 3F) Registern wie ADMUX und ADCSRA hast 
du ja schon umgeändert.

Schreib mal, ob der oben genannte Fehler dein Problem mit PortB behoben 
hat. Die Schaltung sieht nämlich interessant aus. Wo hast du die her?

Steffen

von Electronicfox (Gast)


Lesenswert?

habs jetzt geändert:

RESET:

; Stackpointer Init
ldi speca, LOW(RAMEND)
out SPL, speca
ldi speca, HIGH(RAMEND)
out SPH, speca

trotzdem bleibt PORTC 0

von Electronicfox (Gast)


Lesenswert?

Electronicfox schrieb:
> habs jetzt geändert:
>
> RESET:
>
> ; Stackpointer Init
> ldi speca, LOW(RAMEND)
> out SPL, speca
> ldi speca, HIGH(RAMEND)
> out SPH, speca
>
> trotzdem bleibt PORTB 0

von Electronicfox (Gast)


Lesenswert?

Steffen H. schrieb:

> Schreib mal, ob der oben genannte Fehler dein Problem mit PortB behoben
> hat. Die Schaltung sieht nämlich interessant aus. Wo hast du die her?
>
> Steffen

Die Schaltung hatte ich mal mit TTL-ICs und einen ADC-IC aufgebaut, 
welche mir mal so eingefallen. Danach wollte ich wissen obs mit AVRs 
auch geht und tat es auch, zumindest mit ATMEGA32 und ATTINY2313. Da 
aber die 28PINs gemütlicher sind als 40PINs hab ich es mit ATMEGA48 und 
ATMEGA168 probieren wollen.

von Steffen H. (avrsteffen)


Lesenswert?

Mir fällt noch auf:
1
INPUTA:      ; Kanal 0, interne Referenzspannung
2
    ldi     sw, 0b11000000 
3
    STS     ADMUX, sw
4
    ldi     sw2,0b10000000
5
    STS     ADCSRA, sw2
6
  ret
Hier schaltest du den ADC ein. (bit7 in ADCSRA)

Und hier:
1
wait_adc:    ; wenn der ADC fertig ist, wird dieses Bit gelöscht
2
    ldi speca, 0b01000000
3
    STS ADCSRA, speca
4
...
..schaltest du den ADC wieder aus und willst gleichzeitig eine 
Konvertierung starten?

Steffen

von Steffen H. (avrsteffen)


Lesenswert?

Jetzt hab ich mich sogar noch vertan.

Hier meine ich:
1
sample_adc:  ; den ADC starten
2
    ldi speca, 0b01000000
3
    STS ADCSRA, speca

Und hier willst du doch nur das Statusbit abfragen:
1
wait_adc:    ; wenn der ADC fertig ist, wird dieses Bit gelöscht
2
    ldi speca, 0b01000000  ; <- weglassen
3
    STS ADCSRA, speca      ; <- weglassen
4
    lds  ar0, ADCSRA
5
    cp ar0, speca          ; <- cpi ar0, ADSC (ADSC sollte in der m168.inc 
6
    breq wait_adc          ;                   deklariert sein)

Das geht natürlich nicht so!

von BerndB (Gast)


Lesenswert?

Irgendwas ist an dem ADC code aber auch faul:
1
INPUTA:      ; Kanal 0, interne Referenzspannung
2
    ldi     sw, 0b11000000 
3
    STS     ADMUX, sw
4
    ldi     sw2,0b10000000
5
    STS     ADCSRA, sw2

Dies schaltet den ADC ein (bit #7 in ADCSRA)
1
  ret
2
3
sample_adc:  ; den ADC starten
4
    ldi speca, 0b01000000
5
    STS ADCSRA, speca

Hier schaltest Du den ADC wieder aus?! Bit 7 auf null... Und 
gleichzeitig startest Du eine Wandlung. Wird nicht gehen.
1
 
2
wait_adc:    ; wenn der ADC fertig ist, wird dieses Bit gelöscht
3
    ldi speca, 0b01000000
4
    STS ADCSRA, speca
5
    lds  ar0, ADCSRA
6
    cp ar0, speca
7
    breq wait_adc

Warum versuchst Du in der Schleife die Wandlung immer wieder zu starten 
(bit 6 auf 1?)
Und der Vergleich obs fertig ist wird auch schief gehen:
ADCSRA hat ja noch mehr bits, z.B. wird nach der ersten Wandlung das 
Interrupt-Flag-Bit gesetzt sein und der Vergleich dann immer ergeben 
dass die Schleife verlassen werden kann.

Vielleicht eher so:
1
INPUTA:      ; Kanal 0, interne Referenzspannung
2
    ldi     sw, 0b11000000 
3
    STS     ADMUX, sw
4
    ; ADC ein
5
    ldi     sw2,0b10000000
6
    STS     ADCSRA, sw2
7
    ret
8
9
sample_adc:  ; den ADC starten
10
    ; evtl sollte hier auch noch der ADC 
11
    ;clock prescaler (bit 0..2) geaendert werden, je
12
    ; nach deiner Taktfrequenz
13
    ldi speca, 0b11000000
14
    STS ADCSRA, speca
15
wait_adc:    ; wenn der ADC fertig ist, wird dieses Bit gelöscht
16
    lds  ar0, ADCSRA
17
    andi ar0, 0b01000000 ; ausmaskieren vonbit 6 
18
    brne wait_adc ; schleife, wenn immer noch 1

von Steffen H. (avrsteffen)


Lesenswert?

Oh man, ist das schon so spät?

Doch kein cpi verwenden!

Dein polling auf ADSC sollte so ausehen:
1
wait_adc:    ; wenn der ADC fertig ist, wird dieses Bit gelöscht
2
    lds  ar0, ADCSRA
3
    sbrc ar0, ADSC
4
    rjmp wait_adc
5
 
6
; ADC einlesen:
7
    lds     speca, ADCL        ; immer zuerst LOW Byte lesen
8
    lds     specb, ADCH        ; danach das High Byte
9
    ret

von Electronicfox (Gast)


Lesenswert?

Steffen H. schrieb:
> Oh man, ist das schon so spät?
>
> Doch kein cpi verwenden!
>
> Dein polling auf ADSC sollte so ausehen:wait_adc:    ; wenn der ADC fertig ist, 
wird dieses Bit gelöscht
>     lds  ar0, ADCSRA
>     sbrc ar0, ADSC
>     rjmp wait_adc
>
> ; ADC einlesen:
>     lds     speca, ADCL        ; immer zuerst LOW Byte lesen
>     lds     specb, ADCH        ; danach das High Byte
>     ret

Hallo!
Danke, genau das war der fehlende Ansatz.
Nun funktioniert alles wie bei ATMEGA32 ;)
Anscheinend bin ich total durcheinander gekommen mit LDS, STS statt IN 
und OUT

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.