PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Erneuter Mikrokontrollereinstieg



runner02
30.03.2010, 14:50
Hallo,

Habe schon mal vor 1-2 Jahren versucht, einen ATMega 8 zu programmieren (war beim Programmer dabei)
Den scheine ich aber irgendwie geschrottet zu haben, und der hatte auch zu viele Ausgänge, als dass ich sie als Anfänger verstehen hätte können...


Nun habe ich mit ATtiny 13 besorgt, und möchte es diesmal wirklich schaffen.

- http://www.rn-wissen.de/index.php/Bild:Avr8.jpg - hierzu gleich meine erste Frage: wozu der Widerstand?
Brauche ich den auch beim ATtiny? Und VCC ist in diesem Bild nicht angeschlossen, nur AVCC... Wieso das?

Was heißt hier immer Portd und .6 da habe ich mich schon verrrückt gesucht.. Und manchmal sieht man auch Kombinationen wie Portb.0b.0111.00100 ...
Die Spache hier im Bilde ist aber nicht C?

Dazu noch wichtige Fragen:
Wieso muss ich Port D als Ausgang setzen? Dann sind alle Ports von D (1,2,3,4,5,6,...) Ausgänge. Gibt es auch Möglichkeiten, nur einzelne zu schalten?


___

Obwohl: Welche Sprache wurde in dem Bild verwende? Die sieht ziemlich einfach aus... Ein Bekannter hatte mir aber mal geraten, C zu lernen...

askazo
30.03.2010, 15:05
Hi,

erst mal vorweg zu dieser Minimalbeschaltung:
Das ist nur eine Demonstration, dass man mit sehr wenigen Bauteilen auskommen kann. Das ist kein idealer Aufbau!

- Der Widerstand ist der sogenannte "Pull-Up-Widerstand" für den Reset. Den brauchst Du auch beim Tiny. Idealerweise gehört an den Reset-Pin auch noch ein 100nF Kondensator gegen Masse. (Streng genommen kannst Du den Reset-Pin auch offen lassen bzw. ihn als normalen IO benutzen - allerdings kannst Du ihn dann nicht mehr mit einem ISP programmieren)

- Im Bild ist VCC angeschlossen und AVCC nicht. AVCC benötigt man eigentlich nur, wenn man die internen AD-Wandler benutzt. AVCC sollte dennoch immer mit an VCC (evtl über Filter, wenn der AD benutzt wird) angeschlossen werden.

- Die Programmiersprache im Bild ist Bascom. Das C-Equivalent zu Portd.6 = 1 wäre PORTD |= (1<<6); Damit sprichst Du den Pin PD6 an.

- Im Bild werden die LEDs ohne Vorwiderstände betrieben. Das ist schädlich für Controller und LEDs und sollte daher nicht gemacht werden.

PS: Hast Du schon diesen Artikel gelesen: http://www.rn-wissen.de/index.php/AVR-Einstieg_leicht_gemacht ? Da steht schon viel nütliches für den Einstieg drin...

Gruß,
askazo

markusj
30.03.2010, 15:14
Hallo,

Die Sprache ist nicht C, sondern BASCOM (Basic).
Ferner hat das Bild nicht wirklich Vorbildfunktion, du solltest dir eher die Grundschaltung ansehen, die da normalerweise besteht aus: 10kOhm an RESET gegen VCC, um ungewollte Resets durch Störungen zu vermeiden, ein 100nF-Kerko (oder ähnlich "schnelle" Kondensatoren) zwischen GND und VCC. Außerdem betreibt man LED normalerweise nie, nie, niemals ohne Vorwiderstand.
Die Datenblätter empfehlen, AVCC über eine Induktivität mit 10µH mit VCC sowie einen Kondensator mit 100nF nach GND zu verbinden. (Datenblatt, Analog Noise Canceling Techniques, Fig. 96, Seite 203 im Datenblatt des ATMega8). Natürlich nur, wenn dein AVR AVCC hat ;)

Lies dir doch mal das Datenblatt des Tiny13 durch (auch wenn das einige hundert Seiten hat ...), dann verstehst du vieles besser.

Zu den Anweisungen: Die Ein/Ausgänge der AVRs sind in Ports aufgeteilt. (Details: Datenblatt, Abschnitt I/O-Ports)
Portd.6 = 1 schaltet den Pin mit Nr. 6 an Port D ein (oder den Pullup).

mfG
Markus

