Ich versuche gerade ein Programm zum senden über DMX zu schreiben. Hierzu habe ich versucht den Quellcode von http://www.hoelscher-hi.de/hendrik/light/ressources.htm meinen Controller anzupassen. Ich benutze einen ATMega 644P mit einem externen 20Mhz Oszillator. Jedoch funktioniert das Programm noch nicht so ganz und ich weis nicht genau woran es liegt. Die Daten werden irgendwie noch nicht richtig gesendet. Wäre super wen jemand eine lösung hat.
1 | #include <avr/io.h> |
2 | #include <stdint.h> |
3 | #include <avr/interrupt.h> |
4 | #include <util/delay.h> |
5 | |
6 | // ********************* Definitionen *********************
|
7 | uint16_t gDmxChannel; |
8 | uint8_t gDmxState; |
9 | |
10 | enum {BREAK, STARTB, DATA}; |
11 | |
12 | #define F_OSC (20000) //oszi 20 MHz
|
13 | #define IBG (10) // 10 µs pause
|
14 | |
15 | volatile uint8_t DmxField[50]; //array DMX |
16 | extern void init_DMX(void); |
17 | |
18 | |
19 | int main(void) |
20 | {
|
21 | init_DMX(); |
22 | |
23 | DmxField[1]= 1; //Ausgaben |
24 | DmxField[2]= 20; |
25 | DmxField[3]= 30; |
26 | DmxField[4]= 0; |
27 | DmxField[5]= 40; |
28 | DmxField[6]= 0; |
29 | DmxField[7]= 50; |
30 | DmxField[8]= 0; |
31 | DmxField[9]= 60; |
32 | DmxField[10]=0; |
33 | |
34 | |
35 | sei(); |
36 | while(1); |
37 | }
|
38 | |
39 | |
40 | void init_DMX(void) |
41 | {
|
42 | //Ports zum senden TXEN
|
43 | DDRD |= (1<<PD3); |
44 | PORTD |= (1<<PD3); //Senden einschalten |
45 | |
46 | //USART 250kbaud
|
47 | UBRR1H = 9; |
48 | UBRR1L = 4; |
49 | |
50 | //asynchron wenn UMSEL Bits = 0
|
51 | //USBS = STOP bit
|
52 | //UCSZ10 8 Datenbits
|
53 | UCSR1C = (1<<USBS1)|(3<<UCSZ10); |
54 | UCSR1B |= (1<<TXEN1)|(1<<TXCIE1); //TXCIE interrupt |
55 | UDR1 = 0; |
56 | |
57 | gDmxState= BREAK; //start USART |
58 | }
|
59 | |
60 | // ****************** DMX Transmission ISR ********************
|
61 | |
62 | ISR(USART1_TX_vect) |
63 | {
|
64 | uint8_t DmxState= gDmxState; |
65 | |
66 | if (DmxState == BREAK) |
67 | {
|
68 | UBRR1H = 0; |
69 | UBRR1L = (F_OSC/1600); //90.9kbaud |
70 | |
71 | UDR1 = 0; //break senden |
72 | gDmxState= STARTB; |
73 | }
|
74 | |
75 | else if (DmxState == STARTB) |
76 | {
|
77 | ////250kbaud, für erneutes Start bit
|
78 | UBRR1H = 9; |
79 | UBRR1L = 4; |
80 | |
81 | |
82 | UDR1 = 0; //start byte senden |
83 | gDmxState= DATA; |
84 | gDmxChannel= 0; |
85 | }
|
86 | |
87 | else
|
88 | {
|
89 | _delay_us(IBG); |
90 | uint16_t DmxChannel= gDmxChannel; |
91 | UDR1 = DmxField[DmxChannel++]; //data senden |
92 | if (DmxChannel == sizeof(DmxField)) gDmxState= BREAK; //neuer break wenn alle daten gesendet sind |
93 | else gDmxChannel= DmxChannel; |
94 | }
|
95 | }
|