Hallo,
derzeit arbeitet ich an einer dmx-Testbox. Alle datenverbindungen intern
werden über den TWI geregelt. Am Bus befinden sich ein Ngw100 als
Master, ein Atmega88(Slave), sowie 2 A/D Wandler und ein 8-Bit
Portexpander.
Am Anfang, hatte ich rein über Interrupt gesteuert das TWI angesteuert.
Da das DMX Protokol sehr Zeitkritsich ist klappte es gar nicht. das
protokol verliert mit jeder TWI Abfrage sein Timing. NUn versuche ich es
mit Polling.
Der TWI soll nur dann abgefragt werden wenn das DMX-Protokol gerade
einen Reset fährt denn da ist die Zeit am unkritsichten. Ich muss
lediglich einen Mindestreset von 88µs durchführen. In dieser Zeit möchte
ich das Array wieder mit neuen Daten versorgen.
ich generiere jetzt einen INterrupt wenn der Sendebuffer leer ist. Nur
jetzt verabschiedet sich das Masterprogramm auf dem NGW100
Hier mal mein Code vom Atmega88
1 | #include <stdint.h>
|
2 | #include <io.h>
|
3 | #include <interrupt.h>
|
4 | #include <delay.h>
|
5 | #include <twi.h>
|
6 | #include <sleep.h>
|
7 |
|
8 | uint8_t DMX_senden;
|
9 | uint8_t dmxdata[512];
|
10 | uint16_t dmxbuffer_adr;
|
11 | uint8_t ready;
|
12 |
|
13 | #include <USART.h>
|
14 | #include <TWI_Slave.h>
|
15 |
|
16 | Isr(USART_UDRE_vect)
|
17 | {
|
18 |
|
19 | if ( TWSR == 0x60)
|
20 | {
|
21 | dmxbuffer_adr=0;
|
22 | TWI_Ack;
|
23 | }
|
24 | if(TWSR == TW_SR_DATA_ACK)
|
25 | {
|
26 | dmxdata[dmxbuffer_adr]=TWDR;
|
27 | dmxbuffer_adr++; //Schreibe Daten aus Regsiter in Datenpuffer
|
28 | TWI_Ack;
|
29 | }
|
30 | if (TWSR == 0xA0)
|
31 | {
|
32 | TWI_Ack;
|
33 | }
|
34 | }
|
35 |
|
36 |
|
37 | int main(int argc, char **argv)
|
38 | {
|
39 |
|
40 | DDRC |= (1<<PIN0); // Daten Richtungsregister genereller auf Ausgang gestellt
|
41 | PORTC = (0<<PORTC0); // Port C0 - Leitung zum Transmitter gesperrt
|
42 | Usart_Init (1); // Usart Inititalisieren mit Vorteiler 0
|
43 | TWI_Slave_Adress(0x4b); // Intialisiere I2C und setzte Adresse
|
44 | dmxbuffer_adr=0;
|
45 | sei(); //*Interrupts global aktiieren
|
46 | //for (uint16_t i = 0; i <=511; i = i +2)
|
47 | //{
|
48 | // dmxdata[i] = 10;
|
49 | //}
|
50 |
|
51 | while (1)
|
52 | {
|
53 | _delay_us(88); // verzögere 90µs
|
54 | PORTC = (1<<PORTC0); // Leitung zum Transmitter freigegeben
|
55 | _delay_us(10); // verzögere 50µs
|
56 | USART_Transmit(0); // DMX-Gerätetype "Dimmer" - "Startbyte" übertragen
|
57 | for (uint16_t i=0; i<= 511;i++) //
|
58 | { //DMX-Daten Kanäle 0 - 512 übertragen
|
59 | USART_Transmit(dmxdata[i++]);
|
60 | } //
|
61 | _delay_us(500); // verzögere 500µs
|
62 | PORTC = (0<<PORTC0); // sperre Leitung zum Transmitter
|
63 | }
|
64 | }
|