Edit: Verdammt, zu langsam ... @askazo: Die 100nF an Reset sind m.W. sehr optional und schließen ferner das Debuggen mit DebugWire aus ...

askazo
30.03.2010, 15:43
@markus: ja, eigentlich hast Du Recht. Die AVRs machen auch von sich aus einen sauberen Power-On-Reset. Naja, hab's mir so angewöhnt, benutze aber auch kein Debug-Wire ;)

Gruß,
askazo

runner02
30.03.2010, 18:52
Habe mir das alles nocheinmal durchgelesen...

Bin auf folgendes gestoßen (Gehe ich richtig?)

Mit DDB1 ... DDB5 setzt man einen Fuß auf Eingang/Ausgang (mit Anhang 0x01 oder sowas)

PORTB1 ... PortB2 ... ist schon Ausgang, den kann man dann auf 1 oder 0 schalten (mit Anhnag 0X00 oder sowas)

PINB1, PINB2... Damit nimmt man den Eingang, den man bei if-Befehlen aufrufen kann
Anhang wiederrum nötig


___
Nun, diese ganzen ANhänge verwirren mich irrsinig, und ich finde nirgends eine Logik, wie man sie zuordnet....

Sauerbruch
30.03.2010, 19:10
...fast richtig :-)

"DDR" sind in der Tat die "Data Directory"Register, mit denen man festlegt, ob ein Anschluss ein Ein- oder Ausgang ist.

Beim Power-On-Reset sind sie erstmal alle auf 0, d.h. alle Anschlüsse sind als Eingänge geschaltet. Das ist auch gut so, denn ein Eingang kann erstmal keinen externen Schaden anrichten.

Du kannst die einzelnen Bits eines Registers auf zwei Arten setzen:

Entweder einzeln, also z.B. DDRB.6=1 (setzt das 6. Bit)

oder alle zusammen. Wenn Du also D.0, D.1, D.2 und D.3 als Ausgang nutzen willst, schreibst Du einfach

DDRD = &B00001111

"&B" heißt nur, dass die nachfolgende Zahl binär dargestellt ist. Und das höchstwertigste Bit steht links.

Weil binär 00001111 dezimal 15 entspricht, könnte man auch schreiben

DDRD = 15

Aber binär ist´s halt anschaulicher, weil man alle Bits direkt vor sich sieht.


Eingänge werden in der Tat über PINX.Y abgefragt, und wenn Du einen Ausgang auf 1 oder 0 setzten möchtest, geht das über PORTX.Y.

Das PORT-Register hat aber auch eine Aufgabe, wenn der Anschluss als Eingang konfiguriert ist. Damit wird nämlich der interne PullUZp-Widerstand aktiviert, der die Eingangspin über ca. 50 kOhm auf +5V zieht.

Ist es jetzt etwas klarer? :-)

runner02
31.03.2010, 13:48
Ist es jetzt etwas klarer? Ja, danke

Entweder einzeln, also z.B. DDRB.6=1 (setzt das 6. Bit)
Diesen Befehl gibt es in C?

DDRB=3 (PB0+PB1) habe ich jetzt verstanden...


Wenn man abfragt, ob ein Eingang Strom hat:

Wenn PB0 hat Strom -> Aktion

Wenn ich 'if PINB=1' schreibe ist das aber die falsche Bedingung, da dann ja automatisch alle anderen 0 sind (00000001), das heißt er reagiert nur dann, wenn alle augänge keinen strom haben. Das sollte ihm aber egal sein

Sauerbruch
31.03.2010, 13:58
Diesen Befehl gibt es in C?

Das weiß ich nicht - "C" kann ich gerade mal fehlerfrei buchstabieren, mehr aber nicht :-)

Wenn Du eine Aktion ausführen willst, wenn am Anschluss B.0 ein High-Signal anliegt, geht das so:

If PINB.0 = 1 then
Befehl 1
Befehl 2
...
End if

Soll in Abhängigkeit des Eingangssignales zwischen zwei Aktionen unterschieden werden, geht das so:

If PINB.0 = 1 then
Befehl 1
Befehl 2
...
Else
Befehl A
Befehl B
...
End if

Wenn die Aktion nur aus einem einzigen Befehl besteht, geht´s auch in einer Zeile und ohne End If:

If PINB.0 = 1 then Befehl 1

Bzw. als entweder-oder-Geschichte:

If PINB.0 = 1 then Befehl 1 Else Befehl A

