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
Gggf hast du die Pins nicht auf AUSGNAG geschaltet mittels DDR = Data Direction Register Gruß Roland
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.
servus, eigentlich können solche pegel nur auftreten wenn reset nicht richtig beschaltet ist mfg
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
Hallo Münzi, bei den anderen Ausgängen liegen 0V an, nur bei einem einzelnen Ausgang kommen die komischen 1V. Kann das trotzdem am Reset liegen? Danke. Gruß, Russell
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.
Hallo Alex, trotzdem vielen Dank für Deine Antwort. Auf die Idee bin ich bei meiner Fehlersuche im Forum auch gestoßen. Musste Sie aber genau aus diesem Grund verwerfen. Der Atmega8 hat ja leider kein JTAG-Interface. Wäre zu schön gewesen ;-) Gruß, Russell
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?
ich hatte anfangs auch so meine probleme mit dem reset pin und da konnte man die tollsten sachen messen....
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
Hallo Münzi, und an was wars bei Dir gelegen? Was kann ich beim Reset-Pin grundlegendes falsch machen? Danke. Gruß, Russell
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
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
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
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
Hat noch jemand eine Idee? Timo hat vorhin mal geschrieben, dass der Ausgang abwechselnd mal High und Low sein könnte. Dadurch messe ich vielleicht eine Effektivspannung von 1V mit meinem Multi. Hab ich dann einen Programmfehler? Vielen Dank für Eure Antworten. Gruß, Russell
Hi
>Hab ich dann einen Programmfehler?
Um das zu beantworten müsste man das Programm sehen. Welcher Ausgang ist
es denn überhaupt?
MfG Spess
Ausgang PB6 Da hat Du natürlich recht. Ohne Programm kann man schlecht beurteilen, ob ich einen Programmfehler habe ;-) Entschuldigung. Leider habe ich im Moment das Programm nicht zur Hand. Ich schau aber, dass ich es demnächst hier einstelle. Gruß, Russell
Jetzt bin ich gerade am Ende meines Mikrocontroller-Horizonts ;-) Bin noch nicht so firm und lerne gerade noch fleißig. Was ist ein STK500? Das hab ich schon mal in der AVR-Software irgendwo gelesen.
Ich tippe auf einen Lötfehler. Gib mal wechselweise mit 1s Pause 55 und AA (hex) an den Ports aus und miss die Spannung an allen Ausgängen. Oder zähle den Port einfach hoch und schau dir das Signal auf dem Qszi an, ob es dem entspricht was du erwartest. W.
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
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?!?
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
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
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? Danke. Gruß, Russell
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
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.
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.
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
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
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.
Hi >Deine Problemlösung hört sich echt gut an. >Der PC6 ist ja auch der Reset. Was nun? Oben hast du PB6 geschrieben. MfG Spess
Hallo Spess, ich hab die Antwort von Oldmax so verstanden, dass ich durch die Konfiguration des PC6 (Reset) Probleme bekommen kann, also evtl. auch am PB6. Laut Karl-Heinz ist die Theorie aber schon wieder hinfällig. Schade. Gruß, Russell
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.