Forum: Mikrocontroller und Digitale Elektronik LED toggeln mit ATxmega256A3BU


von Jürgen (bergensdorf)


Angehängte Dateien:

Lesenswert?

Moin,

könnt Ihr mir bitte mal meine ,bzw. meinen Fehler sagen. Ich bin mir 
halt noch unsicher bezüglich der zu verwendenen Syntax. Im Anhang das 
Programm, die Pinbelegung aus dem Datenblatt, die Fehlermeldungen und 
der Schaltplan.

Es soll halt die LED0 getoggelt werden, die an PIN 58 des µController 
angeschlossen ist. Muss ich PIN 58 (PR0) vielleicht auch erstmal als 
Ausgang definieren, wie beim Arduino? Und ist es richtig '#define' 
innerhalb von main zu schreiben? Und ist PR0 überhaupt die richtige 
Schreibweise für PIN58?

Und auf dem XPLAINED board befindet sich ja auch ein 32kHz Quartz, muss 
ich den nicht auch initiieren?

Vielen Dank Eure Hilfe.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

ähmm, Programm als Text zeigen und nicht als Bild. Wir können jetzt 
nämlich nichts kopieren und korrigieren.

Ja der Pin muss als Ausgang konfiguriert werden.
Nimm dafür einen wirklich freien Pin.

Das #define ist innerhalb main() sichtbar, erstmal alles i.O., außerhalb 
main wird zur echten globalen Variablen.

Zum einschalten wird verordert, dass passt.
Beim ausschalten wird verundet. Tausche ODER gegen UND.
Tja was verbirgt sich hinter PR0? Oder soll das PR0_bm lauten?
Ansonsten nimm die übliche Bitnummer zum schieben.

F_CPU hast du woanders definiert?

Irgendeine interne Taktquelle sollte Default arbeiten. Welche und wie 
schnell weiß ich nicht.

: Bearbeitet durch User
von Spess53 .. (hardygroeger)


Lesenswert?

Hi

OUTTGL – Data Output Value Toggle register

MfG Spess

von Michael B. (laberkopp)


Lesenswert?

Jürgen schrieb:
> Muss ich PIN 58 (PR0) vielleicht auch erstmal als Ausgang definieren,
> wie beim Arduino?

Es ist viel komplexer

https://embedded-lab.com/blog/xmega-io-ports/

mehrere Register, ein blödes MASK Register, und dazu noch virtual Port 
Zugriff.

zufem schreibt er include <io.h> und nicht <avr/io.h> obeohl ich nicht 
weiss, ob du damit dieselbe io h erreichst.

von Jürgen (bergensdorf)


Lesenswert?

1
#include <avr/io.h>
2
#include "util/delay.h"
3
4
int main(void)
5
{
6
  #define LEDPORT PORTR//Müsste #define nicht außerhalb von Main stehen?
7
  #define LEDPIN0 PR0 //Ist PR0 hier richtig?
8
9
    while (1) 
10
    {
11
    LEDPORT |= (1<<LEDPIN0);
12
    _delay_ms(250);
13
    LEDPORT |= ~(1<<LEDPIN0);
14
    _delay_ms(250);-
15
  }
16
}
Danke für die schnelle Hilfe, habe es jetzt als Code eingefügt, bin noch 
sehr neu hier. Wie definiere ich den PIN als OUTPUT? Und hat der PORTR 
laut Datenblatt dann nur 4 bit oder wie, bzw. 1 BYTE? Also ist PR0 dann 
PR2 von PR0 bis PR4?

Ich habe das Atmel XMEGA XPLAINED Board, da ist die LED auf dem PCB an 
PIN58, was man auch im Schaltplan sehen kann. Also es gibt nur vier LEDs 
auf dem Board. Wie definiere ich es als Ausgang, wie beim Arduino, oder 
gibt es da eine andere Syntax?

Danke erstmal für Eure Hilfe, ist jetzt schon spät, ich werde es mir 
morgen nochmal ansehen.

: Bearbeitet durch User
von Spess53 .. (hardygroeger)


Lesenswert?

Hi

>Wie definiere ich es als Ausgang, wie beim Arduino, oder
>gibt es da eine andere Syntax?

Wenn du das nicht weißt, dann empfehle ich dir das

XMEGA A MANUAL

zu lesen. Ansonsten erleidest du einen genialen Schiffbruch.

MfG Spess

von Thomas F. (igel)


Lesenswert?

Jürgen schrieb:
> Es soll halt die LED0 getoggelt werden

z.B. so:
  //IO-Ports einstellen
  PORTA_DIR = 0xFF;
  PORTB_DIR = 0xFF;
  PORTE_DIR = 0xFF;
  PORTC_DIR = 0b11111011;
  PORTD_DIR = 0b11111110;

   while(1) {

  PORTB_OUTTGL = 0b10000001; //Port B7 und B0 toggeln

  delay(200ms);
   }
   return 0;

von Roger S. (roger1004)


Lesenswert?

Jürgen schrieb:
> LEDPORT |= ~(1<<LEDPIN0);

Hier müsste es lauten
1
 LEDPORT &= ~(1<<LEDPIN0);


oder noch einfacher

Jürgen schrieb:
> LEDPORT |= (1<<LEDPIN0);
>     _delay_ms(250);
>     LEDPORT |= ~(1<<LEDPIN0);
>     _delay_ms(250);



ändern zu
1
 
2
LEDPORT ^= (1<<LEDPIN0);
3
_delay_ms(250);

das spart sogar zwei Zeilen Code :D

als Ausgang muss der Pin trotzdem initialisiert werden.

