1V am Ausgangsport des Atmega8

OP #1974983
Lesenswert?

Hallo zusammen,

ich versuche mich seit neuerstem in der Programmierung von 
Mikrocontrollern.
Grobe Grundkenntnisse habe ich auf dieser Webseite / in diesem Forum 
erlangt und lerne ständig dazu.
Ich finde diese Seite echt super.

Nun zu meinem Problem:

Ich habe eine Grundschaltung mit dem Atmega8 aufgebaut, die mit 
Reedschaltern an den Eingangsports beschaltet ist (interne Pullups 
wurden aktiviert und die Richtungsregister gesetzt). An den 
Ausgangsports hängen zwei BCD-Decoder, die mir auf 7-Segment-Anzeigen 
Zahlen ausgeben.
Da das Assembler-Programm auf dem AVR-Studio eigentlich richtig läuft, 
aber die Zahlen auf den Anzeigen mit der Theorie nicht übereinstimmen, 
hab ich am Mikrocontroller mal nachgemessen.

Falls kein Reedschalter betätigt ist, dann sollte an den Ausgängen 
eigentlich auch kein 5V-Signal anliegen (BCD-Code: 0000).
Leider messe ich an einem Ausgangsport ein komisches 1V-Signal, auch 
wenn die BCD-Decoder entfernt sind.

An was kann das liegen?
Ist der Controller hinüber?

Herzlichen Dank schon mal für Eure Hilfe.

Gruß,
Russell
Persönliche Seite #1974988
Lesenswert?

Wilhelm Bachinger schrieb:
> Falls kein Reedschalter betätigt ist, dann sollte an den Ausgängen
> eigentlich auch kein 5V-Signal anliegen (BCD-Code: 0000).
> Leider messe ich an einem Ausgangsport ein komisches 1V-Signal, auch
> wenn die BCD-Decoder entfernt sind.
>
> An was kann das liegen?
> Ist der Controller hinüber?

Ich würde eher nochmal kontrollieren, ob die Ausgänge wirklich richtig 
gesetzt sind. Die 1V am Ausgang klingen eher nach einem floatenden Pin.
OP #1975013
Lesenswert?

Hallo Roland,

so sind meine Ausgänge und Eingänge geschalten:


ldi r16, 0xFF
out DDRB, r16     ; Alle Pins am Port B als Ausgang
                  ; Hier sitzen die 2 BCD-Decoder

ldi r16, 0x00
out DDRD, r16     ; Alle Pins am Port D als Eingang
                  ; Hier sind die Reedschalter angeschlossen

ldi r16, 0b11101111
out DDRC, r16     ; Pin 4 am Port C als Eingang
                  ; Hier ist noch ein Reedschalter angeschlossen

ldi r16, 0xFF
out PORTD, r16    ; Aktivieren der Pullup-Widerstände an Port D

ldi r16, 0b00010000
out PORTC, r16    ; Aktivieren des Pullup-Widerstände an Pin 4 Port C


Sollte doch passen oder?

Gruß,
Russell
Gast #1975028
Lesenswert?

Hallo,

wenn du einen Controller mit JTAG-Interface hast, dann musst du es über 
die Fuses abschalten (ist Standardmäßig eingeschaltet). Ansonsten 
funktionieren die entsprechenden Pins nicht als IO. Vielleicht liegt es 
daran.
Gast #1975114
Lesenswert?

wie misst du denn?

Hoffentlich per Oszilloskop! Wahrscheinlich ist der Pin mal High und mal 
Low.
Um zu schauen, ob der Controller richtig läuft, kannst du einen Pin auf 
High schalten und per LED oder besser Oszi messen.

µC-Läuft, Pin auf High.

Ist der Controller programmiert? Welche fuses?
OP #1975149
Lesenswert?

Hallo Timo,

ich messe leider nur mit einem Multimeter.
Du hast recht, vielleicht ist das die Effektivspannung die ich messe.

Du meinst ich soll ein ganz simples Programm zur Ansteuerung dieses 
Ausganges schreiben (auf High setzen) und dann nochmal messen?

