PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AVR Einstieg Leichtgemacht Wiki Frage



Basteltisch
22.07.2009, 22:25
Hallo zusammen,
ich habe folgende Frage:
Der Wikieintrag
http://www.rn-wissen.de/index.php/AVR-Einstieg_leicht_gemacht

schien mir komplizierter zu sein als Nötig. Deswegen hab ich nun folgendes gebastelt(Anhang1).

Mit folgendem Code:


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1000000

Config Portc.0 = Output 'Ein Pin wird als Ausgang konfiguriert PC0 (also Pin0 von Port C)

Config Pina.7 = Input 'Ein Pin (PA0) wird als Eingang definiert
Porta.7 = 1 'Interner Pullup Widerstand ein


Do
If Pina.7 = 1 Then
Portc.0 = 1 'Pin wird auf High, also 5V geschaltet
Else
Portc.0 = 0 'Pin wird auf Low, also 0V geschaltet
End If
Loop


End



Also der Code ist unverändert. Die Veränderung in der Schaltung ist folgende:
A7 Wird nun als Input verwendet, sobald es auf HIGH steht wird auch C0 auf High gesetzt, also die Lampe leuchtet.

Meine Frage: kann das funktionieren?
Wenn nicht, wieso nicht?

Ich arbeite mich grade erst in dieses Thema ein und würde gerne wissen ob ich hier richtig denke oder wo mein Fehler liegt.

Es grüßt,
Basteltisch

markusj
22.07.2009, 23:05
Hä? What?
Was hast du hier zusammengewurstelt?

1. Die Schaltung ist falsch - der Pullup geht gegen VCC, der Taster ist an VCC angeschlossen - du bekommst also niemals mit, dass der Taster gedrückt ist.
2. Wieso ist der Wiki-Eintrag kompliziert? Ich halte ihn für gut Strukturiert und äußerst einsteigerfreundlich, da von Null an angefangen wird.

Der Taster muss bei Verwendung des internen Pullups gegen GND schalten, wenn du gegen VCC schalten möchtest, brauchst du einen parallel geschalteten Pulldown-Widerstand am Portpin des AVRs nach GND.

mfG
Markus

Basteltisch
23.07.2009, 12:16
Hallo,
danke für die Antwort.

Aber der Schalter ist doch bei A7 Input und nicht bei VCC.
Und die LED ist bei C0 Output und nicht bei GND.

Und in dem Uhrsprungsbild ist die LED doch falsch rum an C0 wenn C0 der Output ist.

Ich bitte um Aufklärung.

Es grüsst,
Basteltisch

markusj
23.07.2009, 13:01
Ein Auszug aus deinem Code:

Config Pina.7 = Input 'Ein Pin (PA0) wird als Eingang definiert
Porta.7 = 1 'Interner Pullup Widerstand ein

Damit machst du A7 zum Input, dass ist richtig. Ferner aktivierst du jedoch den internen Pullup-Widerstand in der zweiten Zeile.
Der Pullup zieht die Spannung am unbelasteten Portpin auf VCC (High).
Wenn du jetzt den Taster drückst, verbindest du den Portpin mit VCC (High), es gibt also genau gar keinen Unterschied.
Selbst wenn der Pullup nicht aktiv wäre, würdest du ein undefiniertes Verhalten bekommen, da der Pin auf kein definiertes Signal gezogen würde.

mfG
Markus

PS: Die LED ist nicht falsch angeschlossen, das ist eine Frage der Programmierung. Ob du den Pin auf Ausgang und Low oder Ausgang und High stellst, um die LED zum leuchten zu bringen ist Geschmackssache.

Basteltisch
23.07.2009, 13:16
Hallo,
Also ist das mit dem High und Low garkeine Eigenschaft eines Pins die man Abfragen und setzen kann?

Sonst währe mir nun folgender Code eingefallen:


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1000000

Config Portc.0 = Output
Config Pina.7 = Input

Do

Portc.0 = Pina.7
Loop