von Peter D. (peda)


Lesenswert?

Jürgen schrieb:
> Und ist es richtig '#define'
> innerhalb von main zu schreiben?

#define macht eine Textersetzung und ist ab der nächsten Zeile bekannt 
bis zum Compileende oder einem #undef.
Es kann irgendwo vor der ersten Verwendung stehen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
> könnt Ihr mir bitte mal meine ,bzw. meinen Fehler sagen. Ich bin mir
> halt noch unsicher bezüglich der zu verwendenen Syntax.

Lern erstmal C ohne µC am PC. So wird das nix.

von Jürgen (bergensdorf)


Lesenswert?

Wilhelm M. schrieb:
> Jürgen schrieb:
>> könnt Ihr mir bitte mal meine ,bzw. meinen Fehler sagen. Ich bin mir
>> halt noch unsicher bezüglich der zu verwendenen Syntax.
>
> Lern erstmal C ohne µC am PC. So wird das nix.

Habe ich irgendwo geschrieben, dass ich die Syntax von C/C++ meine. Ich 
meine die Syntax um einen µController zu initiieren, wobei mir schon 
User vor Dir geholfen haben. Das ich nicht alles weiss in C oder C++ ist 
klar, aber wer tut das schon? Ich habe schon sehr viel Arduino 
programmiert, aber ich würde gerne mehr von der Funktionsweise eines µC 
verstehen, ohne jetzt unbedingt in Assembler programmieren zu müssen.

Und zu der Aussage möchte ich noch sagen, dass ich erst richtig gelernt 
habe C bzw. C++ zu nutzen, durch das Programmieren mit einem Arduino. 
Also ich würde niemandem raten, jetzt unbedingt mit einer 
Konsolenanwendung C zu lernen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
> Wilhelm M. schrieb:
>> Jürgen schrieb:
>>> könnt Ihr mir bitte mal meine ,bzw. meinen Fehler sagen. Ich bin mir
>>> halt noch unsicher bezüglich der zu verwendenen Syntax.
>>
>> Lern erstmal C ohne µC am PC. So wird das nix.
>
> Habe ich irgendwo geschrieben, dass ich die Syntax von C/C++ meine.

Welche denn sonst?

> Ich
> meine die Syntax um einen µController zu initiieren, wobei mir schon
> User vor Dir geholfen haben.

Bitte lies nochmal die Definition des Begriffs "Syntax" nach.

> Und zu der Aussage möchte ich noch sagen, dass ich erst richtig gelernt
> habe C bzw. C++ zu nutzen, durch das Programmieren mit einem Arduino.

Das bezweifle ich bzw. man sieht an den Fragen (in Deinem Code), dass 
dem nicht so ist.

> Also ich würde niemandem raten, jetzt unbedingt mit einer
> Konsolenanwendung C zu lernen.

Ich schon ;-)

von Jürgen (bergensdorf)


Lesenswert?

Englische Definition:
-the structure of statements in a computer language.
Gehört dazu nicht auch das Initiieren eines µControllers mithilfe einer 
Programmiersprache? Und es stimmt ich mag etwas eingerostet sein, darum 
poste ich doch hier. Wo soll ich denn sonst meine Fragen stellen? Statt 
zu schreiben, dass ich erstmal C lernen soll, könntest Du mir ja auch 
einfach konstruktiv sagen, wie ich es besser machen soll/kann. Wo meine 
Fehler sind usw., oder nicht?

von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
> Englische Definition:
> -the structure of statements in a computer language.

Perfekt

> Gehört dazu nicht auch das Initiieren eines µControllers mithilfe einer
> Programmiersprache?

Nein, es hat mit der Sprache nichts zu tun.

> Und es stimmt ich mag etwas eingerostet sein, darum
> poste ich doch hier. Wo soll ich denn sonst meine Fragen stellen? Statt
> zu schreiben, dass ich erstmal C lernen soll, könntest Du mir ja auch
> einfach konstruktiv sagen, wie ich es besser machen soll/kann. Wo meine
> Fehler sind usw., oder nicht?

Fangen wir nochmal von vorne an: poste Deinen aktuellen Stand, aber 
nicht als Bild. Und die Fehlermeldungen, auch nicht als Bild. Und am 
besten die Compiler-Optionen: auch nicht als Bild.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Das #define ist innerhalb main() sichtbar, erstmal alles i.O., außerhalb
> main wird zur echten globalen Variablen.

Präprozessor-Symbole sind nicht gescoped. Und der Präprozessor macht nur 
Textersatz, er ist ein nicht-interaktiver Editor.

Also nix globale Variable!

von Veit D. (devil-elec)


Lesenswert?

Hallo,

was einem Arduino abnimmt muss man in Bare Metall alles selbst schreiben 
und verstehen. Das hat in der Tat noch nicht viel mit Programmierung in 
C/C++ zu tun. Das ist nur stumpfes Manual lesen, Register raussuchen und 
die Bedeutung der Bits der Register verstehen. Nimm die ersten beiden 
Data Sheets und lese darin.
https://www.microchip.com/en-us/product/ATxmega256A3BU#document-table
Im A3BU Manual steht drin was dieser Typ speziell kann.
Im Allgemeinen Manual stehen alle Register drin.

Wenn man weiß was pinMode() und digitalWrite() im Hintergrund machen, 
ich meine die Funktion der Funktion nicht die Bits, dann kann man 
anfangen das in Bare Metall umzusetzen. Wenn man das Prinzip verstanden 
kann man jeden Controller programmieren. Egal wie die Register- und 
Bitnamen heißen.

