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?
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
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
staticvoidinit(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
intmain(void)
12
{
13
init();
14
15
while(1)
16
{
17
;
18
}
19
20
return0;
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 ?
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.
> 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
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
understjetztgibtderPineine1aus
Ä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.