Der Mikrocontroller ist zur Zeit programmiert.
Mit Fuses hab ich bis heutzutage noch nichts gemacht. Ich geh davon aus, 
dass diese im Grundzustand gesetzt sind.
Kann man die Fuses ungewollt verändern?

Da hab ich noch eine grundsätzliche Frage.

Was passiert eigentlich, wenn ich z.B. beim Port C einen Eingang und 6 
Ausgänge konfiguriert habe und ich dann ein Register auf dem Port 
ausgebe (out portc, r16). Was passiert da mit meinem Eingang?

Danke nochmal.

Gruß,
Russell
Gast #1975168
Lesenswert?

Hi

>Was passiert eigentlich, wenn ich z.B. beim Port C einen Eingang und 6
>Ausgänge konfiguriert habe und ich dann ein Register auf dem Port
>ausgebe (out portc, r16). Was passiert da mit meinem Eingang?

Du schaltesst u.U. den Pull-Up ab. Lässt sich aber leicht vermeiden:
1
    ....
2
    ori r16,1<<PC4     ;PC4 immer 1
3
    out PortC, r16

MfG Spess
OP #1975195
Lesenswert?

Hallo Spess,

muss nochmal kurz nachfragen.

    ....
    ori r16,1<<PC4     ;PC4 immer 1
    out PortC, r16

Ich setze durch ein ODER den Wert auf PIN4 immer auf eins.
1<<PC4 bedeutet, dass ich nur den PIN4 auf High setze?
Mit 0<<PC4 würde ich ihn dann auf Low setzen? (bringt beim ODER 
natürlich nichts)

Danke.

Gruß,
Russell
Gast #1975223
Lesenswert?

Hi

>Ich setze durch ein ODER den Wert auf PIN4 immer auf eins.
>1<<PC4 bedeutet, dass ich nur den PIN4 auf High setze?
>Mit 0<<PC4 würde ich ihn dann auf Low setzen? (bringt beim ODER
>natürlich nichts)

Nein. Das Pin ist ja Eingang. Und damit wird beim Schreiben einer 1 in 
das Port-Bit der interne Pull-Up eingeschaltet bzw. das Ausschalten 
verhindert.

MfG Spess
OP #1975239
Lesenswert?

Okay jetzt hab ich es kapiert. Hoffe ich zumindest...

Am Anfang definiere ich meine Eingänge, Ausgänge und Pullups.
Da ich aber durch ein am Port ausgegebenes Register den Pullup eines 
Eingangspins wieder deaktivieren könnte, schalte ich das betroffene Bit 
im Register dauerhaft auf High.

Richtig? :-)

Danke nochmal.

Gruß,
Russell
Gast #1975495
Lesenswert?

Hi

>Was ist ein STK500?

Ein Entwicklungsboard von Atmel. Also hast du anscheinend keins. Mir 
wären dann allerdings ein paar Fehlermöglichkeiten eingefallen.

Gut, dann stelle erst mal dein Programm ein.

MfG Spess
Gast #1975504
Lesenswert?

Kleiner Tipp, vielleicht ist es ja das:

Beim Mega8 wird eine Hälfte des PortC aus AVCC versorgt, das ist 
eigentlich die Versorgungsspannung des AD-Wandlers.
Vielleicht ist ja bei dir AVCC nicht angeschlossen?!?
OP #1975654
Lesenswert?

Hallo Wolfgang,

einen Lötfehler kann ich auschließen.

Der besagte Portausgang PortB Pin6 geht direkt zu einem 
BCD-Decoder-Eingang.
Hab den BCD-Decoder auch schon entfernt und gemessen.
Die Strecke vom Atmega8 zum BCD-Decoder hab ich schon nach Fehlern 
durchsucht.

Gruß,
Russell
OP #1976755
Lesenswert?

Hallo Spess,

wie versprochen stelle ich mein Programm mal ein.

Kurze Erklärung was das Programm machen soll:

