1 | #define F_CPU 16000000 // CPU clock in Hz
|
2 | #include <avr/interrupt.h> // dient zur Behandlung der Interrupts
|
3 | #include <avr/io.h> // Integer-Definitionen
|
4 | #include <stdbool.h>
|
5 | #include <avr/pgmspace.h>
|
6 | #include "util/delay.h"
|
7 | #include "stdlib.h"
|
8 | #include <stdint.h>
|
9 |
|
10 | #define I2C_SLAVE_ADDRESS 0x52 // Slave Adresse 0x52
|
11 | #define I2C_DATA_INTERRUPT 0x80 // 0x80
|
12 | #define I2C_BUS_COLLISION 0x08 // 0x08
|
13 | #define I2C_ADDRESS_STOP_MATCH 0x40 // 0x40
|
14 |
|
15 | volatile uint8_t command;
|
16 | uint8_t versa = 1;
|
17 | uint8_t versb = 2;
|
18 | volatile uint8_t tx_buff; // 4
|
19 | volatile uint8_t tx_buf[4];
|
20 | volatile uint8_t tx_buf_index = 0;
|
21 |
|
22 | void I2C_init(void)
|
23 | {
|
24 | TWSA |= I2C_SLAVE_ADDRESS; // Register Bus Adresse
|
25 | TWSD |= 0xFF; // Slave Datenregister
|
26 | TWSCRA |= (1<<TWEN)|(1<<TWSHE)|(1<<TWASIE)|(1<<TWSIE)|(1<<TWDIE);
|
27 | // TWSCRA - Slave Steuerregister A
|
28 | // TWEN - I2C Schnittstelle Aktivieren
|
29 | // TWSHE - Haltezeit aktivieren
|
30 | // TWASIE - Adressenunterbrechung aktivieren
|
31 | // TWSIE - Stop Unterbrechung aktivieren
|
32 | // TWDIE - Datenunterbrechung aktivieren
|
33 | TWSCRB |= (1<<TWAA)|(1<<TWCMD1)|(0<<TWCMD0);
|
34 | // TWSCRB - Slave Steuerregister B
|
35 | // TWAA - Quittierungsverhalten des Slaves
|
36 | // TWCMD1, TWCMD0 - Slave-Operation
|
37 | sei(); // Interrups einschalten
|
38 | }
|
39 |
|
40 | ISR( TWI_SLAVE_vect )
|
41 | {
|
42 | uint8_t status = TWSSRA & 0xC0; // Register A
|
43 | // TWSSRA - TWI-Slave-Status-Register A
|
44 | if (status & I2C_DATA_INTERRUPT) // Daten wurden vom Master empfangen oder werden angefordert
|
45 | {
|
46 | if (TWSSRA & (1 << TWDIR)) // Master fordert Daten vom Slave an
|
47 | // TWSSRA - TWI-Slave-Status-Register A
|
48 | // TWDIR - Richtungsbit des letzten von einem Master empfangenen Adresspakets an.
|
49 | // Wenn dieses Bit eins ist, wird ein Master-Lesevorgang durchgeführt.
|
50 | // Wenn das Bit Null ist, ist ein Master-Schreibvorgang im Gange.
|
51 | {
|
52 | if(tx_buf_index >= sizeof(tx_buf)) // ????
|
53 | { // ????
|
54 | tx_buf_index=0; // ????
|
55 | } // ????
|
56 | TWSD = tx_buff; // Sendepuffer vom Slave zum Master
|
57 | // TWSD - TWI-Slave-Datenregister
|
58 | // Datenregister wird beim Senden und Empfangen von Daten verwendet
|
59 | TWSCRB |= ((1<<TWCMD1)|(1<<TWCMD0));
|
60 | // TWSCRB - TWI-Slave-Steuerregister B
|
61 | // Die TWCMD-Bits geben automatisch die SCL-Leitung frei
|
62 | // und löscht die TWCH- und Slave-Interrupt-Flags.
|
63 | }
|
64 | else // Master sendet Daten zum Slave
|
65 | {
|
66 | TWSCRB |= ((1<<TWCMD1)|(1<<TWCMD0));
|
67 | // TWSCRB - TWI-Slave-Steuerregister B
|
68 | // TWCMD[1:0]: TWI-Befehl
|
69 | // Das Schreiben der TWCMD-Bits gibt automatisch die
|
70 | // SCL-Leitung frei und löscht die TWCH- und Slave-Interrupt-Flags.
|
71 | command = TWSD; // sendepuffer vom Master zum Slave
|
72 | // TWSD - TWI-Slave-Datenregister
|
73 | }
|
74 | }
|
75 | else if (status & I2C_ADDRESS_STOP_MATCH)
|
76 | {
|
77 | if (TWSSRA & I2C_BUS_COLLISION)
|
78 | {
|
79 | TWSCRB |= (1<<TWCMD1);
|
80 | // TWSCRB - TWI-Slave-Steuerregister B
|
81 | // TWCMD[1:0]: TWI-Befehl
|
82 | // Das Schreiben der TWCMD-Bits gibt automatisch die
|
83 | // SCL-Leitung frei und löscht die TWCH- und Slave-Interrupt-Flags.
|
84 | }
|
85 | else
|
86 | {
|
87 | if (TWSSRA & (1<<TWAS))
|
88 | // TWSSRA - TWI-Slave-Status-Register A
|
89 | // TWAS - TWI-Adresse oder Stopp
|
90 | // Bit zeigt an, warum das TWASIF-Bit zuletzt gesetzt wurde
|
91 | { // ACK
|
92 | TWSCRB |= ((1<<TWCMD1)|(1<<TWCMD0));
|
93 | // TWSCRB - TWI-Slave-Steuerregister B
|
94 | // TWCMD[1:0]: TWI-Befehl
|
95 | // Das Schreiben der TWCMD-Bits gibt automatisch die
|
96 | // SCL-Leitung frei und löscht die TWCH- und Slave-Interrupt-Flags.
|
97 | }
|
98 | else
|
99 | { // Stop Condition
|
100 | TWSCRB = (1<<TWCMD1); // muss so sein
|
101 | // TWSCRB - TWI-Slave-Steuerregister B
|
102 | // TWCMD[1:0]: TWI-Befehl
|
103 | // Das Schreiben der TWCMD-Bits gibt automatisch die
|
104 | // SCL-Leitung frei und löscht die TWCH- und Slave-Interrupt-Flags.
|
105 | }
|
106 | }
|
107 | }
|
108 | }
|
109 |
|
110 | int main(void)
|
111 | {
|
112 | DDRA=0b00000011; // Port A auf Ausgang schalten
|
113 | PORTA=0b00000011; // Port A auf aus
|
114 | DDRB=0b00000011; // Port A auf Ausgang schalten
|
115 | PORTB=0b00000011; // Port A auf aus
|
116 | I2C_init();
|
117 | while(1)
|
118 | {
|
119 | if (command != 42) // Taster T2 PD0
|
120 | { // Wenn T1 gedrückt...
|
121 | PORTA &=~(1<<PINA1); // LED 2 ein
|
122 | }
|
123 | else
|
124 | { // wenn nicht
|
125 | PORTA |=(1<<PINA1); // LED 2 ein ??
|
126 | }
|
127 | if (command != 43) // Taster T2 PD0
|
128 | { // Wenn T1 gedrückt...
|
129 | PORTA &=~(1<<PINA0); // LED 2 ein
|
130 | }
|
131 | else
|
132 | { // wenn nicht
|
133 | PORTA |=(1<<PINA0); // LED 2 ein ??
|
134 | }
|
135 | // ========>> TASTENEINGABEN T3
|
136 | if (!(PINA & (1<<PINA7)) ) // Taster T 3
|
137 | { // Wenn T3 gedrückt...
|
138 | //tx_buff = 5; // 4
|
139 | tx_buff = versa;
|
140 | }
|
141 | // ========>> TASTENEINGABEN T2
|
142 | if (!(PINB & (1<<PINB2)) ) // Taster T 3
|
143 | { // Wenn T3 gedrückt...
|
144 | //tx_buff = 3; // 4 geht aber ohne tx_buf[]
|
145 | tx_buff = versb;
|
146 | }
|
147 | }
|
148 | }
|