pinMode() ändert die Datenrichtung des Pins. Wie sieht das in Bare 
Metall aus?
digitalWrite() ändert einen Ausgang. Wie sieht das in Bare Metall aus?

Wenn du die Default Taktquelle unverändert verwendet musst du dennoch 
wissen welche Frequenz diese hat. Damit definiert man F_CPU.
Bspw.
#define F_CPU 8000000UL  // Systemtakt in Hz
Wird benötigt damit Funktionen wie _delay_ms() den richtigen Wert 
berechnen können.

Wenn der Controller dann noch spezielle Port I/O Toogle Register hat, 
kann man loslegen wie Thomas F. schon gezeigt hat. Man spart sich die 
Logikverknüpfungen usw. wobei das delay() noch das Richtige von #include 
<avr/delay.h> sein sollte.

Im Controller Headerfile sind meistens noch allgemeine Bitmasken 
definiert. Muss man selbst wissen was man nutzt und wie schreibt. Dir 
hilft ja die Syntaxvervollständigung in Microchip Studio.
1
// Generic Port Pins
2
#define PIN0_bm 0x01
3
#define PIN0_bp 0
4
#define PIN1_bm 0x02
5
#define PIN1_bp 1
6
#define PIN2_bm 0x04
7
#define PIN2_bp 2
8
#define PIN3_bm 0x08
9
#define PIN3_bp 3
10
#define PIN4_bm 0x10
11
#define PIN4_bp 4
12
#define PIN5_bm 0x20
13
#define PIN5_bp 5
14
#define PIN6_bm 0x40
15
#define PIN6_bp 6
16
#define PIN7_bm 0x80
17
#define PIN7_bp 7
Das hier macht alles das Gleiche.
1
a) PORTD_DIR |= (1<<5);
2
b) PORTD_DIR |= _BV(5);
3
c) PORTD_DIR |= _BV(PIN5_bp);
4
d) PORTD_DIR |= PIN5_bm;
Wobei ich mich zwischen b) und d) entscheiden würde, rein für die 
Lesbarkeit wohl eher b).

von Veit D. (devil-elec)


Lesenswert?

Wilhelm M. schrieb:
> Veit D. schrieb:
>> Das #define ist innerhalb main() sichtbar, erstmal alles i.O., außerhalb
>> main wird zur echten globalen Variablen.
>
> Präprozessor-Symbole sind nicht gescoped. Und der Präprozessor macht nur
> Textersatz, er ist ein nicht-interaktiver Editor.
>
> Also nix globale Variable!

Jawohl Vati.   ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Das hier macht alles das Gleiche.a) PORTD_DIR |= (1<<5);
> b) PORTD_DIR |= _BV(5);
> c) PORTD_DIR |= _BV(PIN5_bp);
> d) PORTD_DIR |= PIN5_bm;

Es ging um PORTR, Pin0. Hoffentlich kann er die Transferleistung 
bringen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Wilhelm M. schrieb:
>> Veit D. schrieb:
>>> Das #define ist innerhalb main() sichtbar, erstmal alles i.O., außerhalb
>>> main wird zur echten globalen Variablen.
>>
>> Präprozessor-Symbole sind nicht gescoped. Und der Präprozessor macht nur
>> Textersatz, er ist ein nicht-interaktiver Editor.
>>
>> Also nix globale Variable!
>
> Jawohl Vati.   ;-)

... gerade bei einem Anfänger ist so etwas fatal!

von Veit D. (devil-elec)



Lesenswert?

Hallo,

soviel traue ich dem TO schon zu. Fördern und fordern. :-)  Machst du ja 
genauso. ;-)

Ich sehe es aktuell wie Du. Wir machen hier einen Schnitt. Jürgen setzt 
alles nach besten Wissen und Gewissen um und zeigt uns notfalls sein 
Programm als Text.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
> Und auf dem XPLAINED board befindet sich ja auch ein 32kHz Quartz, muss
> ich den nicht auch initiieren?

Nein, die Default-Taktquelle ist der interne 2MHz Oszillator. Also: 
aufpassen mit F_CPU, sonst stimmt das "delay" nicht.

von Jürgen (bergensdorf)


Angehängte Dateien:

Lesenswert?

Danke für Eure umfangreiche Hilfe.

Wie bekomme ich denn jetzt raus, in welchem Takt der XMEGA jetzt 
arbeitet? Aus den Fuses werde ich nicht so ganz schlau.

Im Datenblatt auf Seite 18 habe ich den im Anhang befindlichen Absatz 
gefunden, ist damit die Frequenz gemeint, mit der der µC ohne anderen 
Befehl arbeitet? Also 2 Megahertz?

Ich habe noch kein Programm drauf gespielt, aber ich finde einfach nicht 
raus was ich für den PIN PRO schreiben muss (Was ich oben aus dem 
Datenblatt angehängt habe). Ich bekomme einfach keine Vernünftige 
Syntax(oder was auch immer) hin, in der mir der Debugger dann sagt, dass 
PRO oder PIN0, oder was auch immer ein Teil des µCs ist. PORTR ist ein 
Teil des Controllers, aber wie definiere ich den PIN, der im Datenblatt 
als PRO bezeichnet wird, ich hatte übrigens am Anfang PR0 in der 
Programmierung geschriebe, aber er wird mit O geschrieben. Oder ist dies 
PIN58?