An den Eingängen sitzen 9 Reedschalter, denen je ein Zahlenwert 
zugeordnet ist. Reedschalter 1 hat den Zahlenwert 1, Reedschalter 2 hat 
den Zahlenwert 2, usw.
Je nachdem welche Reedschalter betätigt sind (bzw. nicht betätigt sind), 
soll mir meine 7-Segment-Anzeige die Summe anzeigen. Sind z.B. 
Reedschalter 9 und 6 offen, dann soll die Zahl 15 angezeigt werden.

Bei dem Zahlenwert 0 soll an PortB Pin 7 High sein, um mein astabile 
Kippstufe anzusteuern. Diese schaltet meine Anzeigen dann aus und ein.

Das Programm ist wahrscheinlich sehr umständlich, aber jeder fängt mal 
klein an ;-)



.include "m8def.inc"


         ldi r16, 0xFF
         out DDRB, r16   ; Alle Pins am Port B als Ausgang konfigurieren
                         ; Hier sitzen zwei BCD-Decoder
         ldi r16, 0x00
         out DDRD, r16   ; Alle Pins am Port D als Eingang konfigurieren
                         ; Hier sitzen 8 Reedschalter

         ldi r16, 0b11101111
         out DDRC, r16   ; Pin 4 am Port C als Eingang konfigurieren
                         ; Hier sitzt der 9. Reedschalter

         ldi r16, 0xFF    ; An allen Pins vom Port D die
         out PORTD, r16   ; Pullup-Widerstände aktivieren.

          ldi r16, 0b00010000   ; Pin 4 vom Port C den Pullup-Widerstand
         out PORTC, r16         ; aktivieren.


          ldi r22, 0b00000000   ; Register 22 auf 0 setzen



;****************Zahlen addieren***********************

loop1:

      ldi r17, 0b00000000      ; Register 17 auf 0 setzen
      ldi r19, 0b00000001      ; Register 19 auf Zahl 1 setzen
      sbis PIND, 0             ; Addiere r19 nicht zu r17, wenn
      add r17, r19             ; am Eingang 0 des Ports D High ist
                               ; (Reedschalter 1 offen)

      ldi r19, 0b00000010       ; Register 19 auf Zahl 2 setzen
      sbis PIND, 1                ; Addiere r19 nicht zu r17, wenn
      add r17, r19              ; am Eingang 1 des Ports D High ist
                                ;(Reedschalter 2 offen)


     ldi r19, 0b00000011       ; usw.
     sbis PIND, 2
     add r17, r19

     ldi r19, 0b00000100
     sbis PIND, 3
     add r17, r19

     ldi r19, 0b00000101
     sbis PIND, 4
     add r17, r19

     ldi r19, 0b00000110
     sbis PIND, 5
     add r17, r19

     ldi r19, 0b00000111
     sbis PIND, 6
     add r17, r19

     ldi r19, 0b00001000
     sbis PIND, 7
     add r17, r19

     ldi r19, 0b00001001
     sbis PINC, 4
            add r17, r19

; Register 17 hat einen Wert zwischen 0 und 45 je nach
; Addition der Zahlenwerte durch die Stellung der neun Reedschalter

;******Ausgabe der oben errechneten Zahl an zwei 7-Segment-Anzeigen*****