End

Würde das auch nicht funktionieren?
So ich ich mir nun dachte wie es funktioniert würde damit der C0 dann Strom rausgeben wenn A7 Strom reinbekommt. Ist hier der Denkfehler? Sind es nicht einfach nur 1 und 0 bei denen ein Port unterschiedet und die bei einem Port gesetzt werden können?


Bei der LED hab ich auch noch eine Frage:
Wenn der C0 im Uhrsprungsbild nun der Output Port, also der Port ist wo Strom raus kommt ist, dann würde dieser doch zur Spannungsquelle zurückfliessen.


Es Grüsst,
Basteltisch

Edit: ahja wo ist der unterschied zwischen Port und Pin?

markusj
23.07.2009, 16:24
Hey Basteltisch,

wie wäre es wenn du die ganzen Anleitungen mal von vorne durchgehst und nicht quer reinspringst und dich dann wunderst, dass nichts klappt.

Mal ein Paar elektrische Grundlagen:
High = VCC und damit in der Regel 3~5V
Low = GND und damit in der Regel 0V

Und nun zu einigen AVR-Basics

Wenn ein Pin als Eingang fungiert, misst er keinen Strom, sondern nur die anliegende Spannung, Details zu den Schaltschwellen findest du im Datasheet des jeweiligen AVRs.
Wenn ein Pin als Eingang konfiguriert ist, kann man ferner einen sogenannten Pullup-Widerstand aktivieren, also ein Widerstand von ~50kOhm gegen die Versorgungsspannung. Ist der Pin nicht weiter elektrisch belastet, liegt bei aktiviertem Pullup also ein High-Signal an.

Ist ein Pin als Ausgang konfiguriert, versucht der AVR je nach gesetztem Wert diesen Pin entweder auf Low zu ziehen (und fungiert damit als GND) oder aber auf High (und ist damit dann VCC).
Ein Ausgangspin kann also sowohl Stromquelle als auch Stromsenke sein.

Ein Pin ist ein einzelner Anschluss deines AVR, ein "Beinchen".
Ports fassen bis zu acht Pins zu einer Organisationsenheit zusammen, die jeweils gemeinsam über ein Register konfiguriert werden. (1 Byte hat 8 Bit, also für jeden Pin ein Bit ...)
Die "einfachen" Ein-/Ausgabefunktionen haben drei Register:
1. Das Register DDRx
Im DDR steht für jeden Pin ein Bit, das angibt, ob der Pin als Eingang oder Ausgang fungiert.
2. Das Register PORTx
Im PORT-Register steht für jeden Pin ein Bit, dass angibt, ob der Pin auf High oder Low gesteuert werden soll, ist der Pin ein Eingang, aktiviert ein gesetztes Bit den Pullup des jeweiligen Pins
3. Das Register PINx
Mit dem PIN-Register kann man zwei Dinge tun, ist der Pin ein Eingang, so ist sein Bit im PIN-Register gesetzt wenn ein High-Signal anliegt.
Ist ein Pin ein Ausgang und man setzt das Bit eines Pins, so wird dessen Ausgangssignal umgeschaltet (High statt Low bzw. umgekehrt).

x steht jeweils für den entsprechenden Port-Buchstaben, also ist PC0 der erste Pin (und damit das erste Bit in allen betreffenden Registern) im Port C, die Register sind also DDRC, PORTC und PINC

BASCOM versteckt viele dieser Feinheiten hinter Befehlen wie "Config".

Zurück zu deinem Vorschlag:
Wie du vielleicht erkennst, ist der Fehler weniger der Code als vielmehr die Schaltung. Dein Schaltungsentwurf KANN nicht funktionieren.
Der AVR bildet nicht intern irgendwelche Verbindungen zwischen ein und Ausgängen.
Er misst an Eingängen Spannungen und an Ausgängen liefert er eine Spannung, und falls nötig auch in begrenzten Mengen Strom.

