Forum: Mikrocontroller und Digitale Elektronik Mikrocontroller Aufgabe


von Entwickler21 (Gast)


Lesenswert?

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
von IchWeissKeinen (Gast)


Lesenswert?

Hallo,
was sagt denn das Vorlesungsskript zum Thema Portinitialisierung?
Um welches Board mit welchem Controller handelt es sich hier?

von Oliver S. (oliverso)


Lesenswert?

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

von Punkt (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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ß.

von Entwickler21 (Gast)


Lesenswert?

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 ?

von Daniel H. (Firma: keine) (commander)


Lesenswert?

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?

von F. F. (foldi)


Lesenswert?

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
von Tho W. (tommyprog)


Lesenswert?

> 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

von Reinhard #. (gruebler)


Lesenswert?

F. Fo schrieb:
> ich bin schon 51 Jahre alt.

Lass Sie nicht so spüren, dass Sie
anders sind als wir ;-)

von F. F. (foldi)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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>

von Tho W. (tommyprog)


Lesenswert?

> 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

von F. F. (foldi)


Lesenswert?

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.

von datasheet (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von flups (Gast)


Lesenswert?

> 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...

von F. F. (foldi)


Lesenswert?

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.

von F. F. (foldi)


Lesenswert?

datasheet schrieb:
> Ihr sterbt nicht aus ..

Fein!

von Walter Tarpan (Gast)


Lesenswert?

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.

von Tho W. (tommyprog)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.