ldi     r18, 0b00000000         ; Zweiteilung des Registers 18 für die
                                ; zwei BCD-Decoder
                                ; PIN 0-3 ist Einerstelle
                                ; PIN 4-7 ist Zehnerstelle
                                ; Setze Einerstelle auf Zahl 0
                                ; Setze Zehnerstelle auf Zahl 0

    cpi     r17, 0b00000000     ; Vergleiche oben errechnete Zahl mit 0
    breq    weiter              ; Wenn gleich, dann springe zu weiter

    ldi     r18, 0b00000001    ; Setze Einerstelle auf Zahl 1
                               ; Setze Zehnerstelle auf Zahl 0

    cpi     r17, 0b00000001    ; Vergleiche oben errechnete Zahl mit 1
    breq    weiter             ; Wenn gleich, dann springe zu weiter

    ldi     r18, 0b00000010    ; Setze Einerstelle auf Zahl 2
                               ; Setze Zehnerstelle auf Zahl 0

    cpi     r17, 0b00000010    ; Vergleiche oben errechnete Zahl mit 2
    breq    weiter             ; Wenn gleich, dann springe zu weiter

    ldi     r18, 0b00000011    ; usw.
    cpi     r17, 0b00000011
    breq    weiter

    ldi     r18, 0b00000100
    cpi     r17, 0b00000100
    breq    weiter

    ldi     r18, 0b00000101
    cpi     r17, 0b00000101
    breq    weiter

    ldi     r18, 0b00000110
    cpi     r17, 0b00000110
    breq    weiter

    ldi     r18, 0b00000111
    cpi     r17, 0b00000111
    breq    weiter

    ldi     r18, 0b00001000
    cpi     r17, 0b00001000
    breq    weiter

    ldi     r18, 0b00001001
    cpi     r17, 0b00001001
    breq    weiter

    ldi     r18, 0b00010000
    cpi     r17, 0b00001010
    breq    weiter

    ldi     r18, 0b00010001
    cpi     r17, 0b00001011
    breq    weiter

    ldi     r18, 0b00010010
    cpi     r17, 0b00001100
    breq    weiter

    ldi     r18, 0b00010011
    cpi     r17, 0b00001101
    breq    weiter

    ldi     r18, 0b00010100
    cpi     r17, 0b00001110
    breq    weiter

    ldi     r18, 0b00010101
    cpi     r17, 0b00001111
    breq    weiter

    ldi     r18, 0b00010110
    cpi     r17, 0b00010000
    breq    weiter

    ldi     r18, 0b00010111
    cpi     r17, 0b00010001
    breq    weiter

    ldi     r18, 0b00011000
    cpi     r17, 0b00010010
    breq    weiter

weiter:

    cpi     r17, 0b00010011    ; Da ich mit breq nicht so weit springen
                               ; kann, hab ich mir die Lösung einfallen
                               ; lassen
    brsh    runde2
    rjmp    Ende            ; Falls die Zahl oben noch nicht dabei war
                            ; geht der Vergleich in die nächste Runde
                            ; ansonsten Sprung zum Ende


runde2:

    ldi     r18, 0b00011001
    cpi     r17, 0b00010011
    breq    weiter2

    ldi     r18, 0b00100000
    cpi     r17, 0b00010100
    breq    weiter2

    ldi     r18, 0b00100001
    cpi     r17, 0b00010101
    breq    weiter2

    ldi     r18, 0b00100010
    cpi     r17, 0b00010110
    breq    weiter2

    ldi     r18, 0b00100011
    cpi     r17, 0b00010111
    breq    weiter2

    ldi     r18, 0b00100100
    cpi     r17, 0b00011000
    breq    weiter2

    ldi     r18, 0b00100101
    cpi     r17, 0b00011001
    breq    weiter2

    ldi     r18, 0b00100110
    cpi     r17, 0b00011010
    breq    weiter2

    ldi     r18, 0b00100111
    cpi     r17, 0b00011011
    breq    weiter2

    ldi     r18, 0b00101000
    cpi     r17, 0b00011100
    breq    weiter2

    ldi     r18, 0b00101001
    cpi     r17, 0b00011101
    breq    weiter2

    ldi     r18, 0b00110000
    cpi     r17, 0b00011110
    breq    weiter2

    ldi     r18, 0b00110001
    cpi     r17, 0b00011111
    breq    weiter2

    ldi     r18, 0b00110010
    cpi     r17, 0b00100000
    breq    weiter2

    ldi     r18, 0b00110011
    cpi     r17, 0b00100001
    breq    weiter2

    ldi     r18, 0b00110100
    cpi     r17, 0b00100010
    breq    weiter2

    ldi     r18, 0b00110101
    cpi     r17, 0b00100011
    breq    weiter2

    ldi     r18, 0b00110110
    cpi     r17, 0b00100100
    breq    weiter2



weiter2:

    cpi     r17, 0b00100101
    brsh    runde3
    rjmp    Ende