Das mit der 'und'- und 'oder'-Verknüpfung verstehe ich mittlerweile, 
aber ich verstehe nicht wie ich den Anschluss von LED0 als Ausgang 
definiere und diesen Ausgang dann auf High schalte, also wie dieser 
Ausgang überhaupt deklariert wird. DDRR mag der Compiler nicht und PR0 
oder PRO auch nicht.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
> Im Datenblatt auf Seite 18 habe ich den im Anhang befindlichen Absatz
> gefunden, ist damit die Frequenz gemeint, mit der der µC ohne anderen
> Befehl arbeitet? Also 2 Megahertz?

Genau!

Jürgen schrieb:
> Ich habe noch kein Programm drauf gespielt, aber ich finde einfach nicht
> raus was ich für den PIN PRO schreiben muss (Was ich oben aus dem
> Datenblatt angehängt habe).

Sag mal, liest Du eigentlich was andere Leute hier schreiben?

Jürgen schrieb:
> DDRR mag der Compiler nicht und PR0
> oder PRO auch nicht.

Du hast hier einen XMega, und keine Mega! Schau in das DB.

Da Du ja C++-Syntax verstehst, versuche es mal so:
1
struct HW {
2
    static inline constexpr uint8_t led0 = 0b0000'0001;
3
};
4
 
5
int main() {
6
    PORTR.DIRSET = HW::led0;
7
    while(true) {
8
        PORTR.OUTTGL = HW::led0;
9
        _delay_ms(500);
10
    }
11
}

Veit D. schrieb:
> soviel traue ich dem TO schon zu. Fördern und fordern. :-)  Machst du ja
> genauso.

Tja ...

von Wastl (hartundweichware)


Lesenswert?

Jürgen schrieb:
> Also 2 Megahertz?

Wilhelm M. schrieb:
> Genau!

Nein! Sondern 2 Megaherz!

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Wastl schrieb:
> Nein! Sondern 2 Megaherz!

Schrieb ich oben so:

Wilhelm M. schrieb:
> Jürgen schrieb:
>> Und auf dem XPLAINED board befindet sich ja auch ein 32kHz Quartz, muss
>> ich den nicht auch initiieren?
>
> Nein, die Default-Taktquelle ist der interne 2MHz Oszillator. Also:
> aufpassen mit F_CPU, sonst stimmt das "delay" nicht.

von Wastl (hartundweichware)


Lesenswert?

Wilhelm M. schrieb:
> Schrieb ich oben so:

Ja, aber du hast es nicht verstanden.

von Jürgen (bergensdorf)


Lesenswert?

Wastl schrieb:
> Jürgen schrieb:
>> Also 2 Megahertz?
>
> Wilhelm M. schrieb:
>> Genau!
>
> Nein! Sondern 2 Megaherz!

Es ist tatsächlich Hertz und nicht Herz. Die Einheit ist nach dem 
Physiker Heinrich Hertz benannt.

Beitrag #7463341 wurde vom Autor gelöscht.
von Jürgen (bergensdorf)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> soviel traue ich dem TO schon zu. Fördern und fordern. :-)  Machst du ja
> genauso. ;-)
>
> Ich sehe es aktuell wie Du. Wir machen hier einen Schnitt. Jürgen setzt
> alles nach besten Wissen und Gewissen um und zeigt uns notfalls sein
> Programm als Text.

Danke für den Schaltplan, den konnte ich nirgends finden. Und genau, ich 
kämpfe mich gerade durch die ganzen Antworten durch und poste dann mein 
Programm hier, wenn es halbwegs fertig ist.

von Thomas F. (igel)


Lesenswert?

Jürgen schrieb:
> Wie bekomme ich denn jetzt raus, in welchem Takt der XMEGA jetzt
> arbeitet? Aus den Fuses werde ich nicht so ganz schlau.

Die Xmegas haben keine Fuses für die Clock-Konfiguration. Der Takt wird 
per Software in der Reset-Routine eingestellt. Das hatte ich dir 
eigentlich schon mal geschrieben:

Beitrag "Re: Software von Atmel xmegaA3BU runterladen"

von Wilhelm M. (wimalopaan)


Lesenswert?

Thomas F. schrieb:
> Der Takt wird
> per Software in der Reset-Routine eingestellt.

Das kann man machen, wo /wann man will.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich dachte auch das alles klar gewesen sein sollte, es stand im Grunde 
schon alles da. Jetzt hat Wilhelm es in seinem Stil nochmal wiederholt. 
Musste nur noch ausprobieren.

Die richtigen Namen findet man im
a) Manual
b) Headerfile
c) Syntaxvervollständigung, bspw. 'PORT' ...

PR0 oder PA2 oder sonstige sind nur Abkürzungen im Schaltplan bzw. in 
der Pin Beschriftung. Das ist nicht die Schreibweise zum Programmieren.
P ... steht für Port
R oder A ... steht für die Pingruppe R oder A o.a.
0 bis 7 steht für das Bit der Portgruppe.

PS:
Lasst ihn erstmal mit Defaulttakt einen Erfolg verbuchen.
F_CPU Definition darf er nicht vergessen.

: Bearbeitet durch User
von Jürgen (bergensdorf)


Lesenswert?

1
 
2
#define F_CPU 8000000UL //8MHz
3
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
//#include <avr/delay.h>
8
9
int main(void)
10
{
11
12
  PORTR_DIR = 0b00000001; 
13
14
    while (1) 
15
    {
16
    PORTR_OUTTGL = 0b00000001;
17
    _delay_ms(250);
18
  }
19
  return 0;
20
}

Nochmals danke für Eure Hilfe, habe es jetzt geschafft die LED zum 
blinken zu bringen. Hatte mich die letzten Tage mehr mit Arduino und 
Schieberegistern beschäftigt, aber mich dann vor einigen Stunden hier 
ran gesetzt und es hat mit dem obigen Code funktioniert.

