Hallo ich habe gerade Probleme bei dieser Aufgabe und würde mich freuen wenn mir jemand Tipps geben kann. Zum Test ist ein main-Programm zu schreiben, das die Funktionen aufruft und ihre korrekte Funktionsweise nachweist. Wo das sinnvoll ist, soll eine Funktion mehrfach mit korrekten und nicht korrekten Parameterwerten getestet werden (mehrere Testfa?lle). Initialisiert PortA als Eingang mit aktivierten Pullup-Widersta?nden und PortB als Ausgang, schaltet alle LEDs aus. Hinweis: Inkludieren Sie avr/io.h. void putByteLED_B(unsigned char byte); Gibt einen 8-Bit-Wert auf die an PortB angeschlossenen LEDs aus. An Bit-Positionen mit dem Wert 1 soll die zugeho?rige LED leuchten. Hinweis: Aufgrund der Beschaltung der LEDs auf dem Evaluationsboard leuchtet eine LED, wenn eine 0 auf das Port-Pin ausgegeben wird, an das sie angeschlossen ist. unsigned char waitforKey_A() Wartet auf eine Eingabe vom Benutzer u?ber die an PortA angeschlossenen Tasten. Dabei soll es egal sein, welche Taste bzw. ob mehr als eine Taste gedru?ckt wird. Gibt den invertierten Inhalt zuru?ck, den das PINA- Register bei Tastendruck hat (Tastencode), so dass der Ru?ckgabewert an der Position einer gedru?ckten Taste eine 1 entha?lt. Hinweise: Beachten Sie, dass PINA den Inhalt 0xff hat, wenn keine Taste gedru?ckt ist. Der Tastendruck ist erst abgeschlossen, wenn der Benutzer die Taste wieder losgelassen hat. Um eine Reaktion des Programms auf evtl. auftretendes Tastenprellen zu verhindern, sollte die Funktion mit Hilfe von delay_ms (Funktion der AVR-Lib-C) eine kurze Zeit abwarten ehe sie zuru?ckkehrt. Hinweis: Inkludieren Sie util/delay.h. unsigned char getKeyNum(unsigned char sw) Wandelt den Tastencode sw (wie von waitforKey_A() geliefert), in die Nummer der gedru?ckten Taste um, so wie sie auf dem Evaluationsboard bezeichnet sind (niederwertigstes Bit entspricht der Taste 0, ho?chstwertiges Bit der Taste 7). Hinweise: Die Funktion liefert einen Wert zwischen 0 und 7 zuru?ck. Sollte mehr als eine Taste gedru?ckt worden sein, so liefert sie den Wert 255 (0xff) zuru?ck. Beispiele: sw = 0x80 (Taste SW7 wurde gedru?ckt), getKeyNum() liefert den Wert 7 zuru?ck sw = 0x03 (Tasten SW1 und SW0 wurden gedrückt), getKeyNum() liefert den Wert 255 zuru?ck Hat jemand Tipps wie ich schon mal die erste Funktion proggrammieren kann?
:
Verschoben durch User
Hallo, was sagt denn das Vorlesungsskript zum Thema Portinitialisierung? Um welches Board mit welchem Controller handelt es sich hier?
Das AVR-Tutorial findet sich oben links. Zusammen mit den Vorlesungsunterlagen sollte das alle Fragen bzgl. der AVR-Details beantworten. Der Rest steht in deinem C-Buch. Oliver
Da stehts: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports Aber das hättest du eigentlich auch selber finden können.
Entwickler21 schrieb: > Initialisiert PortA als Eingang mit aktivierten Pullup-Widersta?nden und > PortB als Ausgang, schaltet alle LEDs aus. > Hinweis: Inkludieren Sie avr/io.h.
1 | #include <avr/io.h> |
2 | |
3 | static void init (void) |
4 | {
|
5 | DDRA = 0x00; // set all PORTA pins to input |
6 | |
7 | PORTB = 0xff; // PORTB: all outputs high (LED off) |
8 | DDRB = 0xff; // set all PORTB pins to output |
9 | }
|
10 | |
11 | int main (void) |
12 | {
|
13 | init (); |
14 | |
15 | while (1) |
16 | {
|
17 | ;
|
18 | }
|
19 | |
20 | return 0; |
21 | }
|
> [...} > Hat jemand Tipps wie ich schon mal die erste Funktion proggrammieren > kann? Habt Ihr das nicht gelernt (Seminar oder Vorlesung) oder hast Du die ganze Zeit nur geschlafen? Du kannst Dir ja mal Gedanken machen, warum ich erst PORTB und dann erst DDRB setze... Den Rest musst Du aber selber machen. Viel Spaß.
PortB als Ausgang, schaltet alle LEDs aus. Hinweis: Inkludieren Sie avr/io.h. void putByteLED_B(unsigned char byte); Weißt du wie ich hier die erste Funktion proggrammieren kann ?
Lässt du dir jetzt hier Schritt für Schritt alle deine Aufgaben von uns lösen? Was hast du denn bis jetzt von
1 | void putByteLED_B(unsigned char byte); |
implementiert? Und was funktioniert nicht? Wo hast du Verständnisschwierigkeiten?
Entwickler21 schrieb: > PortB als Ausgang, schaltet alle LEDs aus. > Hinweis: Inkludieren Sie avr/io.h. > > void putByteLED_B(unsigned char byte); > > Weißt du wie ich hier die erste Funktion proggrammieren kann ? Früher habe ich hier viele nicht verstanden, wenn sie einfach mit "Ja!" geantwortet haben. @TO Ich habe nicht studiert und lerne das alles neben Beruf und Haushalt und ich bin schon 51 Jahre alt. Wenn du schon so durchs Abi gekommen bist, dann wird es jetzt wohl mal Zeit ein wenig zu lernen.
:
Bearbeitet durch User
> Habt Ihr das nicht gelernt (Seminar oder Vorlesung) oder hast Du die > ganze Zeit nur geschlafen? Eine Äußerung auf ein eventuelles schlafen, naja.. > Du kannst Dir ja mal Gedanken machen, warum ich erst PORTB und dann erst > DDRB setze... ...was aber falsch ist, wie du weißt. Schau mal im ATmel Datenblatt rein, z.b. bei ATmega8. Hier ist es generell (von der Logik her) so, dass du erst die Flussrichtung der Daten angibst, und dann die Ausgänge definierst. Optional kannst du es vlt. sogar im AVR GGC Tutorial nochmals nachlesen, oder dir einfach von einen Entwickler sagen lassen, der 20 Jahre berufserfahrung hat, dass es so einfacher ist. Mfg, tommyProg
F. Fo schrieb: > ich bin schon 51 Jahre alt. Lass Sie nicht so spüren, dass Sie anders sind als wir ;-)
Reinhard ## schrieb: > F. Fo schrieb: >> ich bin schon 51 Jahre alt. > > Lass Sie nicht so spüren, dass Sie > anders sind als wir ;-) :-) Ich habe auch die Vermutung unser "Holz" stirbt aus.
Tho Wes schrieb: > ...was aber falsch ist, wie du weißt. Radio Eriwan: Das kommt darauf an. Im konkreten Fall sind die LEDs low aktiv. Wenn ich erst PORTB auf 0xFF setze, dann schalte ich damit die Pullups ein. Das bewirkt für die LEDs: Genau nichts. Dann schalte ich die Richtung um. Die LEDs werden also nicht aufblitzen. Jetzt andersherum: Zuerst DDRB auf 0xFF. Folge: Die LEDs gehen an, da low-aktiv. Dann PORTB auf 0xff. Folge: die LEDs gehen wieder aus. > Schau mal im ATmel Datenblatt rein, z.b. bei ATmega8. Ja und? Es kommt auf den Ruhezustand an, welche Reihenfolge Du wählst. > Hier ist es generell (von der Logik her) so, dass du erst die > Flussrichtung der Daten angibst, und dann die Ausgänge definierst. Wenn der ATmega hinreichend langsam genug läuft, äussert sich das aber in einem kurzen Lichtblitz, der nicht erwünscht ist. > Optional kannst du es vlt. sogar im AVR GGC Tutorial nochmals nachlesen, Zitat aus: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ausg.C3.A4nge ------ Für Ausgangspins, die mit Anfangswert "high" initialisiert werden sollen: zuerst die Bits im PORTx-Register setzen anschließend die Datenrichtung auf Ausgang stellen Daraus ergibt sich die Abfolge für einen Pin, der bisher als Eingang mit abgeschaltetem Pull-Up konfiguriert war: setze PORTx: interner Pull-Up aktiv setze DDRx: Ausgang ("high") ------ Tja, was sagst Du jetzt? > oder dir einfach von einen Entwickler sagen lassen, der 20 Jahre > berufserfahrung hat, dass es so einfacher ist. Sorry, bei mir sind es 25. :-P
Was erwartet ihr von einem Lernenden, der nicht mal in der Lage ist, eine glasklare Frage zur µC-Programmierung im µC-Forum zu erstellen, sondern ins PC Forum postet? <Thread verschoben>
> Tja, was sagst Du jetzt?
Okay, dann hatte ich noch nie einen so langsamen Prozessor, dass der
Fall vorkommt, und die Ausgänge kritisch sind.
Nach diesr Quelle (habs grad gelesen) hast du recht. Nach ATmel
Datenblatt konnte ich aber den Fall nicht finden, vlt. ist der ATmega8
nicht langsam genug xD.
Mfg,
tommyProg
Frank M. schrieb: >> Hier ist es generell (von der Logik her) so, dass du erst die >> Flussrichtung der Daten angibst, und dann die Ausgänge definierst. > > Wenn der ATmega hinreichend langsam genug läuft, äussert sich das aber > in einem kurzen Lichtblitz, der nicht erwünscht ist. Steht auch in keinem meiner Bücher anders, aber gut zu wissen. Wieder was gelernt. Und diesen Effekt hatte ich auch (das Aufblitzen) hatte ich auch schon mal gesehen. Guter Tipp.
Lese dir bitte die ersten Schritte durch und fang mal an zu lernen :) Ihr sterbt nicht aus .. bin selbst erst 24 Jahre und hab vor 1,5 Jahren mit dem uC Lernen/Basteln angefangen.
Tho Wes schrieb: > Nach ATmel > Datenblatt konnte ich aber den Fall nicht finden In den Datenblättern steht überhaupt nichts dazu. Insbesondere steht dort auch nicht, dass man nicht zu jedem Zeitpunkt die Datenrichtung umschalte könnte. Der Rest ist dann nur noch 2 und 2 zusammenzählen. Zugegeben, der Effekt ist nicht sehr stark. Wenn man es aber weiß, es dunkel genug ist, man senkrecht in die LED hineinsieht und darauf achtet, dann kann man als Mensch dieses Aufblitzen auch bei 16Mhz noch sehen.
> Wenn der ATmega hinreichend langsam genug läuft, äussert sich das aber > in einem kurzen Lichtblitz, und wenn statt einer LED der Enable-Eingang des Fluxcompensators angeschlossen ist, katapultiert es einen ungewollt in eine andere Zeit... Scherz bei Seite: Bei manchen Anwendgunen kann auch was kaputt gehen: Zb. Bei einer Halbbrücke mit Mosfets wenn gleichzeitig zwei schalten oder so...
flups schrieb: > Scherz bei Seite: Bei manchen Anwendgunen kann auch was kaputt gehen: > Zb. Bei einer Halbbrücke mit Mosfets wenn gleichzeitig zwei schalten > oder so... 1+ dafür. Ist wirklich wichtig und richtig. Schön dass ich das lesen und lernen durfte.
flups schrieb: > Zb. Bei einer Halbbrücke mit Mosfets wenn gleichzeitig zwei schalten > oder so... Oder ganz banal: Bei Soft-SPI kann eine ungewollter Takt oder Chip-Select erzeugt werden.
Okay, dann macht es wirklich viel aus. Aber kann mir bitte jemand ganz genau erklären, (Architekturmäßig), warum dass dann passieren kann? Blick da nicht so durch, wenn ich anfangs in der main (bevor was leuchtet oder was angesteuert wird) die Datenrichtung angegeben wird, und ich eine Zeile drunter gleich meinen Port definiere, ist doch dassselbe Wie als wenn ich erst den Port definiere, und dann meine Datenrichtung angebe? ersteres mache ich(scheinbar falsch), zweiteres findet ihr für besser. Das Steuerregister weiß doch sowieso erst ab den Moment wo DDR'x' reingeschrieben worden ist, wie der Port beschaltet wird, und was da Ausgang und Eingang ist. Versteh ich wirklich (technisch) garnicht. Bitte um Erklärung. Mfg, tommyProg
Tho Wes schrieb: > und ich eine Zeile drunter gleich meinen Port definiere, ist doch > dassselbe Wie als wenn ich erst den Port definiere, und dann meine > Datenrichtung angebe? Nein. Es gibt 2 Fälle. * Wenn der Pin nach dem Einschalten auf 0 gehen (bzw. bleiben soll). Dann setzt du das DDR auf Ausgang und meientwegen noch den Pin auf 0. Alles ist gut, weil das Portregister nach dem Stromanlegen sowieso auf 0 war. * Wenn der Pin nach dem Einschalten auf 1 gehen soll Machst du da dieselbe Reihenfolge, dann ist der Pin zwischen dem Setzen des DDR Registers und dem Ausgeben des 1 Bits kurze Zeit auf 0. Denn das war ja der Default nach dem Einschalten.
1 | // bis hier hier ist der Pin im Tri-State
|
2 | DDRB = ( 1 << PB0 ); |
3 | // jetzt ist der Pin auf Ausgang und gibt eine 0 aus
|
4 | PORTB = ( 1 << PB0 ); |
5 | und erst jetzt gibt der Pin eine 1 aus |
Änderst du aber die Reihenfolge: zuerst das Port Register und dann das DDR Register, was passiert dann. Nach dem Einschalten liegt der Zustand vor: DDR ist auf 0 und damit Eingang. PORT ist auf 0 und damit ist an diesem Eingangspin der Pullup abgeschaltet. Der Pin ist also im Tristate - der µC beeinflusst die Leitung an diesem Pin in keinster Weise. Jetzt kommt zuerst das PORT Register an die Reihe. Du schreibst eine 1 ein. Was passiert? Der Pullup wird aktiviert. Damit wird die Leitung auf 1 gezogen. Das ist ja schon mal nicht schlecht, das wollen wir in letzter Konsequenz ja auch. Dann schaltest du mit dem DDR auf Ausgang. Durch das Umschalten auf Ausgang wird der Pullup weggeschaltet, aber dafür klemmt sich jetzt der Ausgangstreiber an den Pin. Und da im Port Register immer noch das 1 Bit steht, treibt der Ausgangstreiber die angehängte Leitung auch weiterhin auf 1. zu keinem Zeitpunkt lag nach dem Einschalten ein aktives 0 Bit am Ausgangspin. Der Pin war entweder im Tristate oder er wurde auf 1 gezogen. Zuerst vom Pullup und dann vom Ausgangstreiber.
1 | // bis hier hier ist der Pin im Tri-State
|
2 | PORTB = ( 1 << PB0 ); |
3 | // Jetzt ist der Pullup aktiv. Der Pin gibt eine (schwache) 1 aus
|
4 | DDRB = ( 1 << PB0 ); |
5 | // jetzt ist der Pin auf Ausgang und gibt eine richtige 1 aus
|
Die kurze Zeitspanne zwischen den Registeroperationen ist der Unterschied! In deinem einen Fall ist während dieser Zeit der Pin 0 und im anderen Fall ist er schon 1! > ersteres mache ich(scheinbar falsch) Na ja. Es ist nicht 'falsch'. Es hängt davon ab, welche Aussenbeschaltung an dem Pin hängt und ob das für die ein Problem macht, wenn ein paar µs-Bruchteile die Leitung mit GND verbunden ist oder nicht. Ob eine LED nach dem Einschalten einen tausendstel Wimpernschlag leuchtet oder nicht, wird niemanden wirklich interessieren. Es gibt aber Fälle, in denen das nicht egal ist.
:
Bearbeitet durch User
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.