Der Strom den der AVR ausgibt stammt aus dessen Versorgungspins, die jeweils mit (A)VCC und (A)GND beschriftet sind.

Darum funktioniert auch die Originalschaltung an PC0: Wird der Pin auf Ausgang + Low konfiguriert, dann existiert ein Stromkreis von VCC durch LED, Widerstand, PC0, den AVR zu dessen GND-Anschluss. Wird der Pin auf Eingang oder Ausgang + High konfiguriert, fließt kein Strom (in ersterem Falle weil der Eingang sowieso keine Stromquelle/-senke ist, und im zweiten Fall weil auf beiden Seiten der Diode die gleiche Spannung anliegt).

mfG
Markus

PS: Am besten setzt du dich einmal gründlich mit einigen Tutorials und den Datasheets der AVRs auseinander, die elektrischen Grundlagen dazu würden natürlich auch nicht schaden.
Ein gutes Buch ist auch sehr hilfreich!.

Besserwessi
23.07.2009, 16:29
Der einfache Code funktioniert, allerdings nur mit dem Schalter nach GND. Mit dem Schalter nach VCC und ohne extra Pulldown kann praktisch keine Software was anfangen (Es würde schon gehen mit kurzen Pulsen auf low um einen Kurzschluß fstzustellen, ist aber nicht so ideal. Für eine Anfänger sollte man diese Lösung erst mal außen vorlassen).

Über Portx.n stellt man ein was ausgegeben werden soll, bzw. ob der Pullup Widerstand an ist. Über Pin ließt man den Zusatnd des Ausgangs ein. Bei einigen µCs kann man durch schreiben einer 1 den Zustand von Bits in der Ausgabe (Port Register) umdrehen.

Basteltisch
23.07.2009, 21:38
Danke für die Umfangreiche Antwort markusj.
Ich dachte mir ich spring mal ins kalte Wasser, so hab ich bisher vieles gelernt.

Ich glaube ich hab das Geheimniss nun gelüftet und weiss wo mein Denkfehler lag.

Ich dachte bei Eingang das ein Port Signale empfängt und diese Auswertet, so wie ich Ausgang für einen Port gehalten habe der Signale ausgibt, also Strom Eingang und Strom Ausgang.

Scheinbar ist es so (bitte korrigieren falls es falsch ist):

Der Eingang wird quasi als durchfluss verwendet, wenn er keinen Pullup Widerstand mehr hat kann der Strom herein und die LED leuchtet (in diesem Fall).
Ausgänge prüfen ihren eigenen Status dahingehend, ob er mit GND/einem anderen Konsument verbunden ist, also ob Strom durch ihn fliesst. Dies geben sie entsprechend wieder.
Kann man es mit GET (Ausgang) und LET (Eingang) von höheren Basic Dialekten vergleichen?

Die Sache mit den Ports habe ich nun auch verstanden als ich einen C Quellcode gesehen habe:
Es gibt in diesem Fall nur 4 Ports (A bis D) mit jeweils 8 Pins.
Angesprochen werden diese durch (A|.. |D).(1|..|8).

Doch worin liegt der Unterschied zwischen PinA.1 und PortA.1?
ist es die Unterschiedliche verwendungsweise? Wenn ich mir die Quelltexte so ansehe würde ich sagen man definiert Outputs über das Präfix Port, und Input über Pin.

Ich habe noch eine Allgemeine Frage zur Programmierung:
Was ich bisher gesehen habe ist das man nur Boolsche Werte, also 1 oder 0 Abfragt. Was passiert denn bei Sensoren die mehr als nur 2 Statuse kennen? Also z.b. ein GPS Sensor der direkt ganze Zeichenketten zurückgibt. Wie werden diese Ausgewertet?

Es grüßt,
Basteltisch

Besserwessi
23.07.2009, 22:06
Über Port und Pin spricht man 2 verschiedene Register an. Beide Register kann man lesen oder schreiben.

