Hallo zusammen,
hat jemand von euch eine brauchbare Library für DMX Senden und Empfangen
auf Atmel XMEGA in C zu Hand oder ist über sowas schonmal gestolpert? Am
besten währe natürlich mit Einsatz des DMA Controllers, damit die
Systemlast gering bleibt.
Bei Elektor gab es wohl mal eine solche Codesammelung, leider hat der
Author die Dateien wieder gelöscht.
Gruß Chris
Hallo zusammen,
da scheinbar keiner eine Lösung hat, habe ich angefangen einen DMX
Sender für den Atxmega256A3U zu schreiben. Zur Verbesserung der
Systemperformance nutzte ich den DMA Modus für den Datentransfer aus dem
DMX Datenarray hinüber zum UART. Bis dahin funktioniert das Programm
auch schon. Daten senden via UART läuft.
Probleme macht mir die Erzeugung des DMX spezifischen Frame Starts. DMX
Verlangt ja einen 88µs Break, gefolgt von 8µs Mark vor der eigentlichen
Datenübertragung. Zur Erzeugung dieser Bedingung wollte ich mit
verlangsamter Datenrate eine 0x00 senden. Zusammen mit der "Null" vom
Start Bit und den zwei "Eins" Stop Bits kommt man bei 100 kBaud so auf
90µs für den Break und 20 µs Mark.
Leider schaffe ich es nicht die Datenrate zur Laufzeit zu ändern. Die
grandiosen Debug Fähigkeiten des AVR Studio 6 sind dort auch keine große
Hilfe. In meinem Programm warte ich darauf, dass das Data Register Empty
flag gelöscht wird, ehe ich neue Daten in den Sendepuffer stelle. Der
Debugger steppt auch schön durch, jedoch erhalte ich das gesamte
Datenpacket immer mit der 250kBaud Datenrate an einem Stück.
Jemand eine Idee wie man den XMega dazu bewegen kann die Datenrate des
UART zur Laufzeit zu änder? Oder geht das beim XMega nicht mehr? Wobei
mir kommt gerade eine Idee, geht das ändern der Datenrate vielleicht nur
während einer ISR?
Wie dem auch sei, hier mal der Quelltext für den DMX Output. Im
Hautprogramm stelle ich eigentlich nur einen Systemtakt von 32 MHz ein
und rufe dann die 3 Funktionen aus der dmx.h
1
/*
2
dmx.c
3
Functions to send DMX data via USART
4
Uses DMA to minimize system load during transfer of 512 bytes payload
5
*/
6
7
8
#include"dmx.h"
9
#include<stdlib.h>
10
#include<avr/io.h>
11
12
//The Buffer from where the DMX Data is read, Filled for test purpose with ABCDEABC...
@ Chris N. (Gast)
>Probleme macht mir die Erzeugung des DMX spezifischen Frame Starts. DMX>Verlangt ja einen 88µs Break, gefolgt von 8µs Mark vor der eigentlichen>Datenübertragung. Zur Erzeugung dieser Bedingung wollte ich mit>verlangsamter Datenrate eine 0x00 senden. Zusammen mit der "Null" vom>Start Bit und den zwei "Eins" Stop Bits kommt man bei 100 kBaud so auf>90µs für den Break und 20 µs Mark.>Leider schaffe ich es nicht die Datenrate zur Laufzeit zu ändern.
Machs nicht zu kompliziert. Erzeuge den BREAK + Pause danach einfach per
_delay_us() IN der ISR, JA, IN der ISR. Das ist hier schon OK.
>Hilfe. In meinem Programm warte ich darauf, dass das Data Register Empty>flag gelöscht wird, ehe ich neue Daten in den Sendepuffer stelle.
Falsch. Du musst das TXC Flag prüfen, erst DANN ist das Byte
vollständiug gesendet.
>UART zur Laufzeit zu änder? Oder geht das beim XMega nicht mehr?
Das glaube ich nicht.
Hallo Falk,
das mit dem TXC Flag hatte ich auch schon versucht, aber wohl ein großes
Brett vor dem Kopf gehabt. Ich habe schon im Break geprüft, ob das TXC
Flag gesetzt ist, kann natürlich nicht, weil ich zuvor ja nie was
gesendet habe. Also im Break weiterhin auf DREIF prüfen und bei Start
und Daten dann auf TXC. Schon klappt es auch ganz ohne Interrupts oder
Timer
1
/*
2
dmx.c
3
Functions to send DMX data via USART
4
Uses DMA to minimize system load during transfer of 512 bytes payload
5
*/
6
7
8
#include"dmx.h"
9
#include<stdlib.h>
10
#include<avr/io.h>
11
12
//The Buffer from where the DMX Data is read, Filled for test purpose with ABCDEABC...
Ok,
ich kommme nicht dahinter was der UART in meiner Software treibt.
Die erste Übertragung von DMX Daten funktioniert wie gewünscht. Bei der
zweiten stimmt das Timing nicht. Ich habe das Programm jetzt so
umgebaut, dass ich sicherstelle, dass die DMA Übertragung abgeschlossen
ist, der UART die Daten auch wirklich auf den PIN ausgegeben hat und ich
deaktiviere sogar den UART vor dem Umkonfigurieren auf die langsame
Baudrate wieder. Dennoch ist im zweiten DMX durchgang immer der Wurm
drin. Zur besseren Übersichtlichkeit der Daten habe ich das erste Null
Bit mal auf CC gesetzt. Lasse ich nun die Break Erzeugung auf 00 stehen
kommen alle Daten mit 250 kBaud raus, auch das Break.
Änder ich die Break Erzeugung einfach mal auf zum Beispiel 0x46 passt
gleich die ganze Datenübertragung nicht mehr.
Noch jemand eine Idee was mit dem UART nicht stimmt?
1
/*
2
dmx.c
3
Functions to send DMX data via USART
4
Uses DMA to minimize system load during transfer of 512 bytes payload
5
*/
6
7
8
#include"dmx.h"
9
#include<stdlib.h>
10
#include<avr/io.h>
11
12
//The Buffer from where the DMX Data is read, Filled for test purpose with ABCDEABC...
//Reconfigure baud rate to 250 kBaud
USARTC0.BAUDCTRLA = 07;
USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(07 >> 8);
Schau mal in XMEGA Manual unter
BAUDCTRLB – Baud Rate register B
Writing BAUDCTRLA will trigger an immediate update of the baud rate
prescaler.
Ich glaube, du solltest erst CTRLB und danach CTRLA beschreiben.