Forum: Mikrocontroller und Digitale Elektronik LED ansteuern?


von Robert O. (rotto)


Angehängte Dateien:

Lesenswert?

Hallo,

entschuldigt bitte meine Unkenntnisse, bin noch ganz am Anfang und 
versuche mir gerade selbst das µ-Controller-Programmieren beizubringen 
und will einfach nur eine LED einschalten.

Mein Controller ist ein ATXMEGA256A3BU und an Port R1 (PR1 laut 
Datenblatt) ist eine LED angeschlossen. Leider fehlt mir noch etwas die 
Syntax, die ich schreiben muss.

#define F_CPU 32000UL; //32kHz

#include <avr/io.h>

#define LEDPORT PORTR;
#define LEDPIN PR1;

int main(void)
{

    while (1)
    {
    LEDPORT |= (1<<LEDPIN);
    }
}

Vielen Dank für jede Hilfe.
Habe noch ein Bild aus dem Datenblatt angefügt, da wird Port R1 als PR1 
bezeichnet. Muss ich vielleicht noch eine Bibiothek vom Controller mit 
einbinden?

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Robert O. schrieb:

> entschuldigt bitte meine Unkenntnisse, bin noch ganz am Anfang und
> versuche mir gerade selbst das µ-Controller-Programmieren beizubringen
> und will einfach nur eine LED einschalten.

Natürlich fehlt da ein kleines Stück Portinitialisierung. Nämlich das 
Schalten auf Ausgang für PR1.

> Mein Controller ist ein ATXMEGA256A3BU

Nicht gerade der Einstiegscontroller in's AVR-Universum. Aber das ist im 
konkreten Zshg. irrelevant. Würde auch bei den ganz kleinen nicht 
funktionieren. Übrigens auch bei nahezu keinem anderen µC, egal aus 
welcher Familie.

Praktisch überall muß man mindestens erstmal festlegen, dass ein Pin als 
Ausgang fungieren soll, bevor man ihn als solchen benutzen kann...

von Robert O. (rotto)


Angehängte Dateien:

Lesenswert?

Vielen Dank für Deine Hilfe. Habe etwas im Netz gesucht und habe es 
jetzt wie im Anhang geschrieben. Aber Port R wird bei DDRx nicht 
erkannt.

Laut Debugger sind DDRR und PR1 nicht deklariert, aber in den Tutorials, 
die ich gefunden habe, wurde dies auch nicht gemacht. Fehlt da nicht 
vielleicht doch eine Bibliothek?

: Bearbeitet durch User
von Pandur S. (jetztnicht)


Lesenswert?

Also erstens mal ist es unwahrscheinlich, dass der Controller nur am 
32kHz Quarz laeuft. Dann sollte die LED ueber einen Vorwiderstand 
angeschlossen sein, und dann muss noch klar sein, ob die LEd bei Null 
oder bei Eins leuchten soll.

von wendelsberg (Gast)


Lesenswert?

Robert O. schrieb:
> Fehlt da nicht
> vielleicht doch eine Bibliothek?

An welcher Stelle sagst Du dem Compiler, fuer welchen uC er das Programm 
machen soll?

wendelsberg

von Ernas Häkel-Blog (Gast)


Lesenswert?

Pandur S. schrieb:
> Also erstens mal ist es unwahrscheinlich, dass der Controller nur
> am
> 32kHz Quarz laeuft. Dann sollte die LED ueber einen Vorwiderstand
> angeschlossen sein, und dann muss noch klar sein, ob die LEd bei Null
> oder bei Eins leuchten soll.

Das ist überhaupt nicht unwahrscheinlich, denn der Controller besitzt 
einen internen 32kHz-Oszillator. Der kommt sinnvoller dann zum Einsatz, 
wenn ungewöhnlicherweise am Port PR, der für den externe Quarz 
vorgesehen ist, kein Quarz hängt.

Das Datenblatt sagt dazu:
"The oscillator is automatically enabled/disabled when it is used as 
clock source for any part of the device."