Also, um es nochmal zusammenzufassen. Eigentlich muss ich (erstmal) nur 
wissen, dass ich mit PORTR_DIR, je nach 1 (Ausgang) oder 0 (Eingang), 
festlege, ob es ein Ein- oder Ausgang sein soll (viele Wege führen nach 
Rom, wie man ja weiter oben sehen kann). Ich habe mich oben entschieden 
nur den PIN, den ich nutzen möchte, als Ausgang zu setzen, weil ja 
Eingänge hochohmiger sind als Ausgänge, richtig?

Im nächsten kann ich am Output ein high oder low setzen, womit ich (in 
meinem Fall), die LED ein- und ausschalten kann. Hier wird dies 
allerdings automatisch durch den obigen Befehl getan.

Ich würde gerne noch wissen, wie ich an diese Befehle komme? Die müssten 
doch in der Headerdatei avr/io.h sein, richtig? Wie kann ich die öffnen 
um die Befehle zu lesen, Oder gibt es da irgendein gutes Cheatsheet? Da 
sich ja anscheinend die Befehle von ATxmega-Controllern zu anderen 
unterscheiden.

Ich habe hier noch drei Arduinos rumfliegen und noch ein Board mit nem 
ATmega32u mit USB C Anschluss, ohne ISP oder JTAG.

Wäre es vielleicht sinnvoller für mich, erstmal bei den für Anfängern 
gebräuchlicheren (weiss ich natürlich nicht ganz genau) µC zu bleiben? 
Da viele Bücher und Guides deren Befehle nutzen. Mir fehlen halt vor 
allem die Wörter, in den Datenblättern stehen ja immer nur die 
Assembler-Befehle.

Wir haben zwar damals in der Schule ein wenig Assembler programmiert, 
aber da weiss ich gar nichts mehr von und macht ja auch kaum noch sinn, 
habe gehört, die Compiler sind besser als die meisten Menschen.

Und noch etwas, ist die Bildschirmansteuerung ähnlich einfach, wie beim 
Arduino? Aber wahrscheinlich ist es besser einen neuen Thread 
aufzumachen, oder kann ich das hier fragen?

von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
>
1
> #define F_CPU 8000000UL //8MHz
2
> 
3
> 
4
> #include <avr/io.h>
5
> #include <util/delay.h>
6
> //#include <avr/delay.h>
7
> 
8
> int main(void)
9
> {
10
> 
11
>   PORTR_DIR = 0b00000001;
12
> 
13
>     while (1)
14
>     {
15
>     PORTR_OUTTGL = 0b00000001;
16
>     _delay_ms(250);
17
>   }
18
>   return 0;
19
> }
20
>
>

> Also, um es nochmal zusammenzufassen. Eigentlich muss ich (erstmal) nur
> wissen, dass ich mit PORTR_DIR, je nach 1 (Ausgang) oder 0 (Eingang),
> festlege, ob es ein Ein- oder Ausgang sein soll (viele Wege führen nach
> Rom, wie man ja weiter oben sehen kann). Ich habe mich oben entschieden
> nur den PIN, den ich nutzen möchte, als Ausgang zu setzen, weil ja
> Eingänge hochohmiger sind als Ausgänge, richtig?

OK

> Ich würde gerne noch wissen, wie ich an diese Befehle komme?

Ein Blick ins Datenblatt wirkt Wunder ;-)


> Die müssten
> doch in der Headerdatei avr/io.h sein, richtig?

Nein, diese Header Datei inkludiert die Device-spezifische,
in Deinem Fall die iox256a3bu.h

> Wie kann ich die öffnen
> um die Befehle zu lesen, Oder gibt es da irgendein gutes Cheatsheet?

Mit einem Editor: vi, emacs oder notepad

> Da
> sich ja anscheinend die Befehle von ATxmega-Controllern zu anderen
> unterscheiden.

Ja. Wie ich schon schrieb: xmega ist nicht mega ist nicht tiny ist nicht 
DA, DB, DD ...

> Wäre es vielleicht sinnvoller für mich, erstmal bei den für Anfängern
> gebräuchlicheren (weiss ich natürlich nicht ganz genau) µC zu bleiben?
> Da viele Bücher und Guides deren Befehle nutzen.

Mag sein.

> Mir fehlen halt vor
> allem die Wörter, in den Datenblättern stehen ja immer nur die
> Assembler-Befehle.

Wenn Du in C/C++ programmierst, brauchst Du keine Assembler-Befehle, 
wohl aber die SFR-Namen.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ergänzend.

Die binäre Schreibweise mag zwar erstmal schön sein, ist aber schwer zu 
lesen und fehlerträchtig. Nimm lieber das _BV() Makro.

Was meinst du mit Befehlen genau? Meinst du damit sowas wie PORTR_DIR? 
Das sind keine Befehle, dass sind Registernamen. Das sind definierte 
Namen für definierte Adressen im Controller. Die sind alle im Headerfile 
definiert und im Manual beschrieben. Davon gibt es "Tausende", alle 
Register sind im Controller Manual beschrieben. Jedes einzelne Bit 
davon. Das alles hat wie schon gesagt noch nichts mit Programmierung zu 
tun. Das ist nur die Hardwarebeschreibung des Controllers. Schlage das 
Manual auf, hatte ich schon verlinkt, gehe ins PORT Kapitel und lese 
alles über den PORT Hardwareaufbau und dessen Register und wie das 
funktioniert, was welches Bit in welchem Register macht. Am Anfang 
erschlägt es einen, später wird es zur Gewohnheit. Deswegen ist es egal 
mit welchem 8 Bit Controller du anfängst.