runner02
31.03.2010, 14:01
Kennt sich zufällig jemand mit pem Programm myAvr aus?

Das habe ich benutzt, um den Code zu schreiben, dann wollte ich brennen, und nun schreibt er 'USB not found' und 'giveio not found' ....

Dann habe ich den USB-Treiber installiert, danach ging es noch immer nicht...

runner02
01.04.2010, 16:21
Hey es geht endlich!!! (teilweise)

Nun ist der Chip programmiert und mit 2* 1,6 V Batterien angeschlossen...

Allerdings kann ich die periodischen 'Stomstöße', die ich einprogrammiert habe, nur messen.

LEDs leuchten keine, da ein Widerstand eingebaut ist.
Ohne Widerstand würde ich den Chip schrotten - was soll ich tun? Bitte um schnelle Hilfe!!

Kennt jemand eine Möglichkeit, das ganze (ohne Verstärkerschaltung) hinzubekommen?

Sauerbruch
01.04.2010, 16:27
was soll ich tun?

Kleineren Widerstand nehmen :-)

Bei ´ner Betriebsspannung von 3,2V, einer LED-Spannung von vielleicht 2,5V und einem Strom von 15mA wären das roundabout 50 Ohm. Der Controller kann den Strom einer normalen LED locker ab.

Oder Variante 2: 1 bis 2 Dioden vor bzw. hinter die LED schalten, je nachdem ob die LEDs von + zum Controller gehen oder vom Controller nach GND. Das hätte den Vorteil, dass Du´s nur einmal für beliebig viele LEDs brauchst.

runner02
01.04.2010, 19:22
Der Controller kann den Strom einer normalen LED locker ab.
Ich habe mir Unterstützung bei einem Bekannten geholt, und der meinte: LED frisst 50 mA, Mikrocontrollerausgang hält maximal 20 mA aus...
Nicht korrekt??



Oder Variante 2: 1 bis 2 Dioden vor bzw. hinter die LED schalten, je nachdem ob die LEDs von + zum Controller gehen oder vom Controller nach GND. Das hätte den Vorteil, dass Du´s nur einmal für beliebig viele LEDs brauchst.
Die Dioden als Widerstand nutzen oder wie?

Und alle Leucht-Dioden auf die Dioden schließen und die dann an GND?

Sauerbruch
01.04.2010, 19:35
Das mit den 20 mA ist sicherlich korrekt. Normale (!) LEDs sollten schon bei deutlich niedrigerem Strom (10 - 15mA) ordentlich leuchten. Auf allen möglichen gängigen Experimentierboards werden LEDs mit Vorwiderstand von +Ub zum Controller geschaltet - das hat sich bewährt.

So ein I/O-Port kann etwas mehr Strom nach Masse ableiten (wenn er LOW ist) als er abgeben kann, wenn er HIGH ist. Deshalb sind LEDs meistens von +Ub zum Controller geschaltet - und gehen an, wenn der Port 0 ist.

Die Diode ist nicht in erster Linie als Vorwiderstand zu sehen, sondern verbrät ziemlich konstant 0,7 Volt. Und weil diese 0,7 Volt unabhängig davon sind wie hoch der Strom gerade ist, funktioniert das für eine LED genauso gut wie für 10 LEDs. Die Diode liegt entweder zwischen +Ub und der LED (bzw. den LEDs), oder verbindet die LEDs mit GND. Je nachdem, ob Du die LEDs mit einem 1 oder 0 schalten möchtest.

Wenn Du ein Multimeter hast, miss doch mal Spannung und Strom nach, bei denen die LED ordentlich leuchtet. Dann kannst Du abschätzen, wie viele Dioden Du in Reihe schalten musst, wenn Du mit 3,2 Volt reingehst.

runner02
03.04.2010, 06:49
Ich glaub's kaum:

Gestern hatte ich anscheinend einen Chip geschrottet weil falsch angehängt (Stromversorgung versehentlich an PIN)

Heute nehme ich den nächsten Chip, und das Programm läuft.
Dann lade ich das Programm auf den 'kaputte' Chip - und siehe da: er läuft wieder!!


Bei ´ner Betriebsspannung von 3,2V, einer LED-Spannung von vielleicht 2,5V und einem Strom von 15mA wären das roundabout 50 Ohm.

Als Wiederstand hatte ich keinen 50 Ohm, darum habe ich 15+10+10 Ohm genommen. Die LED hat nicht geleuchtet, daher nahm ich einen weg.