runde3:


    ldi     r18, 0b00110111
    cpi     r17, 0b00100101
    breq    weiter3

    ldi     r18, 0b00111000
    cpi     r17, 0b00100110
    breq    weiter3

    ldi     r18, 0b00111001
    cpi     r17, 0b00100111
    breq    weiter3

    ldi     r18, 0b01000000
    cpi     r17, 0b00101000
    breq    weiter3

    ldi     r18, 0b01000001
    cpi     r17, 0b00101001
    breq    weiter3

    ldi     r18, 0b01000010
    cpi     r17, 0b00101010
    breq    weiter3

    ldi     r18, 0b01000011
    cpi     r17, 0b00101011
    breq    weiter3

    ldi     r18, 0b01000100
    cpi     r17, 0b00101100
    breq    weiter3

    ldi     r18, 0b01000101
    cpi     r17, 0b00101101
    breq    weiter3

weiter3:

ende:

;*******************Blinkende Anzeige bei Zahlenwert 0******************

   cpi     r18, 0b00000000    ; Vergleiche Register 18 mit 0
   brne    ende1              ; Wenn nicht gleich, dann springe zu ende1
   ldi    r18, 0b10000000    ; Wenn gleich, dann setze Bit7 auf High

; An PortB Pin7 hängt eine astabile Kippstufe
; welche meine BCD-Decoder ein- und ausschaltet

;********Ausgabe meines Zahlenwertes an die BCD-Decoder************

ende1:


     out PORTB, r18    ; Inhalt von r18 an Port B ausgeben

rjmp loop1        ; Sprung zu "loop:" -> Endlosschleife




Danke fürs Durchschauen.

Gruß,
Russell
Gast #1976992
Lesenswert?

Hi Mister Ungeduld
>15.12.2010 11:12
>wie versprochen stelle ich mein Programm mal ein
>15.12.2010 13:28
>weiß vielleicht jemand an was das liegt, dass ich 1V am Pin6 PortB habe?
>Ist das eher ein Programmfehler oder ist mein Atmega8 hinüber?

Na ja 2Std. und 16 Minuten sind ja nun wirklich völlig ausreichend, den 
Fehler zu finden....
>ldi r16, 0b11101111
>out DDRC, r16   ; Pin 4 am Port C als Eingang konfigurieren
>                         ; Hier sitzt der 9. Reedschalter
Hab grad nicht das Datenblett, aber ist nicht PC6 ein Eingang, und zwar 
der Reset ?
Wenn du den als Ausgang parametrierst, kannst du soweit ich weiß, nicht 
mehr auf den Controller schreiben, zumindest nicht mit ISP.
Wenn du nicht weißt, ob du einen Pin einfach so übershreiben kannst und 
willst ihn auch in seinem Default belassen, dann lese vorher die 
Register ein:
   In   R16, DDRC
   ANDI r16, 0b11101111
   out DDRC, r16
So wird nur sichergestellt, das Bit 4 auf 0 gesetzt wird, alle anderen 
in ihrem Defaultwert bleiben. Ich bin mir sicher, wenn du dir die 
Bedeutung der IO's mal richtig ansiehst, wirst du feststellen, das du 
bei einigen nicht so auf Anhieb sagen kannst, welche Parametrierung nun 
richtig ist, um die Funktionalität zu erhalten. Daher mit And und Or nur 
die Bits löschen oder setzen, die benötigt werden.
Gruß oldmax
#1977009
Lesenswert?

Wilhelm Bachinger schrieb:
> Hallo Zusammen,
>
> weiß vielleicht jemand an was das liegt, dass ich 1V am Pin6 PortB habe?
>
> Ist das eher ein Programmfehler oder ist mein Atmega8 hinüber?

Hast du denn schon probiert, mit einem Einfachst-Testprogramm 
festzustellen, ob da was am Pin faul ist?

Dein Code ist extrem in die Länge gezogen. Da jetzt alle Pfade 
abzuklappern, ob sich rigendwo in mehrfachen Schleifendurchläufen 
ergibt, ob das Bit einmal 0 und einmal 1 ist, ist mühsam.
#1977021
Lesenswert?

