Hallo!
Ich hab es endlich mal geschafft mich an die Microcontrollersachen
ranzusetzen. Ich hab folgenden Code als Test genutzt:
1
/* Alle Zeichen zwischen Schrägstrich-Stern
2
und Stern-Schrägstrich sind lediglich Kommentare */
3
4
// Zeilenkommentare sind ebenfalls möglich
5
// alle auf die beiden Schrägstriche folgenden
6
// Zeichen einer Zeile sind Kommentar
7
8
#include<avr/io.h> // (1)
9
10
intmain(void){// (2)
11
12
DDRB=0xff;// (3)
13
PORTB=0x03;// (4)
14
15
while(1){// (5a)
16
/* "leere" Schleife*/;// (5b)
17
}// (5c)
18
19
/* wird nie erreicht */
20
return0;// (6)
21
}
Nutzen tu ich AVR STK500 mit AVR Studio. Bei der Simulation funktioniert
alles prima. PortB 0 und 1 werden auf logisch 1 gesetzt, somit sollten
ja eigentlich auch die LED's 0 und 1 leuchten. Allerdings leuchten bei
mir alle ausser die ersten beiden. Warum invertiert er es?!
LG Max
Ich glaub das liegt auch an den ersten AT90... MC's. Der AT902313 konnte
20mA bei 5V als Senke aber nur 3mA bei 5V als Quelle (lt. Datenblatt S.
72/73). Ein Mega8 kann in beide Richtungen 20mA.
Yep, und die AT90 haben das so gemacht, weil gewisse Standardchips der
Branche, Intels 8051, praktisch garnicht nach oben ziehen (50µA),
sondern nur nach unten. Und die noch älteren TTLs auch lieber runter als
hoch ziehen. Und sich folglich alle Welt längst daran gewöhnt hatte. Und
die 8051er haben das auch deshalb so gemacht, weil die dafür
ursprünglich verwendete NMOS Technik das nahelegt.
> Hm... Aber es ist schon richtig PB0 = 1 und PB1 = 1 und der Rest> Null ist? Sprich an PB0 und PB1 liegen 5V an?
So ist es. Und die anderen Enden der angeschlossenen LEDs liegen
ebenfalls an 5 V, d. h. die Spannungsdifferenz zwischen den
LED-Anschlüssen beträgt 0 V, was Dunkelheit ergibt.
Aber bei dem SKT Board sind die LED's mit Transitoren geschaltet. Sprich
wenn an der Basis 5V anliegen schaltet der Transitor in den Aktivbereich
und somit fließt Strom. Warum fließt denn scheinbar hier keiner?!
> Sprich wenn an der Basis 5V anliegen schaltet der Transitor in den> Aktivbereich und somit fließt Strom.
An der Basis liegt immer die Versorgungsspannung des µC an, der
µC-Ausgang ist mit dem Emitter verbunden (STK500 User Guide, S. 12).
Der Transistor wird in Basisschaltung eingesetzt, d. h. die Schaltung
ist nicht invertierend (im Gegensatz zur Emitterschaltung, die oft als
LED-Treiber eingesetzt wird).
Wenn der µC-Ausgang low ist, fließt ein Basisstrom, dadurch leitet der
Transistor und die LED leuchtet.
Der Transistor hat in dieser Schaltung keine stromverstärkende
Wirkung, sondern ermöglicht es, die LEDs (oder genauer gesagt die
Serienschaltung aus LED und Vorwiderstand) unabhängig von der
Versorgungsspannung des µC (VTG) immer mit 5 V betreiben zu können.
Warum die Atmel-Jungs keine Emitterschaltung verwenden, die diesen
Vorteil ebenso hat und zusätzlich den µC-Ausgang entlastet, ist mir
unklar. Möglicherweise wollen sie demonstrieren, dass der µC-Ausgang
für sich alleine in der Lage ist, den nötigen Strom aufzubringen. Für
VTG = 5 V ist der Transistor tatsächlich überflüssig.
Wenn der uC Ausgang auf Low ist, sprich 0V warum fließt da eine
Basisstrom? LEDn gehe ich einfach mal davon aus, dass das GND ist?! Also
wenn der uC Ausgang 0V hat ist die Spannung kleiner 0.6V folglich sperrt
der Transistor. Somit fließt auch kein Strom von oben 5+ nach LEDn. Wenn
jetzt der uC Ausgang auf Logisch 1 gesetzt wird (also 5V), liegt dort
eine Spannung größer 0.6V an folglich sollte der Transitor leiten und es
sollte ein Strom von 5+ durch die Diode nach LEDn fließen. Irgendwie
habe ich da noch einen Logikfehler!? Sorry wenn ich so hartnäckig frage,
aber ich will ja auch irgendwann meine eigenen Schaltungen aufbauen, und
dann wäre es schon von Vorteil, wenn ich das begriffen habe.
Noch eine andere Frage! :)
Warum wird das true. Ein Bit-Beispiel würde mir reichen! ;)
1
/* Fuehre Aktion aus, wenn Bit Nr. 1 (das "zweite" Bit) in PINC gesetzt (1) ist */
Maximilian Lang wrote:
> Noch eine andere Frage! :)> Warum wird das true. Ein Bit-Beispiel würde mir reichen! ;)>
1
>/* Fuehre Aktion aus, wenn Bit Nr. 1 (das "zweite" Bit) in PINC gesetzt
2
> (1) ist */
3
>if(PINC&(1<<PINC1)){
4
>/* Aktion */
5
>}
6
>
>> Ganz lieben Dank für die Hilfe bis jetzt schon!
PINC1 ist ein Makro und expandiert zu 1
1 << PINC1 wird also zu 1 << 1
Das ist eine binäre 1 0b00000001
die 1 mal nach links geschoben wird 0b00000010
PINC & 0b00000010
der Inhalt von PINC wird geholt (also der Porteingang abgefragt)
und Bit für Bit mit 0b00000010 UND Verknüpft
A B | A und B
----------|------------
0 0 | 0
1 0 | 0
0 1 | 0
1 1 | 1
Wir beobachten:
Wenn B 0 ist, dann ist das Ergebnis von A und B auf jeden Fall
0. Wenn B aber 1 ist, dann entspricht das Ergebnis genau dem
Zustand von A. Der & Operator in C macht genau diese UND Verknüpfung,
allerings für alle 8 Bitpositionen gleichzeitig (und für alle
8 Bitpositionen unabhängig von den anderen Bitpositionen)
d.h. bei
PINC & 0b00000010
ist im Ergebnis an allen Stellen in denen in 0b00000010 eine 0
steht auf jeden Fall eine 0. Dort wo in der Maske 0b00000010 eine
1 steht, wird im Ergebnis der Bitzustand von PINC an aben jener
Bitposition auftauchen. Da in der Maske aber nur ein einziges
1 Bit ist, kann das Ergebnis daher nur 0b00000000 (also 0) oder
0b0000010 (also 2) sein, je nachdem ob in PINC an dieser Bitposition
eine 0 oder eine 1 war.
Und dann greift da noch eine C Regel, die da lautet:
Bei boolschen Entscheidungen gilt: Ein Wert von 0 wird als logisch
falsch (FALSE) gewertet, ein Wert ungleich 0 als logisch wahr (TRUE).
Hat PINC & ( 1 << PINC1 ) als Ergebnis eine 0, dann ist der gesammte
Ausdruck somit logisch falsch.
Hat PINC & ( 1 << PINC1 ) als Ergebnis aber 2, so gilt das als
logisch wahr und der if führt seine abhängige Anweisung aus.
Hast du dir das Bild im User Guide angeschaut? Im Anhang ist es noch
einmal, damit wir von der gleichen Sache sprechen.
> Wenn der uC Ausgang auf Low ist, sprich 0V warum fließt da eine> Basisstrom?
Weil dann der Emitter des Transistors auf einem niedrigeren Potential
liegt als die Basis.
> LEDn gehe ich einfach mal davon aus, dass das GND ist?!
Den Satz habe ich nicht verstanden.
> Also wenn der uC Ausgang 0V hat ist die Spannung kleiner 0.6V> folglich sperrt der Transistor.
Die Basis-Emitter-Spannung ist nicht kleiner als 0,6 V (s. o.).
> Wenn jetzt der uC Ausgang auf Logisch 1 gesetzt wird (also 5V),> liegt dort eine Spannung größer 0.6V an
Nein, dann ist die Basis-Emitter-Spannung VTG - 5 V = 0 V (ich nehme
an, dass bei dir VTG = 5 V ist).
> folglich sollte der Transitor leiten und es sollte ein Strom von 5+> durch die Diode nach LEDn fließen.
folglich eben gerade nicht.
> Irgendwie habe ich da noch einen Logikfehler!?
So sieht's aus :-)
Ich hoffe aber, jetzt nicht mehr.
> Warum wird das true. Ein Bit-Beispiel würde mir reichen! ;)
Folgende Konstanten tauchen in dem Ausdruck auf:
1: 00000001 (bin)
und
PINC1: 1 (dez)
Damit ist
1 << PINC1: 00000010 (bin)
Fall 1: an PC1 liegt ein High-Pegel an:
PINC: xxxxxx1x (bin, x ist irgendetwas)
PINC & (1<<PINC1) ist die bitweise Und-Verknüpfung:
xxxxxx1x
& 00000010
----------
00000010
Das Ergebnis von Null verschieden, damit ist die Bedingung wahr, und
der If-Zweig wird ausgeführt.
Fall 2: an PC1 liegt ein Low-Pegel an:
PINC: xxxxxx0x (bin, x ist irgendetwas)
PINC & (1<<PINC1) ist die bitweise Und-Verknüpfung:
xxxxxx0x
& 00000010
----------
00000000
Das Ergebnis ist Null, damit ist die Bedingung falsch, und der
If-Zweig wird nicht ausgeführt.
> Ganz lieben Dank für die Hilfe bis jetzt schon!
Keine Ursache. Viel Spass beim Basteln.
> Warum die Atmel-Jungs keine Emitterschaltung verwenden
Hat vielleicht etwas mit Atmels 8051ern zu tun. Die können zu wenig
Basisstrom liefern, daher muss man dort andere Lösungen finden.
Wieder mal ein großes Danke! Im Gegensatz zu der Linuxgemeinde wird hier
ja richtig geholfen! :-D
@yalu
Ja genau das Bild ist das. Hm... verstehen tu ich das aber immer noch
nicht... :'( Hatten das in der Uni und eigentlich habe gedacht, dass ich
ihn verstanden habe... :(
Also erstmal Schritt für Schritt. Versteh nicht wo es bei mir hackt. Das
ist doch ein NPN Transistor? (links Basis, unten Emiter, oben Kollektor)
LEDn := 0V (sage ich jetzt einfach mal. Ist ja Schaltungsabhängig)
Wenn ja, cool schonmal eines richtig. So wenn ich jetzt den uC Ausgang,
sprich VGT auf Ov (logisch 0) setze, dann ist doch die Spannung VGT-LEDn
= -0.6V, weil die über den Transistor 0.6V abfallen!? Also sollte er
doch sperren!? Warum tut er es nicht?
So wenn ich jetzt den uC Ausgang, sprich VGT auf 5V (logisch 1) setzt,
dann ist doch die Spannung VGT-LEDn = 5V. Somit fallen am 10K
Wiederstand 4.4V ab, weil VGT-0.6V. Somit fließt ein Basisstrom von
0.44mA?! Dadurch leitet der Transistor, wodurch dann ein Strom
Ic=0.44mA*Verstärkung fließt.
Ist das jetzt falsch??? :'(
Na ja dafür hat ich das mit den Bit verstanden. Eigentlich ist das ja
echt peinlich, denn wissen sollte ich das eigentlich. Na ja lieber
fragen als dumm sterben! ;)
Kann ich denn mithilfe von UART zwei uC untereinander kommunizieren
lassen. Denn wenn das alles so läuft will ich später mal eine LCD haben
der von einen uC gesteuert wird. Dieser sendet dann die "Auswahl" an
einen anderen uC der dann die Aktion ausführt. Hat einfach den Sinn,
dass ich für die LCD Steuerung aus Platzgründen keinen so großen uC
brauche und ich nicht so viele Kabel ziehen muss. Ein Beispiel wäre eine
Lichtersteuerung fürs Auto. LCD->Fußraumbeleuchtung an->uC1 sendet
Befehl an uC2->Schaltet einen Mosfet oder NPN :'(. Das so finde ich ein
gutes Thema bzw. Projekt um in das ganze reinzukommen. Scheint mir nicht
so schwer aber auch nicht zu leicht zu sein.
Fals jetzt Can fallen sollte. Ja habe ich schon von gehört und weißt
auch ungefähr wie es funktioniert. Allerdings nur von der Theorie! :-D
Wie kann es auch anders sein... :)
NOCHMAL DANKE! :D
>So wenn ich jetzt den uC Ausgang,>sprich VGT auf Ov (logisch 0) setze,
Der Ausgang des uC liegt nicht an der Basis an. Das steht schon oben
von:
Autor: yalu (Gast)
Datum: 13.06.2007 01:37
>dann ist doch die Spannung VGT-LEDn>= -0.6V, weil die über den Transistor 0.6V abfallen!? Also sollte er>doch sperren!? Warum tut er es nicht?
Weil die Schaltung nicht so wie Du es beschreibst aufgebaut ist.
>Ist das jetzt falsch??? :'(
Ja, aus oben genannten Gründen
>Fals jetzt Can fallen sollte. Ja habe ich schon von gehört und weißt>auch ungefähr wie es funktioniert. Allerdings nur von der Theorie! :-D>Wie kann es auch anders sein... :)
CAN ist auf jeden Fall die Einarbeitung wert. Dir wird wahrscheinlich
sowas auch mehr liegen als Transistorschaltungen, nehme ich mal an?
Der Anschluss eines CAN-Transceivers lässt abgesehen von der
Terminierung nur eine Variante zu, das macht doch Mut ;)
>Eigentlich ist das ja echt peinlich, denn wissen sollte ich das eigentlich.
Man kann ja nicht alles Wissen, aber vieles Lesen und evtl. verstehen
>Na ja lieber fragen als dumm sterben! ;)
Respektable Einstellung
Maximilian Lang wrote:
> Also erstmal Schritt für Schritt. Versteh nicht wo es bei mir hackt.
Du hast die falsche Schaltung im Hinterkopf.
Wann leitet ein npn Transistor? Wenn in die Basis ein
Strom hineinfliesst, der am Emitter wieder herauskommt.
Die LED und der Widerstand da rechts oben spielen keine Rolle
bei der Überlegung wann den der Transistor leitet.
Ausgang des µC auf 1:
Am Emitter liegen 5V an.
An der Basis liegen 5V an (bei VTG = 5V)
Ergo: -> keine Spannungsdifferenz zwischen Basis und Emitter.
-> kein Strom der in die Basis hineinläuft
-> der Transistor sperrt
-> dadurch kann auch kein Strom vom Collektor zum
Emitter laufen: die LED leuchtet nicht
Ausgang des µC auf 0:
Am Emitter liegen 0V an
An der Basis liegen (vor dem R) immer noch 5V an
Ergo: -> es gibt eine Spannungsdifferenz zwischen Basis und Emitter
-> Strom rinnt in die Basis hinein
-> der Transistor macht auf
-> dadurch kann auch Strom vom Collektor zum Emitter
laufen: die LED leuchtet
ACHHH SOOOOOOOOOO!!!! Der uC liegt am Emitter an!? Dann wäre das
natürlich logisch und ich glücklich, weil ich die Transistoren scheinbar
doch verstehe! :D hüpf durch die Gegend Wenn das so sein sollte fließt
da nicht der ganze Strom in den uC rein!?
Hab mal ein bißchen rumgespielt.
1
intmain(void)
2
{
3
//Definieren der Ausgänge
4
5
DDRB|=(1<<PB0);//(1)
6
PORTB&=(1<<PB0);//(2)
7
8
while(1)
9
{
10
//Programm
11
if(PORTB&(1<<PB0))//(3)
12
{
13
PORTB&=(1<<PB1);//(4)
14
}
15
else
16
{
17
PORTB&=(1<<PB2);//(5)
18
}
19
}
20
return0;
21
}
So was ich eigentlich will ist.
(1) Setzt PinB0 als Ausgang
(2) Setzt den PinB0 auf logisch 0 (also LED leuchtet; Tut es auch :])
(3) Das so eine kleine Spielerei. Ohne Sinn! ;)
Zu mindest sollte (4) ausgeführt werden. Es wird aber (5) ausgeführt. So
habe ich das gedacht
PORTB: 00000001
PB0: 00000001
&--------------------
00000001
folglich doch eine wahre Aussage!? Das war Problem Nummer eins. Problem
Nummer zwei ist, da ja (5) ausgeführt wird, warum leuchtet die LED
nicht?
Das werden erstmal die letzten Fragen sein. Dann wühle ich mich selber
erstmal durch! ;)
LG Max
Maximilian Lang wrote:
> Wenn das so sein sollte fließt> da nicht der ganze Strom in den uC rein!?
Das tut er, und das war auch oben bereits erwähnt worden: die
Basisschaltung hat keine Stromverstärkung. Das macht aber nichts,
da ein Controller (selbst die alten 8051) eben den Strom einer LED
locker in seinem Ausgang versenken kann. In einer normalen
Schaltung (mit fester Betriebsspannung) brauchst du daher gar keinen
Transistor erst dafür, sondern klemmst sie gleich mit Widerstand
an die Versorgungsspannung. Der ganze Sinn des Transistors im STK
ist eben nur, die Helligkeit der LED unabhängig von Vtarget des
Controllers zu haben.
Maximilian Lang wrote:
>> folglich doch eine wahre Aussage!? Das war Problem Nummer eins. Problem> Nummer zwei ist, da ja (5) ausgeführt wird, warum leuchtet die LED> nicht?
Schalte erst mal die beiden Port Pins auf Ausgang.
Maximilian Lang wrote:
> folglich doch eine wahre Aussage!? Das war Problem Nummer eins.
1. Karl Heinz Bucheggers Post hier drüber lesen und beachten.
2. Für Abfragen vom Port benutze immer PINx nicht PORTx (Siehe deinen
ersten Post oben). Denn: PORTx fragt immer das Ausgaberegister ab, PINx
das Eingaberegister.
PS: Sieht aber ansonsten nicht schlecht und vorallem wesentlich
erfolgreicher als so manch anderer Kollege (Thomas4711 oder so :D) aus.
Hmm... Stimmt habe vergessen PB1 und 2 auf Ausgang zu setzen... Mal ne
Frage zu "PIN". Braucht man das nicht nur, wenn man einen Pin als
Eingang geschaltet hat und dessen Status haben will?! Aber ich will ja
den Status des Ausganges haben. Also ob der 1 oder 0 ist. Muss man das
trotz Ausgang auch mit Pin machen?!
Maximilian Lang wrote:
> Hmm... Stimmt habe vergessen PB1 und 2 auf Ausgang zu setzen... Mal ne> Frage zu "PIN". Braucht man das nicht nur, wenn man einen Pin als> Eingang geschaltet hat und dessen Status haben will?!
Ganz genau
> Aber ich will ja> den Status des Ausganges haben. Also ob der 1 oder 0 ist. Muss man das> trotz Ausgang auch mit Pin machen?!
Langsam. Welchen Wert willst du wirklich haben. Den Status
so wie du ihn rausgeschrieben hast oder den Status den
der Pin tatsächlich eingenommen hat. Beides ist nicht
notwendigerweise identisch. Ich sag einfach mal: Kurzschluss
am Pin. Da kannst du eine 1 auf den Port schreiben soviel
du willst, der Pin ist trotzdem 0.
Aber im Prinzip kannst du das so machen. (Mittels PORT
abfragen, was du zuletzt ausgegeben hast)
Ah ok! Verstanden.
So jetzt eigentlich die letzte Frage, dann geht es los mit meinem
Projekt. :)
Wie verbinde ich mehrer Controller untereinander. Mit UART kann man ja
scheinbar nur zwei verbinden... :(
Jetzt kommt der schon von Dir erwartete Verweis auf den CAN-BUS :)
Es geht natürlich mit jedem anderen BUS auch. CAN, LIN, I2C sind aber
oft schon in Hardware auf den uC vorhanden und bieten sich daher
besonders an.
Gruss,
Edson
Ok dann frage ich mal so. Wie würde man folgende Schaltung anlegen.
uC zur Steuerung des Menu-LCD. Dieser sendet dann die Auswahl an einen
weiteren uC der dann die Infos an die jeweiligen Steuer Controller
weiterleitet. So im groben... Hab mir da noch keine Gedanken gemacht.
Aber es werden auf jeden Fall mehrere Controller. Kostenmässig sollte
sich das auch im Rahmen halten, weil es nur ein privat Projekt ist. :)
Maximilian Lang wrote:
> Wie kritisch?
Anders als bei z. B. I²C hat der SPI-Slave keine Möglichkeit, dem
Master zu signalisieren, ob er die gewünschten Daten nach dem slave
select nun bereits verfügbar hat. Typischerweise schiebt ein Master
zuerst sowas wie ein Kommandobyte raus und danach dann ein Dummy-Byte,
um die gewünschten Daten abzuholen. Das funktioniert prima, wenn der
Slave in Hardware realisiert ist, da er dann nur einige Nanosekunden
nach dem Kommando braucht, um die Daten bereit zu stellen. U. U. kann
er die ersten internen Schaltaktionen bereits durchführen, nachdem die
ersten beiden Bits des Kommandos rein sind... Anders ein Controller,
der muss erst auf das Ende des Kommandos warten und kann danach erst
entscheiden.
Man kann das natürlich auf der Basis von gegenseitigen ,Absprachen'
lösen, wenn man will.
So wie ich es jetzt rauslesen konnte scheint also es eine gute Wahl zu
sein einen I²C Bus zu nehmen. Wo kann man denn nachlesen, wie man sowas
nutzt?
Was ich nämlich machen will.
Ein Controller der den LCD steuert. Der sendet die Menüauswahl an einen
Controller im Kofferraum, der sich dann unter anderem Informationen wie
Spannung, Temperatur. etc. holt und dann an den LCD zurücksendet.
Ich hab mal so ein schnelles Bild gemacht, wo man sehen kann, was ich
machen will... :) Kann man das so machen?
Ich hab da so einen Beitrag von MMC/SD Bootloader gesehen. Hab ich das
richtig verstanden, dass der Code praktisch von dem MMC Baustein läuft.
Das wäre nämlich schon sehr praktisch, weil ich bei Updates nur die MMC
Karte rein tun muss, mit dem aktuellem Code! :)
LG Max