Bei PIN ließt man den Spannungswert am IO PIN, unabhängig davon ob er als Eingang oder Ausgang definiert ist. Die wesenliche Anwendung sind hier aber die Eingänge.
Wenn man ins PIN Register schreibt, hängt es vom µC model ab. Bei älteren tut sich nichts, bei neueren wird durch das schreiben einer 1 ins register PIN das entsprechende BIT im Register PORT umgedreht. Das ist eine spezialfunktion die man als Anfänger eher selten braucht.
Der Eingang ist Spannungsgesteuert. Es hat also nichts mit einem fließenden Strom zu tun.



Das Port Register ist etwas einfacher. Beim lesen bekommt man immer die Werte des Registers raus, unabhängig von der Spannung die von außen anliegt. Wenn der IO-Anschluß als Ausgang definiert ist, wird über das PORT BIT die Spannung am Ausgang festgelegt. Eine 1 steht für für Hohe Spannung, also fast VCC. Ein 0 Steht für niedriege Spannung, also fast GND.
Wenn der IO Anschluß als Eingang definiert ist, dann steuert das Bit im Register PORT den Pullup Widerstand. Eine 1 stellt den Pullup Widerstand an, eine 0 aus.

Das Registser Port nutzt man also in der Regel für Ausgänge. Bei Eingängen nur um den Pullup zu konfigurieren.

markusj
23.07.2009, 22:22
Hallo Basteltisch,

ich versuche deine Gedanken noch etwas weiter zu entwirren und springe deshalb vermutlich etwas durch deinen Post:

Ich habe noch eine Allgemeine Frage zur Programmierung:
Was ich bisher gesehen habe ist das man nur Boolsche Werte, also 1 oder 0 Abfragt. Was passiert denn bei Sensoren die mehr als nur 2 Statuse kennen? Also z.b. ein GPS Sensor der direkt ganze Zeichenketten zurückgibt. Wie werden diese Ausgewertet?
Genauso ;) Im Endeffekt gibt es nur zwei Formen der Kommunikation: Digital, also eine Reihe von Boolschen Werten, die in irgend einer Form durch ein Medium geschoben werden, oder analog - und analoge Werte müssen dann auch erst wieder in eine digitale Form gebracht werden, damit ein AVR damit arbeiten kann.
Wenn ich nicht irre, arbeiten GPS-Geräte in der Regel über eine Art serielle Schnittstelle, die die Bits in einem bestimmten Takt und mit einer durch ein Protokoll definierten Struktur durch die Leitung schickt, am anderen Ende setzt man dann die Bits gemäß dem Protokoll zusammen.

AVRs haben in der Regel eine Menge nützlicher Komponenten, die sich mit der "normalen" Pin-Funktion Pins teilen und dann zum Beispiel die Verwendung einzelner Pins als serielle Schnittstelle, Eingänge zum ADC und viele andere Dinge ermöglichen, die in der Regel dem Programmierer viel Arbeit abnehmen und direkt mit Hardware ausführen.


Der Eingang wird quasi als durchfluss verwendet, wenn er keinen Pullup Widerstand mehr hat kann der Strom herein und die LED leuchtet (in diesem Fall).
Ausgänge prüfen ihren eigenen Status dahingehend, ob er mit GND/einem anderen Konsument verbunden ist, also ob Strom durch ihn fliesst. Dies geben sie entsprechend wieder.
Äh - nein.
Inbesondere irgendwelche Durchflüsse hatte ich mit meinem Post eigentlich ausdrücklich ausgeschlossen, oder?

Zuerst wieder einmal die Basics:
(Fast) jeder Pin ist multifunktional. Er kann als Eingang oder Ausgang dienen, viele Pins haben noch weitere Funktionen, auf die ich jetzt aber nicht eingehen möchte.
Ob ein Pin als Eingang oder Ausgang fungiert, wird, wie wir bereits wissen, über das DDRx geschaltet.

Ach ja - Eingang oder Ausgang sagt nicht bezüglich der Stromrichtung!