Programmierung beginnt wenn du diese Register verwendest. Für die 
Programmierung benötigst du ein C/C++ Buch. Wenn du schon mit Arduino 
programmiert hast dann C++. Solche 'Dinge' wie pinMode(), digitalWrite() 
usw. die du schon kennst sind auch keine Befehle. Das sind Funktionen 
die andere Leute geschrieben haben. Das alles schreibst du nun so oder 
in ähnlicher Form ohne Arduino selbst. Denke in Funktionen und denke 
nicht an Befehle. Dann klappt das besser.

Befehle sind wirklich nur die Assembler Kommandos die im Controller 
Manual stehen. Aber das brauchst du alles nicht wenn du C/C++ 
programmieren möchtest.

von Jürgen (bergensdorf)


Angehängte Dateien:

Lesenswert?

Wilhelm M. schrieb:
> Ein Blick ins Datenblatt wirkt Wunder ;-)

Veit D. schrieb:
>Schlage das
>Manual auf, hatte ich schon verlinkt, gehe ins PORT Kapitel und lese
>alles über den PORT Hardwareaufbau und dessen Register und wie das
>funktioniert, was welches Bit in welchem Register macht.

Veit D. schrieb:
> https://www.microchip.com/en-us/product/ATxmega256A3BU#document-table
> Im A3BU Manual steht drin was dieser Typ speziell kann.
> Im Allgemeinen Manual stehen alle Register drin.

Ihr meint das was im AU-Manual auf Seite 148 (Anhang) steht und da muss 
ich dann immer nur PORTn_DIR, PORTn_DIRSET oder PORTn_OUT schreiben, 
also immer PORTn_ davor setzen? Ich glaube ich habe es jetzt verstanden.

Wilhelm M. schrieb:
> Wenn Du in C/C++ programmierst, brauchst Du keine Assembler-Befehle,
> wohl aber die SFR-Namen.

Sind die vorigen genannten dann die SFR-Namen?

Wilhelm M. schrieb:
> Mit einem Editor: vi, emacs oder notepad