Und das war der Beginn meiner ersten Blinkenden LED.

Welchen (Vor)widerstand brauche ich denn, wenn ich einen Schalter (Taster) einbauen will?

Sauerbruch
03.04.2010, 09:47
Und das war der Beginn meiner ersten Blinkenden LED.


Immer wieder schön, über was für Kleinigkeiten man sich freuen kann :-)


Welchen (Vor)widerstand brauche ich denn, wenn ich einen Schalter (Taster) einbauen will?

Wenn Du damit einen Eingang auf High oder Low legen möchtest, brauchst Du gar keinen Vorwiderstand, weil die Eingänge von sich aus äußerst hochohmig sind (ich glaube mehrere 100 MOhm). Deshalb müssen die Dinger auch immer einen definierten (!) Pegel führen - lässt man sie einfach unbeschaltet in der Luft hängen, fangen sie sich alle möglichen Störsignale ein.

Die Controller haben für jeden I/O-Port einen eingebauten PullUp-Widerstand, der den Eingang über ca. 50 kOhm auf +Ub zieht. Den aktiviert man mit PORTX.Y = 1. Damit liegt der Pin solange auf High, bis der Taster ihn mit Masse verbindet. Da der PullUp-Widerstand hochohmig ist, fließt auch nur ein sehr kleines Strömchen, wenn der Taster den +Ub-führenden Anschluss auf GND "zwingt".

Also in Kürze:
wenn ein I/O-Port als Eingang läuft, schaltet PORTX.Y den PullUp-Widerstand ein oder aus, und über PINX.Y wird der Zustand des Pins abgefragt.

o.K.?

runner02
04.04.2010, 09:32
Kleine Frage: +UB, was bedeutet das?


wenn ein I/O-Port als Eingang läuft, schaltet PORTX.Y den PullUp-Widerstand ein oder aus, und über PINX.Y wird der Zustand des Pins abgefragt.
Das heißt, sobald er ein Eingang ist, ist der Pullupwiderstand aktiviert.

Auf deutsch ich muss nur mehr den Pin mit der Masse verbinden, und dazwischen einen Schalter.
Der aktivierte Pull-up-Widerstand schützt den Chip von selbst?

PS: Frohe Ostern!

Sauerbruch
04.04.2010, 14:25
Kleine Frage: +UB, was bedeutet das?

Positiver Pol der Betriebsspannung (d.h. bei Dir 3,6V).


Das heißt, sobald er ein Eingang ist, ist der Pullupwiderstand aktiviert.

Nicht ganz. Ich versuch mal, die 4 möglichen Fälle systematisch darzustellen (am Beispiel des Anschlusses B.0):

DDRB.0 = 0: Anschluss ist als Eingang konfiguriert
PORTB.0 = 1: Interner PullUp-Widerstand aktiviert
PORTB.0 = 0: Interner PullUp-Widerstand nicht aktiviert

(Der logische Pegel am Eingangspin steht in PINB.0.)


DDRB.0 = 1: Anschluss ist als Ausgang konfiguriert
PORTB.0 = 1: Anschluss führt ein High-Signal
PORTB.0 = 0: Anschluss führt ein Low-Signal

(Der Registerplatz PINB.0 hat hier keine Bedeutung.)

Jetzt klarer??

Wenn so´n Anschluss als Eingang konfiguriert ist (DDRX.Y = 0), ist er wie gesagt extrem hochohmig. Das bedeutet für die Praxis folgendes:

1. kannst Du ihn ohne jeden Vorwiderstand mit + oder Masse verbinden. Es fließt praktisch kein Strom, und Du musst ihn auch nicht schützen.

2. Wenn Du ihn weder mit + noch mit Masse verbindest, hängt er "in der Luft". Und weil die Luft voll mit allem möglichen Elektrosmog ist, wird der Eingang ein vollkommen chaotisches Signalgewirr einfangen. Und das ist die Stunde des PullUp-Widerstandes:
Wenn er alleine am Werke ist, zieht er den Pin nämlich einerseits auf ein sauberes "High". Er ist aber andererseits so hochohmig, dass er definitiv den kürzeren zieht, wenn der Anschluss über einen Taster, einen Draht oder sonsteine gut leitende Verbindung auf Low gezogen wird - dagegen kommt er nicht an.