Eingang:
Ist der Pin ein Eingang, "betrachtet" er nur die anliegende Spannung. Was der Pin gerade "sieht", kannst du über das PINx-Register auslesen.
Jetzt kommt noch der Pullup ins Spiel. Intern ist wie in diesem RN-Wissen Artikel zum Thema Pullup (http://www.rn-wissen.de/index.php/Pullup) gezeigt, ein Pullup neben der normalen Funktion integriert, da man Pullups oft braucht und so leicht Bauteile sparen kann.
Es ist also quasi der Widerstand auf der Schaltung in den AVR hineinverschoben worden, ferner kannst du ihn via PORTx ein/ausschalten).
Das Einschalten des Pullups kann das, was der Pin dann letztendlich zu "sehen" bekommt beeinflussen - die grundlegende Funktion des Eingangs als reinen "Beobachter" ändert es nicht.

Ausgang:
Wenn ein Pin als Ausgang konfiguriert wird, beeinflusst er seine Umgebung aktiv. Entweder gibt er GND aus, oder VCC. Besteht dann eine Verbindung zu einem höheren(niedrigeren Potential, fließt entsprechend Strom.
Der AVR überwacht jedoch den Stromfluss nicht, insbesondere auch nicht auf Überstrom oder falsche Polung (durch mehrere Versorungsspannungen oder unterschiedliche Masseniveaus)
Welches Signal am Pin ausgegeben wird, definiert der Wert im PORTx-Register.

Basic auf PCs habe ich nie programmiert, BASCOM nach einer Woche gegen C ausgetauscht.

mfG
Markus

PS: Es schadet nicht, wenn man sich dennoch etwas informiert, auch wenn man sich jenseits der üblichen Pfade bewegen möchte.
Mein erstes AVR-Board war auch selbstentwickelt, -gelötet und -programmiert, dem ging aber eine intensive Recherchephase voraus - ich kann insbesondere das Buch von Roland Walter speziell für BASCOM-Einsteiger nur empfehlen.

Edit: Meine Anmerkung zu PINx gelöscht, Besserwessis Beitrag dazu ist besser und korrekter - man lernt nie aus.

Basteltisch
27.07.2009, 20:53
Hallo,
nochmals danke für die Antworten.
Ich denke ich habe nun verstanden wie die Schaltung dort funktioniert:

Da der Schalter mit GND verbunden ist gibt die Abfrage von Pina.7 eine 1 zurück sobald der Schalter gedrückt, also der Stromkreis geschlossen ist.

Dem PortC.0 wird es darauf hin erst ermöglicht den Strom der von der Stromquelle kommt aufzunehmen da er auf High geschaltet wird, also eine Spannung da ist.

Ist das so korrekt? Wenn ja dann kann ich in Zukunft sehr gut darauf zurückgreifen. Ist das etwas Amtel / Atmega32 spezifisches oder funktionieren alle Microcontroler I/Os nach diesem Schema?

Leider kann ich das noch nicht ausprobieren da mir noch das Programmierkabel fehlt, aber sobald das da ist werde ich loslegen mit der Programmierung :)

Es grüßt,
Basteltisch

markusj
27.07.2009, 21:15
Nochmal nein.
Wenn der Schalter gedrückt wird, wird der PA7 auf GND gezogen, GND ist wenn du Pina.7 einliest eine 0.
Es geht hier nicht um Stromkreise, beim einlesen geht es nur um die anliegende Spannung.

Und das Programm rennt die ganze Zeit im Kreis (DO ... LOOP bildet hier eine Endlosschleife) und fragt diesen Pin ab.
Das Programm entscheidet darüber, wie PC0 dann konfiguriert wird.
Bei dem Beispielprogramm aus dem Wiki wird der PC0 auf High konfiguriert, wenn PA7 High eingelesen wurde. PA7 ist genau dann High, wenn der Taster das Signal nicht auf GND zieht.
Wurde PA7 als Low ausgelesen, ändert das Programm das Ausgangssignal für PC0 auf Low, das andere Ende der LED hängt aber an High, es fließt also in genau diesem Fall ein Strom der die LED zum leuchten bringt.