Woher soll aber der Compiler wissen, welche CPU er vor sich hat?
Ich kenne jetzt nicht den Controller aber sollte das nicht hier 
definiert werden?
Statt
#include <avr/io.h>
also
#include <avr/iox256a3bu.h>

Weiterhin bin ich mir nicht sicher, ob das alleine genügt:

#define F_CPU 32000UL; //32kHz

Woher soll der Controller wissen, der Clock intern oder extern ist? Da 
gibt es dieses Code-Schnipsel:

OSC.CTRL |= OSC_RC32KEN_bm; // initalize internal 32kHz Osci
do {
/* Wait for the 32kHz oscillator to stabilize. */
} while ( ( OSC.STATUS & OSC_RC32KRDY_bm ) == 0);

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Robert O. schrieb:
> Habe etwas im Netz gesucht
Du solltest eher mal im Datenblatt (hier das 
ATxmega64A3U/128A3U/192A3U/256A3U - Complete Datasheet) suchen. Das Netz 
kannst du dann noch zur Bestätigung deiner Untersuchungen herziehen.

Oder mach es zumindest so, dass du im Netz was suchst und dann mit dem 
Datenblatt herausfindest, was da gemacht wird.

Denn auch wenn du das Datenblatt nicht gern lesen willst, weil es 
Englisch geschrieben ist: irgendwann muss du es sowieso tun, weil du die 
Antwort auf ein spezielles Problem nicht mehr im Netz findest. So viel 
zum Thema "hab ich mir selbst beigebracht".

> Fehlt da nicht vielleicht doch eine Bibliothek?
Wenn es so wäre, dann würden dir der Compiler oder der Linker das sagen.


Und zum "Problem" an sich: man muss 3 Dinge tun, um einen µC zum Laufen 
zu bekommen.
1. den Reset verlassen
(Datenblatt Seite 27 System Control and Reset)

2. den Takt erzeugen, ggfs. den Takt für einzelne Module aktivieren
(Datenblatt Seite 22 System Clock and Clock options)

3. die Port-Hardware konfigurieren, alternative Portfunktionen beachten
(Datenblatt Seite 32 I/O-Ports)

Und dann kommt
4. den gewünschten Pegel ausgeben

: Bearbeitet durch Moderator
von Thomas W. (thomas_w808)


Lesenswert?

Beim Anfang mit dem gleichen uC hat mir 
https://www.kampis-elektroecke.de/mikrocontroller/xmega-io/
geholfen.

von Stefan F. (Gast)


Lesenswert?

Ernas Häkel-Blog schrieb:
> Woher soll aber der Compiler wissen, welche CPU er vor sich hat?
> Ich kenne jetzt nicht den Controller aber sollte das nicht hier
> definiert werden?

> Statt
> #include <avr/io.h>
> also
> #include <avr/iox256a3bu.h>

Nein, beim avr-gcc stellt man das durch eine Compiler-Option 
(Kommandozeilenparameter, bzw. Projekteinstellung) ein.

Zu den Takteinstellungen möchte ich sagen, dass das hier (noch) 
irrelevant ist. Das Problem hat nichts mit der Taktfrequenz zu tun.


Robert:
Bitte poste Quelltexte nicht als Bildschirmfoto,. sondern als Text.

Bei den "alten" AVR würde das so gehen:
1
DDRR |= (1<<PR1);  // Bit 1 im DDR Register setzen = PR1 auf Ausgang schalten
2
PORTR |= (1<<PR1); // Bit 1 im PORT Register setzen = PR1 auf HIGH setzen

Du hast aber einen Xmega, da ist einiges Syntax anders. Die meisten AVR 
Tutorials passen nicht zur Xmega reihe. Dort geht es vermutlich so:
1
PORTR.DIR |= (1<<PR1);  // Bit 1 im DIR Register setzen = PR1 auf Ausgang schalten
2
PORTR.OUT |= (1<<PR1); // Bit 1 im OUT Register setzen = PR1 auf HIGH setzen

