1 | #include <avr/io.h>
|
2 | #ifndef F_CPU
|
3 | #define F_CPU 8000000UL /* Quarz mit 8 Mhz */
|
4 | #endif
|
5 | #include <util/delay.h>
|
6 | #include <util/twi.h>
|
7 | #include <avr/interrupt.h>
|
8 | #include <stdlib.h> //fuer NULL
|
9 |
|
10 | //TWI SLAVE EINSTELLUNGEN
|
11 | #define TWI_BIT_RATE 40
|
12 | #define TWI_PRESCALER 0
|
13 | #define TWI_EIGENE_ADRESSE 120 //eigene SLAVE ADRESSE 1...127
|
14 | #define TWI_ADRESSE_SLAVE 127
|
15 |
|
16 | #define TWI_GENERAL_CALL_enable 0 //1=Generral Call enabled / 0=disabled
|
17 |
|
18 |
|
19 |
|
20 | unsigned char DATENTABELLE [30] [3]; //2 Dimensionales Array - Speicherort aller zu sendenden Daten
|
21 | #define GOESSE_DATENTABELLE_IN_BYTES 90
|
22 | unsigned char *LAUFENDER_ZEIGER_AUF_DATENTABELLE = NULL;
|
23 |
|
24 | unsigned char TWI_EMPFANGENE_DATEN [1] [3]; //2 Dimensionales Array - Speicherort fuer ueber TWI empfangene Daten
|
25 | unsigned char *LAUFENDER_ZEIGER_AUF_TWI_EMPFANGENE_DATEN = NULL;
|
26 |
|
27 |
|
28 | unsigned char TWI_BUSY_FLAG = 0;
|
29 |
|
30 |
|
31 | void init_twi() {
|
32 | TWBR = TWI_BIT_RATE;
|
33 | TWSR = TWI_PRESCALER;
|
34 | TWAR = (TWI_EIGENE_ADRESSE << 1 | TWI_GENERAL_CALL_enable << TWGCE);
|
35 | TWCR = (0<<TWINT | 1<<TWEA | 1<<TWEN | 1<<TWIE);
|
36 | }
|
37 |
|
38 |
|
39 |
|
40 | unsigned char next_byte() {
|
41 | unsigned char temp_char = *LAUFENDER_ZEIGER_AUF_DATENTABELLE;
|
42 | LAUFENDER_ZEIGER_AUF_DATENTABELLE ++ ;
|
43 | return temp_char;
|
44 | }
|
45 |
|
46 |
|
47 |
|
48 | ISR(TWI_vect){ //Two-wire Serial Interface Handler
|
49 |
|
50 | switch (TWSR & 0xF8){
|
51 |
|
52 | //MASTER TRANSMITTER
|
53 |
|
54 | case TW_START: //start condition transmitted
|
55 | //Load SLA + "W" (W=0)
|
56 | TWDR = (127 << 1); //general call
|
57 | TWCR = (1<<TWINT) | (1<<TWEN| 1<<TWIE); //send SLA + "W" (W=0)
|
58 | PORTB &= ~(1<<PB5);
|
59 | break;
|
60 |
|
61 | case TW_MT_SLA_ACK: //SLA+W transmitted, ACK received
|
62 | //Load data byte
|
63 | TWDR = next_byte();
|
64 | //senden - Clear TWINT
|
65 | TWCR = (1<<TWINT) | (1<<TWEN| 1<<TWIE);
|
66 | PORTB &= ~(1<<PB4);
|
67 | break;
|
68 |
|
69 | case TW_MT_DATA_ACK: //data transmitted, ACK received
|
70 |
|
71 | if (LAUFENDER_ZEIGER_AUF_DATENTABELLE > ((&DATENTABELLE[0][0]) + 90)){ //Zeiger ausserhalb der DATENTABLELLE
|
72 |
|
73 | //transmit STOP condition
|
74 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO| 1<<TWIE );
|
75 | PORTB &= ~(1<<PB2);
|
76 | TWI_BUSY_FLAG = 0; //es darf erneut gesendet werden
|
77 |
|
78 | }
|
79 | else {
|
80 | //Load data byte
|
81 | TWDR = next_byte();
|
82 | //senden - Clear TWINT
|
83 | TWCR = (1<<TWINT) | (1<<TWEN| 1<<TWIE);
|
84 | PORTB &= ~(1<<PB3);
|
85 | }
|
86 | break;
|
87 |
|
88 | //ERROR
|
89 | PORTD &= ~(1 << PD0);
|
90 |
|
91 |
|
92 | }
|
93 | }
|
94 |
|
95 |
|
96 |
|
97 | void TWI_MASTER_TRANSMITTER(){
|
98 |
|
99 | LAUFENDER_ZEIGER_AUF_DATENTABELLE = &DATENTABELLE[0][0]; //Zeiger auf Adresse "DATENTABELLE [0][0]"
|
100 | //transmit START condition
|
101 |
|
102 | PORTB = 0xFF;
|
103 | PORTB &= ~(1<<PB0);
|
104 | TWCR = (1<<TWINT|1<<TWSTA|1<<TWEN |1<<TWIE);
|
105 |
|
106 | _delay_ms(10);
|
107 | }
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | int main (void) {
|
113 | DDRB = 0xFF; //Alle Pins auf Ausgang
|
114 | PORTB = 0xFF;
|
115 | DDRD = 0xFF; //Alle Pins auf Ausgang
|
116 | PORTD = 0xFF;
|
117 | DDRC = 0x00; //PORT C alles EINGÄNGE
|
118 |
|
119 |
|
120 | init_twi(); //TWI INITIALISIERUNG
|
121 | _delay_ms(4000);
|
122 |
|
123 | sei(); //Interrupts global freigeben
|
124 |
|
125 | while (1) {
|
126 |
|
127 | if (TWI_BUSY_FLAG == 0) {
|
128 | PORTB = 0xFF;
|
129 | TWI_BUSY_FLAG = 1;
|
130 | TWI_MASTER_TRANSMITTER();
|
131 | }
|
132 |
|
133 |
|
134 | } //End while
|
135 | return 0;
|
136 | } //End main
|