Ich habe vorhin bestimmt eine Stunde auf meinem Computer nach der 
avr/io.h HEADER-Datei gesucht, also unter dem Pfad in den Klammern 
(C:\Program Files 
(x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\arm-none-eabi\inc 
lude)  liegen bei mir ganz viele Header-Dateien, aber die gesuchte war 
nicht dabei, wo werden die denn gespeichert?

Veit D. schrieb:
> Nimm lieber das _BV() Makro.

Das erkennt der Compiler bei mir nicht. Das hatte ich versucht.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Jürgen schrieb:
> Ihr meint das was im AU-Manual auf Seite 148 (Anhang) steht und da muss
> ich dann immer nur PORTn_DIR, PORTn_DIRSET oder PORTn_OUT schreiben,
> also immer PORTn_ davor setzen? Ich glaube ich habe es jetzt verstanden.

Im Prinzip: PORTA_DIR geht. Aber: es gibt auch die anderer Variante mit 
einem C-Struct statt eines eigenen Präprozessor-Symbols für jedes 
Register.

Also: PORTA.DIR geht auch. PORTA ist ein dereferenzierter Zeiger auf 
eine Port-struct, darin wählst Du das Member DIR aus.

Aber wie gesagt, dass sind alles Basics in C/C++, und deswegen sollte 
man C/C++ am PC lernen.

Jürgen schrieb:
> Sind die vorigen genannten dann die SFR-Namen?

SRF = special function register

Jürgen schrieb:
> Ich habe vorhin bestimmt eine Stunde auf meinem Computer nach der
> avr/io.h HEADER-Datei gesucht, also unter dem Pfad in den Klammern
> (C:\Program Files
> (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\arm-none-eabi\inc
> lude)  liegen bei mir ganz viele Header-Dateien, aber die gesuchte war
> nicht dabei, wo werden die denn gespeichert?

Lass doch den Computer suchen ;-)

Und io.h nützt Dir nichts, die Datei, die Du brauchst, hatte ich oben 
geschrieben. Lies das einfach mal.

Bei mir ist das unter /usr/avr/include/avr, aber das ist eben Linux und 
kein Windoofs. Dort hat man die Datei in 0.1 ms gefunden.

Kleiner Hinweis: Du brauchst die Header für die AVR µC und nicht die für 
ARM-basierte µC.

: Bearbeitet durch User
von Thomas W. (thomas_w808)


Lesenswert?


von Veit D. (devil-elec)


Lesenswert?

Hallo,

das Headerfile namens iox256a3bu.h muss auf deinem Rechner vorhanden 
sein, sonst könntest du für den Controller nichts kompilieren. Wenn dein 
Microchip Studio auf C installiert ist, dann lasse den Explorer auf C 
nach der Datei suchen. Das kann ja jetzt nicht so schwer sein.

Bei mir:
"C:\Program Files 
(x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr 
\iox256a3bu.h"

Auch das _BV() Makro muss dein Microchip Studio kennen. Habe es soeben 
mit der nativen Toolchain ausprobiert. Geht.
https://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html

Vielleicht solltest du das hier erstmal durcharbeiten.
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
https://www.mikrocontroller.net/articles/Kategorie:AVR-Tutorial

Die Anpassung an deine Registernamen wirst du nun sicherlich 
hinbekommen. Das restliche Prinzip ist immer gleich. Das ist noch 
einfacher als wirklich irgendeine Idee zu programmieren.

von Jürgen (bergensdorf)


Lesenswert?

Wilhelm M. schrieb:
> Aber wie gesagt, dass sind alles Basics in C/C++, und deswegen sollte
> man C/C++ am PC lernen.

Ich habe schon so viele Konsolenprogramme geschrieben, vor allem in C. 
Es macht halt einfach viel mehr Spaß einen Mikrocontroller zu 
programmieren, aber ich behalte das im Hinterkopf.

Hast du vielleicht eine Buchempfehlung? Für C habe ich was hier, aber 
nicht für C++.

Wilhelm M. schrieb:
> Kleiner Hinweis: Du brauchst die Header für die AVR µC und nicht die für
> ARM-basierte µC.

Hab es mit deinem Tipp gefunden. Danke.

Veit D. schrieb:
> "C:\Program Files
> (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr
> \iox256a3bu.h"

Bei mir auch. Aber danke für die Mühe. Ist echt umfangreich, war aber 
interessant mal da rein zu schauen.

Thomas W. schrieb:
> https://www.kampis-elektroecke.de/mikrocontroller/xmega-io/

Sehr guter Link. Danke.

Veit D. schrieb:
> Vielleicht solltest du das hier erstmal durcharbeiten.
> https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
> https://www.mikrocontroller.net/articles/Kategorie:AVR-Tutorial

Hab ich glaube ich schon drin gelesen, aber habs mal zu Favoriten 
hinzugefügt.


Eine Frage habe ich noch zu _delay_ms() Ich finde den Vollstop etwas 
unpraktisch. Bei Arduino gibt es ja dazu millis() um sowas zu umgehen 
(zumindest, was ich kenne, da gibt's bestimmt noch mehr). Also gibt es 
eine ähnliche Header Datei?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

verstehe mich jetzt nicht falsch. Wenn du schon Konsolenpogramme in C 
geschrieben und mit Arduino Erfahrung hast, wundern mich manche Fragen 
langsam. Dann müßtest du wissen das millis() ein laufender Zähler ist 
der auch nur einen Timer vom Controller verwendet. Das ist eine Funktion 
die wie viele andere auch vom Arduino Framework zur Verfügung gestellt 
werden. Auch das musst du dir nachprogrammieren ohne Arduino im Rücken. 
Einen freien Timer im 1ms Intervall eine Variable inkrementieren lassen.

Für eine Buchempfehlung für C++ haben sich Bücher von Ulrich Breymann 
"Der C++ Programmierer" als gut herauskristallisiert. Aktuell ist 
Ausgabe für C++20. Alle älteren Ausgaben darunter sind mittlerweile 
ausverkauft. Bis zu welchen C++ Standard möchtest du denn programmieren?

von Jürgen (bergensdorf)


Angehängte Dateien:

Lesenswert?

Veit D. schrieb:
> Dann müßtest du wissen das millis() ein laufender Zähler ist
> der auch nur einen Timer vom Controller verwendet. Das ist eine Funktion
> die wie viele andere auch vom Arduino Framework zur Verfügung gestellt
> werden. Auch das musst du dir nachprogrammieren ohne Arduino im Rücken.
> Einen freien Timer im 1ms Intervall eine Variable inkrementieren lassen.

Jetzt wo du es schreibst, klingt es ziemlich einfach. Einfach nur pro 
Sekunde eine Variable hochzählen und schon habe ich die vergangene Zeit, 
seit Systemstart in Sekunden. Aber egal, eigentlich war ich nur 
neugierig. Ignorier die Frage einfach, manche Sachen machen viel mehr 
Spaß, wenn man sie selbst herausfindet.

Was mir bloß aufgefallen ist, kann es sein, das doch der externe Quarz 
des ATxmega xplained Boards läuft? Ich finde, dass die LEDs viel zu 
lange leuchten. Und außerdem steht das Fusebyte 2 auf "TOSC1/2 shared 
with XTAL". Habe da auch Bilder zu angehängt. Genau dort hängt ja auch 
der 32KHz Oszillator dran, weiter oben wurde ja von dir auch der 
Schaltplan geposted.

Veit D. schrieb:
> Für eine Buchempfehlung für C++ haben sich Bücher von Ulrich Breymann
> "Der C++ Programmierer" als gut herauskristallisiert. Aktuell ist
> Ausgabe für C++20. Alle älteren Ausgaben darunter sind mittlerweile
> ausverkauft. Bis zu welchen C++ Standard möchtest du denn programmieren?

Für mich reicht vermutlich Standard C++14 oder C++17. Aber da bin ich 
wahrscheinlich hinterher schlauer, wie immer. Ist doch wahrscheinlich 
dann eh am besten den neuesten Standard mir C++20 zu nehmen und mir das 
von dir genannte Buch zu besorgen. Welchen Standard würdest du 
empfehlen?

: Bearbeitet durch User
von Thomas F. (igel)


Lesenswert?

Jürgen schrieb:
> Einfach nur pro Sekunde eine Variable hochzählen und schon habe ich die 
vergangene Zeit seit Systemstart in Sekunden.

Ich lasse dafür eigentlich immer eine Uhr mitlaufen:
1
volatile uint8_t stunde;
2
volatile uint8_t minute;
3
volatile uint8_t sekunde;
4
5
void uhr(void)  {
6
  
7
  sekunde++;
8
  if (sekunde == 60) {
9
    sekunde=0;
10
    minute++;
11
    if (minute == 60) {
12
      minute=0;
13
      stunde++;
14
      if (stunde == 24) {
15
        stunde=0;
16
      }
17
    }
18
  }
19
}
Den Timer-Interrupt dazu darfst du selber erstellen. :-)


> Was mir bloß aufgefallen ist, kann es sein, das doch der externe Quarz
> des ATxmega xplained Boards läuft? Ich finde, dass die LEDs viel zu
> lange leuchten.

Kann schon sein. Die Taktquelle wird per Software eingestellt, nicht 
über Fuses:
Beitrag "Re: LED toggeln mit ATxmega256A3BU"

von Jürgen (bergensdorf)


Lesenswert?

Thomas F. schrieb:
> Den Timer-Interrupt dazu darfst du selber erstellen. :-)

Mach ich gerne, danke!

Thomas F. schrieb:
>> Was mir bloß aufgefallen ist, kann es sein, das doch der externe Quarz
>> des ATxmega xplained Boards läuft? Ich finde, dass die LEDs viel zu
>> lange leuchten.
>
> Kann schon sein. Die Taktquelle wird per Software eingestellt, nicht
> über Fuses:
> Beitrag "Re: LED toggeln mit ATxmega256A3BU"

Hat sich erledigt. Ich habe den Fehler gemacht und die Frequenz falsch 
eingestellt. Dafür weiß ich jetzt, dass es nichts macht den falschen 
Systemtakt einzustellen. Es stimmen dann halt nur die Zeitwerte nicht.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich hätte die Frage vielleicht gar nicht stellen sollen. Das Problem 
ist, es gibt keine/kaum käufliche Bücher zu C++14 und C++17. So richtig 
Nutzen bringen die auch nur wenn man die Cpp Standard Lib hat, diese 
entwickelt sich hauptsächlich weiter. Die gibt es aber für AVR offiziell 
nicht. Es gibt zwar eine auf GitHub, aber die sorgt auch für manche 
Überraschungen, von daher rate ich dir aktuell davon ab. Auf dem Desktop 
PC könntest du alles programmieren was aktuell ist, aber wie gesagt 
nicht auf dem AVR. Du hättest noch eine Baustelle was ich dir derzeit 
nicht zumuten möchte. Kannste später immer noch beackern. Zudem du dann 
auch eine aktuelle Toolchain benötigst. Könntest du alles bekommen. Aber 
wie gesagt, dass wären aktuell für dich laut meiner Einschätzung zu 
viele Baustellen auf einmal. Erstmal mit AVR Bare Metall und C++ 
klarkommen, dann kann man immer noch tiefer einsteigen. So meine 
Bewertung. Ist nicht böse gemeint. Für dich geht es erstmal dadrum mit 
dem Controller Manual warm zu werden damit du die Hardware selbst 
programmieren kannst. Der Rest kommt von alleine. Und wenn es ganz 
anders kommt programmierst du gar kein C++ sondern bleibst bei C. Wird 
sich zeigen.

von Jürgen (bergensdorf)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> ich hätte die Frage vielleicht gar nicht stellen sollen. Das Problem
> ist, es gibt keine/kaum käufliche Bücher zu C++14 und C++17. So richtig
> Nutzen bringen die auch nur wenn man die Cpp Standard Lib hat, diese
> entwickelt sich hauptsächlich weiter. Die gibt es aber für AVR offiziell
> nicht. Es gibt zwar eine auf GitHub, aber die sorgt auch für manche
> Überraschungen, von daher rate ich dir aktuell davon ab. Auf dem Desktop
> PC könntest du alles programmieren was aktuell ist, aber wie gesagt
> nicht auf dem AVR. Du hättest noch eine Baustelle was ich dir derzeit
> nicht zumuten möchte. Kannste später immer noch beackern. Zudem du dann
> auch eine aktuelle Toolchain benötigst. Könntest du alles bekommen. Aber
> wie gesagt, dass wären aktuell für dich laut meiner Einschätzung zu
> viele Baustellen auf einmal. Erstmal mit AVR Bare Metall und C++
> klarkommen, dann kann man immer noch tiefer einsteigen. So meine
> Bewertung. Ist nicht böse gemeint. Für dich geht es erstmal dadrum mit
> dem Controller Manual warm zu werden damit du die Hardware selbst
> programmieren kannst. Der Rest kommt von alleine. Und wenn es ganz
> anders kommt programmierst du gar kein C++ sondern bleibst bei C. Wird
> sich zeigen.

Alles gut. Du hast mir ja super weitergeholfen hier, vor allem mit dem 
gesamten Bestückungs- und Schaltplan (Finde den nirgends, obwohl 
Microchip genau dieses Atmel Xplained Board immer noch verkauft). Für 
mich war vor allem das Initiieren das Problem und vielleicht war es 
sogar gut, es auf dem Xmega zu machen, da die Architektur nicht so weit 
gebräuchlich ist, wie die, der normalen Mega-Controlller. Dadurch habe 
ich auch wirklich verstanden, dass man nur ins Datenblatt schauen muss, 
um die Befehle zu bekommen, die ich aber in der eigentlich Manual des 
spezifischen µCs gar nicht gefunden habe, sondern in dem 
Xmega-Familiendatenblatt (oder wie auch immer ich es nennen soll), 
vielleicht habe ich sie übersehen, egal.

Ich bin gelernter Elektroniker für Geräte und System, also ich habe 
schon ein ziemlich gutes Elektronikverständnis, ich glaube, da fehlt es 
den meisten, wenn sie mit µControllern anfangen, aber bei mir ist auch 
noch eine Menge Potential nach oben, was ich vergessen habe, oder noch 
nicht verstanden habe.

Ich werde dann versuchen das Buch einfach so billig wie möglich zu 
bekommen, gibt es ja bei Amazon gebraucht.

Also, vielen Dank an Euch alle für die Hilfe.

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.