Etwas effizienter geht es mit den speziellen Registern DIRSET und 
OUTSET, aber ich will dich damit jetzt nicht verwirren. Behalte das 
einfach mal für später im Hinterkopf.

von Thomas F. (igel)


Lesenswert?

Stefan ⛄ F. schrieb:
> Etwas effizienter geht es mit den speziellen Registern DIRSET und
> OUTSET, aber ich will dich damit jetzt nicht verwirren. Behalte das
> einfach mal für später im Hinterkopf.

Wenn man sich da mal daran gewöhnt hat will man es  nicht mehr anders 
machen.
Hier ein kurzer Ausschnitt von mir für XMega, nicht ganz perfekt:
1
     PORTA_DIR = 0xFF;
2
     PORTB_DIR = 0b11110011;
3
  
4
     PORTA_OUTSET |= 1<<4;
5
     PORTB_OUTSET = 0b00000011;

von Thilo L. (bc107)


Lesenswert?

... und wenn das alles umgesetzt wurde und das Programm läuft, wird die 
LED scheinbar schwach leuchten, da sie viel zu schnell an- und 
ausgeschaltet wird, als dass das Auge die zwei unterschiedlichen 
Zustände tatsächlich wahrnehmen kann.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thilo L. schrieb:
> da sie viel zu schnell an- und ausgeschaltet wird
Ich sehe da kein Ausschalten, denn
Robert O. schrieb:
>>>> LEDPORT |= (1<<LEDPIN);
Und auch sonst toggelt keiner der Codeschnipsel hier den Portpin...

: Bearbeitet durch Moderator
von P. P. (Gast)


Lesenswert?

Er schrieb ja auch:

Robert O. schrieb:
> und will einfach nur eine LED einschalten.

von Robert O. (rotto)


Angehängte Dateien:

Lesenswert?

Vielen Dank an Euch alle. Hat mir schon sehr geholfen.

Pandur S. schrieb:
> Also erstens mal ist es unwahrscheinlich, dass der Controller nur am
> 32kHz Quarz laeuft. Dann sollte die LED ueber einen Vorwiderstand
> angeschlossen sein, und dann muss noch klar sein, ob die LEd bei Null
> oder bei Eins leuchten soll.

Der Quarz ist ein externer mit etwa 32 kHz, das ist eine XPLAINED 
Platine. Habe ein Bild aus dem Datenblatt angehängt, da hängt der dran. 
Zum Glück habe ich gestern nichts mehr auf den Controller geschrieben, 
ich hätte jetzt einfach blind den Ausgang auf "High" gesetzt, der muss 
aber auf "Low".

Ernas Häkel-Blog schrieb:
> Das ist überhaupt nicht unwahrscheinlich, denn der Controller besitzt
> einen internen 32kHz-Oszillator. Der kommt sinnvoller dann zum Einsatz,
> wenn ungewöhnlicherweise am Port PR, der für den externe Quarz
> vorgesehen ist, kein Quarz hängt.

Der externe 32 kHz Quarz hängt an TOSC1 und TOSC2, also Pin 43 und 42. 
Da wo du sagst (PortR), hängen in der Platine zwei LEDs dran. Aber Quarz 
könnte man dort auch anschließen. Wie weiter oben schon erwähnt, habe 
ich ein Bild aus dem Datenblatt dazu angehängt.

Stefan ⛄ F. schrieb:
> Bitte poste Quelltexte nicht als Bildschirmfoto,. sondern als Text.

Werde ich mir merken und vielen Dank für Deine ausführliche Antwort, die 
hat mir schon viel geholfen.

P. P. schrieb:
> Er schrieb ja auch:
>
> Robert O. schrieb:
>> und will einfach nur eine LED einschalten.

Genau, das hin und herschalten ist kein Problem, das kann ich zur Not 
auch mit Zählvariablen, oder ähnlichem machen. Mir geht es nur darum die 
LED einzuschalten und die nötige Syntax zu verstehen.

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