Ich hege den Verdacht, dass du dem Mikrocontroller zu viel Eigenintelligenz zuschreibst.
Der AVR (und jeder andere Mikrocontroller) tut genau das, was du ihm sagst.
Sagst du ihm, er soll einen Ausgangspin auf Low/High ziehen, stellt er intern eine Verbindung zwischen GND/VCC und dem Pin her. Wenn dabei ein Kurzschluss entsteht, stirbt (im besten Fall nur) der Pin.
Sagst du ihm, er soll einen Pin als Eingang benutzen, schaltet er nicht mehr direkt GND oder VCC an den Pin, sondern bietet nur noch die Möglichkeit, ihn nicht zu beeinflussen oder mit einem Pullup anzusteuern.
Sagst du ihm, er soll den momentanen Wert auslesen, tut er genau das.

Ferner solltest du ein wenig vom Stromkreisdenken wegkommen. Bei den Mikrocontrollern läuft viel nur mit Pegeln (High/Low), dass aus anliegenden Pegeln ein Stromfluss (wie bei der LED) folgen kann, ist für die Signalverarbeitung im AVR selbst weniger wichtig.
Wenn du Ausgänge schaltest, musst du primär wissen, dass du damit eben jene besagte Leitung nach GND oder VCC durchschaltest. Wie das dann die nachfolgende Schaltung beeinflusst, ist für den AVR erst einmal unwichtig.

mfG
Markus

Basteltisch
27.07.2009, 21:34
Hallo,
oh weia also bedeutet High auf der einen Seite und Low auf der anderen das Strom von High zu Low fliesst?
Also wird mit dem schliessen des Tasters das LOW auf A7 erzeugt da es nun mit GND verbunden ist?

Stimmt dies nun?

Ich habe zwar beruflich mit Anwendungsentwicklung zu tun, sogar speziell Basic devirate, aber in diesem Fall tue ich mich unterwartet schwer mit dem Verständniss.

Es grüßt,
Basteltisch

markusj
28.07.2009, 00:04
Hey, du redest schon wieder von Strom ;)

Ja, High auf einer Seite (z. Bsp Pin eines AVR) und Low auf der anderen Seite (z.Bsp. GND) verursacht eine Spannung die zwischen den beiden Seiten anliegt, und damit kann also auch ein Strom fließen.
Und weiter richtig, Schließen wir den Taster, ziehen wir den PA7 auf LOW, korrekt. (Weil die Ladung am Portpin nach GND abfließt und der geringe Strom, den der Pullup im AVR abgibt ebenfalls).
Lässt man den Taster los, kann der Pullup den Pin wieder auf HIGH ziehen.
Der direkte "Kurzschluss" des Pins über den Taster hat keine weiteren Folgen, weil der Pullup mit ~50kOhm nur sehr wenig Strom fließen lässt.
Hätte man den Pin aber als Ausgang konfiguriert, würde der Pin direkt mit GND kurzgeschlossen, ein hoher Stromfluss würde den AVR (oder zumindest Teile von ihm) beschädigen oder zerstören.

mfG
Markus

PS: Sieh dir doch mal das Datasheet (nicht die Summary) unter Product Card ATMega32A (http://www.atmel.com/dyn/products/product_card.asp?part_id=4404) an.
Auf Seite 50, Fig 12-1 siehst du, wie der Pin innen weiter verschaltet ist (zumindest der erste Teil).
Die ersten beiden Schaltzeichen (von links) sind Schutzdioden, die das Eingangssignal gegen VCC bzw. GND ableiten, wenn es über oder unter GND bzw. VCC steigt/fällt.
Cpin ist momentan uninteressant, aber das was danach als Rpu zu sehen ist, ist der schaltbare Pullup-Widerstand gegen VCC.