PS. du weißt aber schon, dass man eine 2-stellige Zahl ganz leicht in 
die Zehner und die Einerstelle aufdröseln kann, indem man

a) einfach durch 10 dividiert

   23 durch 10   macht 2 und 3 bleiben Rest

b) man die Division auch ersetzen kann, indem man in einer Schleife
   einfach immer wieder 10 abzieht und mitzählt wie oft man das konnte
   ehe man einen Unterlauf hat

c) da dein Ergebnis ja nur in den Bereichen 0-9, 10-19, 20-29,
   30-39 und 40-45 liegen kann, reicht es auch, ganz einfach mit
   Vergleichen die entsprechende Zehnerstelle herauszufinden, dann
   die Zehner abzuziehen und die Einerstelle bleibt übrig.

   Beispiel:  38.  Durch testen findet man raus, dass man sich im
   Bereich 30 bis 39 bewegt (weil 38 größer 29 und kleiner als 40 ist)
   Also ist die Zehnerstelle schon mal 3.
   Von 38 dann die 3*10 abgezogen, bleibt 8 übrig, welches die Einer
   sind


Beide Einzelteile (Zehner und Einer) noch bitmässig zurechtschieben und 
ab damit an den Decoder.


Deine Lösung ist so ziemlich die komplizierteste, unübersichtlichste und 
fehleranfälligste, die man sich vorstellen kann.

Aber stell erst mal fest, ob mit deinem Pin 6 / Port B hardwaremässig 
alles in Ordnung ist.
OP #1977072
Lesenswert?

Hallo Oldmax,

entschuldige meine Ungeduld ;-)

Deine Problemlösung hört sich echt gut an.
Der PC6 ist ja auch der Reset.
Ich sollte diesen Pin mal lieber nicht konfigurieren.

Werde Deinen Vorschlag mal ins Programm integrieren und schauen.

Vielen Dank nochmal für den Tip und Deine Geduld :-)

Gruß,
Russell
OP #1977083
Lesenswert?

Hallo Karl-Heinz,

ich hatte natürlich schon im Gefühl, dass mein Lösung nicht annähernd 
die einfachste und beste ist.

Hab mir einfach mit dem jetzigen Wissen etwas zusammen geschustert.
Werd mir aber Deine Lösungsansätze zu Herzen nehmen, um das Ganze zu 
entwirren und fehlerunanfälliger zu machen.

Falls der Tip vom Oldmax nichts bringt, werde ich eine einfache 
Testschaltung auf diesen ominösen Pin loslassen.

Danke :-)

Gruß,
Russell
#1977086
Lesenswert?

Wilhelm Bachinger schrieb:
> Hallo Oldmax,
>
> entschuldige meine Ungeduld ;-)
>
> Deine Problemlösung hört sich echt gut an.
> Der PC6 ist ja auch der Reset.

Aber leider falsch.
So einfach kann man sich nicht den Reset unterm Hintern wegdefinieren. 
Das wäre ein bischen zu einfach.
Da muss man schon mit den Fuses rann, damit der Pin sein Reset-Verhalten 
aufgibt und als normaler Port-Pin angesprochen werden kann.

Auf Deutsch: Solange du nicht an den Fuses gespielt hat, ist dem PC6 
völlig egal, was du da umschaltest.
OP #1977600
Lesenswert?

Hallo zusammen,

jetzt hab ich mal ein Testprogramm zur Überprüfung des Pins 6 am Port B 
geschrieben:


loop1:
           sbis PIND, 0
           sbi portb, 6
           sbic pind, 0
           cbi portb, 6

rjmp loop1

Ergebnis:

Am Ausgang liegen entweder 1,0 V an oder 4,1 V an.
Der BCD-Decoder erkennt die Pegel und die Anzeige ist korrekt.

Aber normal ist der Zustand doch nicht, oder?
Kann das auch Ursache für die Probleme in meinem Hauptprogramm sein?

Gruß,
Russell

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren