1 | #define F_CPU 16000000UL
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <util/twi.h>
|
5 | #include <util/delay.h>
|
6 | #include <stdlib.h>
|
7 |
|
8 | #define F_SCL 400000L
|
9 |
|
10 | #define TWCR_START 0xA4 //send start condition
|
11 | #define TWCR_STOP 0x94 //send stop condition
|
12 | #define TWCR_RACK 0xC4 //receive byte and return ack to slave
|
13 | #define TWCR_RNACK 0x84 //receive byte and return nack to slave
|
14 | #define TWCR_SEND 0x84 //pokes the TWINT flag in TWCR and TWEN
|
15 |
|
16 | /* SLAVE ADRESSEN*/
|
17 | #define GENERAL_CALL 0x00
|
18 | #define SLAVE 0x7F
|
19 | #define SLAVE1 0x7E
|
20 |
|
21 |
|
22 | void I2C_INIT()
|
23 | {
|
24 | TWSR = 0;
|
25 | TWBR = ((F_CPU/F_SCL)-16)/2;
|
26 | }
|
27 |
|
28 | void I2C_ERROR()
|
29 | {
|
30 | /* Hier Code für ERROR fall*/
|
31 | }
|
32 |
|
33 | void MASTER_START (uint8_t add_SLAVE,uint8_t TM_STATUS)
|
34 | {
|
35 | while(1)
|
36 | {
|
37 | TWCR = TWCR_START; /* Start*/
|
38 |
|
39 | while (!(TWCR & (1<<TWINT)) ); /* Warten bis Start ausgeführt*/
|
40 | if(!(TW_STATUS == TW_START)) /* Start erfolgreich: Ja weiter im Programm / Nein :ERROR*/
|
41 | {
|
42 | I2C_ERROR();
|
43 | }
|
44 |
|
45 | TWDR = (add_SLAVE<<1|TM_STATUS);
|
46 | TWCR = TWCR_SEND;
|
47 |
|
48 | while (!(TWCR & (1<<TWINT)));
|
49 | switch (TW_STATUS)
|
50 | {
|
51 | case TW_SR_GCALL_ACK:
|
52 | break;
|
53 |
|
54 | case TW_MT_SLA_ACK:
|
55 | break;
|
56 |
|
57 |
|
58 | case TW_MT_SLA_NACK:
|
59 | TWCR = TWCR_STOP;
|
60 | while(TWCR & (1<<TWSTO));
|
61 | continue;
|
62 |
|
63 | case TW_MR_SLA_ACK:
|
64 | break;
|
65 |
|
66 | case TW_MR_DATA_NACK:
|
67 | TWCR = TWCR_STOP;
|
68 | while(TWCR & (1<<TWSTO));
|
69 | continue;
|
70 |
|
71 | default:
|
72 | I2C_ERROR();
|
73 |
|
74 | }
|
75 | break;
|
76 | }
|
77 | }
|
78 |
|
79 |
|
80 | void MASTER_STOP()
|
81 | {
|
82 | TWCR = TWCR_STOP;
|
83 |
|
84 | while(TWCR & (1<<TWSTO));
|
85 | }
|
86 |
|
87 | void MASTER_DATA_WIRTE(uint8_t DATA)
|
88 | {
|
89 | TWDR = DATA;
|
90 | TWCR = TWCR_SEND;
|
91 |
|
92 | while(!(TWCR & (1<<TWINT)));
|
93 | switch (TW_STATUS)
|
94 | {
|
95 | case TW_MT_DATA_ACK:
|
96 | break;
|
97 |
|
98 | case TW_MT_DATA_NACK:
|
99 | MASTER_STOP();
|
100 | break;
|
101 |
|
102 | default:
|
103 | I2C_ERROR();
|
104 | }
|
105 | }
|
106 |
|
107 | void MASTER_DATA_READ_ACK(uint8_t DATA)
|
108 | {
|
109 | TWCR = TWCR_RACK;
|
110 | while(!(TWCR & (1<<TWINT)));
|
111 |
|
112 | DATA = TWDR;
|
113 |
|
114 | switch (TW_STATUS)
|
115 | {
|
116 | case TW_MR_DATA_ACK:
|
117 | break;
|
118 |
|
119 | default:
|
120 | I2C_ERROR();
|
121 | }
|
122 | }
|
123 |
|
124 | void MASTER_DATA_READ_NACK(uint8_t DATA)
|
125 | {
|
126 | TWCR = TWCR_RNACK;
|
127 | while(!(TWCR & (1<<TWINT)));
|
128 |
|
129 | DATA = TWDR;
|
130 |
|
131 | switch (TW_STATUS)
|
132 | {
|
133 | case TW_MR_DATA_NACK:
|
134 | MASTER_STOP();
|
135 | break;
|
136 |
|
137 | default:
|
138 | I2C_ERROR();
|
139 | }
|
140 | }
|
141 |
|
142 | void MT_SLAVE(uint8_t DATA, uint8_t DATA1, uint8_t DATA2)
|
143 | {
|
144 |
|
145 | MASTER_START(SLAVE,TW_WRITE);
|
146 | MASTER_DATA_WIRTE(DATA);
|
147 | MASTER_DATA_WIRTE(DATA1);
|
148 | MASTER_DATA_WIRTE(DATA2);
|
149 | MASTER_STOP();
|
150 | }
|
151 |
|
152 | void MR_SLAVE(uint8_t DATA)
|
153 | {
|
154 | MASTER_START(SLAVE,TW_READ);
|
155 | MASTER_DATA_READ_ACK(DATA);
|
156 | MASTER_DATA_READ_ACK(DATA);
|
157 | MASTER_DATA_READ_ACK(DATA);
|
158 | MASTER_DATA_READ_ACK(DATA);
|
159 | MASTER_DATA_READ_NACK(DATA);
|
160 |
|
161 | }
|
162 |
|
163 | int main(void)
|
164 | {
|
165 | I2C_INIT(); /* I2C Initialisierung Durchführen*/
|
166 | uint8_t DATA = 1;
|
167 | uint8_t DATA1 = 3;
|
168 | uint8_t DATA2 = 7;
|
169 | while (1)
|
170 | {
|
171 |
|
172 | MT_SLAVE(DATA,DATA1,DATA2);
|
173 | MR_SLAVE(DATA1);
|
174 | DATA = DATA1;
|
175 |
|
176 | }
|
177 | return 0;
|
178 | }
|