Hi,
ich habe hier Code, der eigentlich für einen ATMega328P gedacht ist und
versuche, diesen für einen XMega D4 zu übersetzen. Bei der seriellen
Schnittstelle wirft mir der Compiler diverse Fehler über unbekannte
Register/Bezeichner UCSR0A, UCSR0B, U2X0, UBRR0H, UBRR0L, RXEN0, TXEN0,
RXCIE0, UDRIE0 und USART_RX_vect.
Was hat sich beim D4 hier geändert - wie heißen die richtigen Register
für die serielle Schnittstelle an PortC? Gibt es irgend eine
Tabelle/Liste, wo die vergleichbaren Register zu finden sind?
:-)
ATMega und ATXMega haben grundsätzlich unterschiedliche Registernamen.
Rookie schrieb:> Gibt es irgend eine> Tabelle/Liste, wo die vergleichbaren Register zu finden sind?
Ja, die beiden Datenblätter der Controller die du benutzt.
Alt Backen schrieb:> ATMega und ATXMega haben grundsätzlich unterschiedliche> Registernamen.
Sind denn nur die Namen anders oder haben die auch eine andere
Funktionsweise?
> Ja, die beiden Datenblätter der Controller die du benutzt.
Leider kenne ich mich damit nicht wirklich aus und versuche her nur,
eine Anleitung aus dem Internet umzusetzen...
Rookie schrieb:> Sind denn nur die Namen anders oder haben die auch eine andere> Funktionsweise?
Beides. Die UARTS vom Xmega sind viel universeller z.B. auch im
SPI-Mode.
Mir reicht eigentlich immer sowas:
Dieses Register-Namen-Durcheinander wie bei den Megas oder 8bit-PIGs
gibts beim XMEGA nicht. Immer: HARDWARE-UNIT PUNKT REGISTER, also
USARTC0.CTRLA ...
Scheint anfangs aufwendiger, hat Vorteile. Ich verwende selbst bei
kleinen Projekten nur noch XMEGAs.
z.B. lassen sich auch sehr schön alias verwenden, gibt der HW-UNIT
einfach den Namen seiner Nutzung, f.E., #define RS485_UART USARTC0, der
Quelltext wird übersichtlicher. Hardware-Änderungen bei lfd. Entwicklung
sind so viel einfacher "einarbeitbar".
Serielle Kommunikation: Der "reichliche" RAM der XMEGAs erlaubt die
Verwendung von 256-Byte-Ringpuffern, als quasi "wartefreies" Senden:
(Atmel Studio 7, ohne ini)
#define SERCOM USARTC0
#define SERCOM_DREINT USARTC0_DRE_vect
#define SERCOM_RXCINT USARTC0_RXC_vect
byte rxbuffer[256];
volatile byte rxbuffer_write_ix;
volatile byte rxbuffer_read_ix;
byte txbuffer[256];
volatile byte txbuffer_write_ix;
volatile byte txbuffer_read_ix;
volatile byte rxed_cmd_cnt;
rs232_send_char(char c)
{
if(SERCOM.STATUS & USART_DREIF_bm) SERCOM.DATA=c;
else
{
txbuffer[txbuffer_write_ix++]=c;
SERCOM.CTRLA |= USART_DREINTLVL_LO_gc;
}
}
ISR (SERCOM_DREINT)
{
if(txbuffer_read_ix==txbuffer_write_ix) SERCOM.CTRLA &=
~USART_DREINTLVL_LO_gc;
else SERCOM.DATA=txbuffer[txbuffer_read_ix++];
}
ISR (SERCOM_RXCINT)
{
byte rxd=SERCOM.DATA;
if(rxd==rx_term)
{
rxed_cmd_cnt++;
}
else rxbuffer[rxbuffer_write_ix++]=rxd;
}
interrupt.h include nicht vergessen, bei "grossem" Datenverkehr müssen
die Buffer selbstredend auf Overrun getestet werden.
mfg
Achim
J. Zimmermann schrieb:> interrupt.h include nicht vergessen, bei "grossem" Datenverkehr müssen> die Buffer selbstredend auf Overrun getestet werden.
Schön wie die Fachleute hier rücksichtslos ihre Fachbeiträge
reinknallen. Kann eigentlich nur der Selbstdarstellung dienen,
wenn ich den Level und die Einstellung des Anliegen-Habenden
betrachte.
Rookie schrieb:> Leider kenne ich mich damit nicht wirklich aus und versuche her nur,> eine Anleitung aus dem Internet umzusetzen...
Rookie schrieb:> Leider kenne ich mich damit nicht wirklich aus und versuche her nur,> eine Anleitung aus dem Internet umzusetzen...
Welche? (Link)
Warum auf XMega umsetzen?
Auf Gemerkt:
> Schön wie die Fachleute hier rücksichtslos ihre Fachbeiträge> reinknallen. Kann eigentlich nur der Selbstdarstellung dienen,> wenn ich den Level und die Einstellung des Anliegen-Habenden> betrachte.
Wollte eigentlich helfen, aber wenn das so rüberkommt, kann ich's auch
lassen, dann können Leute wie Du hier Ihren inhaltslosen Quatsch
ablassen.
mfg
Achim
Dieter F. schrieb:> Rookie schrieb:>> Leider kenne ich mich damit nicht wirklich aus und versuche her nur,>> eine Anleitung aus dem Internet umzusetzen...>> Welche? (Link)>> Warum auf XMega umsetzen?
Ich versuche das hier zu bauen: https://github.com/gnea/grbl
Dazu hatte ich noch ein HOWTO, das beschrieben hat, was für eine andere
CPU zu ändern ist (das war allerdings auch nicht für den XMega).
Im Makefile habe ich den Wert für DEVICE und CLOCK schon angepasst.
Ebenso die anderen PORT-Werte in der cpu_map.h. Jetzt stolpert er mir
halt noch über die Fehler in grbl/serial.c sowie über ein
grbl/cpu_map.h:159:25: Warnung: »USART_UDRE_vect« appears to be a
misspelled signal handler, missing __vector prefix [-Wmisspelled-isr]
#define SERIAL_UDRE USART_UDRE_vect
XMega deswegen, weil ich so ein Board hier habe und keins mit dem 328P.
Rookie schrieb:> XMega deswegen, weil ich so ein Board hier habe und keins mit dem 328P.
Ganz ehrlich, kaufe Dir ein Arduino Nano board (um die 5 € bei eBay z.B.
https://www.ebay.de/itm/Arduino-Nano-Atmega328P-BEREITS-GELOTET-verlotet-fertig-aufgebaut/253638131454)
- wenn Du Zeit hast auch für deutlich weniger Geld aus China - und packe
dort die Software drauf.
Die Alternative ist, dass Du Dich wirklich mit den beiden Datenblättern
und den "Besonderheiten" des ATXMega beschäftigst. Eine Portierung von
ATMega auf ATXMega ist schon eine mittlere Aufgabe - das wird hier
niemand für Dich erledigen.
in Atmel-Studio (?)
#define SERIAL_UDRE USARTC0_DRE_vect
oder #define SERIAL_UDRE USARTC1_DRE_vect
jenachdem, ob Du USARTC0 (RXD auf C2, TXD C3) oder USARTC1 (RXD C6, TXD
C7) benutzt
mfg
Achim
Dieter F. schrieb:> Eine Portierung von> ATMega auf ATXMega ist schon eine mittlere Aufgabe - das wird hier> niemand für Dich erledigen.
Ist doch schon gemacht.
Ein Fachmann klatscht hier seine Sourcen und seine Fach-
ausdrücke rein - und schon ist das Problem gelöst.
Dieter F. schrieb:> Ganz ehrlich, kaufe Dir ein Arduino Nano board (um die 5 € bei eBay z.B.> Ebay-Artikel Nr. 253638131454)> - wenn Du Zeit hast auch für deutlich weniger Geld aus China - und packe> dort die Software drauf.
Es ist keine Preisfrage, vielmehr läuft der XMega mit der doppelten
Taktfrequenz und ich hoffe, auf die Art auch eine doppelte maximale
Stepfrequenz zu erreichen.
J. Zimmermann schrieb:> in Atmel-Studio (?)> #define SERIAL_UDRE USARTC0_DRE_vect> oder #define SERIAL_UDRE USARTC1_DRE_vect> jenachdem, ob Du USARTC0 (RXD auf C2, TXD C3) oder USARTC1 (RXD C6, TXD> C7) benutzt> mfg> Achim
Funktioniert! Jetzt hängen da noch so Fehler wie
grbl/serial.c:73:5: Fehler: »UCSR0A« nicht deklariert (erste Verwendung
in dieser Funktion)
UCSR0A |= (1 << U2X0); // baud doubler on for high baud rates,
i.e. 115200
^
grbl/serial.c:73:5: Anmerkung: jeder nicht deklarierte Bezeichner wird
nur einmal für jede Funktion, in der er vorkommt, gemeldet
grbl/serial.c:73:21: Fehler: »U2X0« nicht deklariert (erste Verwendung
in dieser Funktion)
UCSR0A |= (1 << U2X0); // baud doubler on for high baud rates,
i.e. 115200
^
grbl/serial.c:75:3: Fehler: »UBRR0H« nicht deklariert (erste Verwendung
in dieser Funktion)
UBRR0H = UBRR0_value >> 8;
^
grbl/serial.c:76:3: Fehler: »UBRR0L« nicht deklariert (erste Verwendung
in dieser Funktion)
UBRR0L = UBRR0_value;
^
grbl/serial.c:79:3: Fehler: »UCSR0B« nicht deklariert (erste Verwendung
in dieser Funktion)
UCSR0B |= (1<<RXEN0 | 1<<TXEN0 | 1<<RXCIE0);
^
grbl/serial.c:79:17: Fehler: »RXEN0« nicht deklariert (erste Verwendung
in dieser Funktion)
UCSR0B |= (1<<RXEN0 | 1<<TXEN0 | 1<<RXCIE0);
^
grbl/serial.c:79:28: Fehler: »TXEN0« nicht deklariert (erste Verwendung
in dieser Funktion)
UCSR0B |= (1<<RXEN0 | 1<<TXEN0 | 1<<RXCIE0);
rum.
Auf Gemerkt:
> Ein Fachmann klatscht hier seine Sourcen und seine Fach-> ausdrücke rein - und schon ist das Problem gelöst.
Hättest Du gern mehr solche hohlen Beiträge wie Deine? Wenn Dich Dein
Unwissen zerfrisst, geh zu Freud.
Rookie:
> XMega deswegen, weil ich so ein Board hier habe und keins mit dem 328P.
Halte auch nichts davon, jedes mal, wenn ein Programmier-Problem
auftritt, die Plattform zu wechseln, das bedeutet auch Zeitaufwand und
irgendwann hast Du dann einen Schrank voller nicht funktionierender
Hardware.
Wenn Du weiter XMEGA programmieren willst: Nimm Dir das Datenblatt,
wähle das Kapitel der zu programmierenden Hardware-Unit, Unterkapitel
Registerbeschreibung und arbeite die einzelnen Register der Reihe nach
ab.
statt RXCIE0:
USARTC0.CTRLA=USART_RXCINTLVL_LO_gc;
statt RXEN0, TXEN0, U2X0:
USARTC0.CTRLB=USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm;
statt UBRR0L, H:
USARTC0.BAUDCTRLA=0x0F;
USARTC0.BAUDCTRLB=0xD1;
Ausserdem muss beim XMEGA der Programmierbare Interrupt Controller
eingestellt werden:
PMIC.CTRL=PMIC_LOLVLEN_bm | PMIC_RREN_bm;
Der TX-Port als Ausgang, Hi:
#define TX_PIN 3 // (für USARTC1: 7 einsetzen)
PORTC.OUTSET=1<<TX_PIN;
PORTC.DIRSET=1<<TX_PIN;
Wir kriegen das zum Laufen, auch wenn hier einer immer dazwischen
labert.
mfg
Achim
J Zimmermann schrieb:> Halte auch nichts davon, jedes mal, wenn ein Programmier-Problem> auftritt, die Plattform zu wechseln, das bedeutet auch Zeitaufwand und> irgendwann hast Du dann einen Schrank voller nicht funktionierender> Hardware.Rookie schrieb:> Es ist keine Preisfrage, vielmehr läuft der XMega mit der doppelten> Taktfrequenz und ich hoffe, auf die Art auch eine doppelte maximale> Stepfrequenz zu erreichen.
Mir scheint, da fehlt Erfahrung auf beiden Plattformen. Aber ich möchte
nicht weiter stören ... :-)
Dieter F. schrieb:> Rookie schrieb:>> Es ist keine Preisfrage, vielmehr läuft der XMega mit der doppelten>> Taktfrequenz und ich hoffe, auf die Art auch eine doppelte maximale>> Stepfrequenz zu erreichen.>> Mir scheint, da fehlt Erfahrung auf beiden Plattformen. Aber ich möchte> nicht weiter stören ... :-)
Wieso sollte das nicht so sein? Die PWM-Frequenz leitet sich ja auch vom
CPU-Takt ab!
Rookie schrieb:> Es ist keine Preisfrage, vielmehr läuft der XMega mit der doppelten> Taktfrequenz und ich hoffe, auf die Art auch eine doppelte maximale> Stepfrequenz zu erreichen.
Also die ISR(TIMER1_COMPA_vect) die bei GRBL letzten Endes die Steps
erzeugt arbeitet mit 30 kHz. Es sind also maximal 30000 kSteps/s
möglich. Was bei 16 µSteps mit einer Spindel mit 8mm Steigung 75 mm/s
sind.
Der begrenzende Faktor dabei ist, dass eben die ISR schneller
abgearbeitet sein muss bevor der nächste Tick erzeugt wird. Beim Xmega
werden die Befehle natürlich durch die höhere Taktrate i.d.R. schneller
abgearbeitet weswegen man den Tick dann auch beschleunigen kann. Im
besten Fall eben um das doppelte.
Problem ist eben dass bei steigender Geschwindigkeit eben auch das
Drehmoment der Schrittmotoren abnimmt. Zwar wird hier mit Beschleunigung
gearbeitet, aber irgendwann ist halt Schluss.
Rookie schrieb:> Wieso sollte das nicht so sein? Die PWM-Frequenz leitet sich ja auch vom> CPU-Takt ab!
Hast Du Dein Zitat auch mal gelesen? Ich schrieb, das es scheinbar an
Erfahrung auf beiden (Hardware-) Plattformen fehlt. Nichts von Frequenz
und Takt etc.
Timmo H. schrieb:> Rookie schrieb:>> Es ist keine Preisfrage, vielmehr läuft der XMega mit der doppelten>> Taktfrequenz und ich hoffe, auf die Art auch eine doppelte maximale>> Stepfrequenz zu erreichen.> Also die ISR(TIMER1_COMPA_vect) die bei GRBL letzten Endes die Steps> erzeugt arbeitet mit 30 kHz.
Diese Begrenzung existiert aber nur, wenn MAX_STEP_RATE_HZ gesetzt ist!?
Per Default ist dieser Parameter zwar auf 30000 festgelegt, in GRBL 1.1
aber auskommentiert.
Krrx schrieb:> Diese Begrenzung existiert aber nur, wenn MAX_STEP_RATE_HZ gesetzt ist!?
Nein das Define ist nur zum Prüfen und standardmäßig deaktiviert, aber
das steht ja auch im Kommentar darüber
1
// Sets the maximum step rate allowed to be written as a Grbl setting. This option enables an error
2
// check in the settings module to prevent settings values that will exceed this limitation. The maximum
3
// step rate is strictly limited by the CPU speed and will change if something other than an AVR running
4
// at 16MHz is used.
5
// NOTE: For now disabled, will enable if flash space permits.
6
// #define MAX_STEP_RATE_HZ 30000 // Hz
Die tatsächliche Tickrate wird in Zeile 772ff (stepper.c) berechnet und
gesetzt.
Timmo H. schrieb:> Die tatsächliche Tickrate wird in Zeile 772ff (stepper.c) berechnet und> gesetzt.
Da steht was von
#ifdef VARIABLE_SPINDLE
bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); //
Force update whenever updating block.
#endif
Für mich sieht das eher aus, als ob da irgend ein Bit gesetzt wird?
Timmo H. schrieb:> Bei 1.1 stehts 171 Zeilen weiter unten> https://github.com/gnea/grbl/blob/master/grbl/stepper.c#L943
Und dort berechnet sich TICKS_PER_MICROSECOND aus F_CPU - d.h. ein
erhöhen der Taktfrequenz sollte also in der Tat für einen höhere
maximale Stepfrequenz sorgen können. Die Annahme des TO ist also
richtig.