runner02
04.04.2010, 19:20
Also wenn er ein Eingang ist, kann man den Pull-up ein oder aussachalten...

Das müsste dann in C sein PINA=3, dann sind P0 und P1 pull-ups aktiviert, die anderen deaktiviert... ?


Zitat:
Kleine Frage: +UB, was bedeutet das?


Positiver Pol der Betriebsspannung (d.h. bei Dir 3,6V).
Bei mir steht immer Vcc, das ist also das selbe wie UB.



Jetzt muss ich nur mehr den Code finden, um if mit C zu programmieren...
Ich nehme an, die Pull-ups sind automatisch an, wenn sich sie nicht ausschalte...

Sauerbruch
04.04.2010, 22:46
Jetzt muss ich nur mehr den Code finden, um if mit C zu programmieren...

Das müsste dann in C sein PINA=3, dann sind P0 und P1 pull-ups aktiviert, die anderen deaktiviert... ?


In Bascom (!) werden die PullUps über das PORT-Register gesetzt, und nicht über PIN (erwähnte ich glaube ich schon mal...).

Wie das in C ist, darüber kann ich nur spekulieren. Aber auch für diese Sprache gibt´s ein extra Forum im RN:

https://www.roboternetz.de/phpBB2/viewforum.php?f=34


Ich nehme an, die Pull-ups sind automatisch an, wenn sich sie nicht ausschalte...

Dem ist definitiv NICHT so: Beim Einschalten steht in den DDR- und PORT-Registern &B00000000. Das heißt alle Anschlüsse sind erstmal als Eingänge ohne PullUps konfiguriert.

markusj
05.04.2010, 10:54
Nicht nur in Bascom, der Registerzugriff verhält sich bei beiden Programmiersprachen transparent so wie im Datenblatt deines AVRs beschrieben.
DDR auf Eingang -> PORT schaltet Pullup ein oder aus
DDR auf Ausgang -> PORT schaltet die "Leistungsstufe" auf "High" oder "Low"

mfG
Markus

runner02
05.04.2010, 15:44
Danke für die Mühe...


Aber auch für diese Sprache gibt´s ein extra Forum im RN:

Dann werd ich da mal bezüglich Input-befehle weiterposten.

Mfg

runner02
07.04.2010, 15:47
Es geht leider noch immer nicht...

Wie ist es eigentlich mit der Polung??

Die Led ist so geschalten: + 'Pol' ist der Ausgang des Chips, rinnt über die Led und auf den negativen Pol 'Masse', 'GND' (- der Batterie)


Den Schalter habe ich genau so eingebaut, ging nicht, anders gepolt, ging auch nicht

Also Beinchnen (+) -> Taster -> Masse (-)
???

Sauerbruch
07.04.2010, 16:22
Es geht leider noch immer nicht...

Verrat´ uns doch noch mal schnell, was es denn nochmal sein sollte...
und am besten den Code mit dazu - dann werden wir´s schon finden :-)

markusj
07.04.2010, 16:46
Stimmt so eigentlich.
Beim Taster schaltet man dann den Pullup ein. Folge: Drückst du den Taster nicht, zieht der Pullup den Eingang auf High, drückst du den Taster, liegt Low am Eingang an.
Bei der LED muss aber der Pin auf Ausgang geschaltet werden.

mfG
Markus

runner02
07.04.2010, 18:56
Gute Idee, poste hier mal den Code:




main () // Hauptprogramm, startet bei Power ON und Reset
{
DDRB=7;
PORTB=16;
if(PINB & (1<<PINB3))
{

// Schleifenanfang Mainloop
PORTB=17;
waitMs(500);
PORTB=19;
waitMs(250);
PORTB=18;
waitMs(250);
PORTB=17;
waitMs(100);
PORTB=16;
waitMs(1000); // Quellcode
}
while (true); // Schleifenende Mainloop



____

Komisch finde ich dabei auch, dass die Blinkfolge zuerst einmal läuft (ohne Taster, obwohl das eigentlich nicht sein sollte), sobald ich das System unter Strom setze.

Dann macht es aber nichts mehr, nicht einmal, wenn ich den Schalter drücke...

Sauerbruch
07.04.2010, 19:33
Wieso postest Du das ganze eigentlich in einem Bascom-Forum? :-)

runner02
07.04.2010, 20:17
Oh, da habe ich mich (wohl über die Suchfunktion) ins falsche Thema verirrt... ](*,) 8-[