I²C problem - Hilflos

Gast #1124924
Lesenswert?

hey ho,
ich wollte endlich mal den i2c bus ausprobieren (aus reinen 
textzwecken).

Situation:
ich habe 2 atmega8, die ich richtig miteinander verbunden habe. im 
internet fand ich eine fertige i²c library, die auch fast funktioniert. 
Die funktionen habe ich bereits durchgeschaut und keine fehler gefunden, 
warum diese nicht ordnungsgemäß funktioniert, aber x*2 augen sehen mehr 
als 2 ;).

die i²c lib:
1
/* *************************************
2
   TWI Lib Version 5 oder so
3
   bhm 2006
4
  ************************************** */
5

6
// bislang keinmultimaster support
7
// keine Garanie für irgendwas
8
// Bemerkungen, Fehlerreports usw willkommen
9

10

11
#ifndef _TWILIB_
12
#define _TWILIB_ 1
13
                                  //Zugriff auf IO's des Controllers
14
#include <stdint.h>
15
#include <compat/twi.h>
16

17
void init_Master (void) {
18
   TWSR &= ~(_BV(TWPS0) | _BV(TWPS1));    //0b11111100: Prescaler auf 1 setzen, Bit 1 und 0 auf 0
19
   TWBR = 0x0A;                        //Bitrate auf 10 setzen, gibt 220kHz Bustakt bei 8MHz
20
}
21

22
void init_Slave (uint8_t SlvAdd) {
23
   TWAR = SlvAdd;                         // eigene Address, hier ohne general call
24
   TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);   //slave receive, TWEA > ACK,
25
}
26

27

28
void waitTWINT (void) {
29
   uint32_t m=0,mmax=8000000; //zZt einfach eine große Zahl
30

31
   while (bit_is_clear(TWCR, TWINT)) {
32
      if (m++ > mmax) return;         // bricht waitTWINT ab, TW_Status enthält dann TW_NO_INFO
33
   }
34
}
35

36
// *********** MasterTransmitter *************
37
// Daten in *Data, lenmax #Daten senden, MT #gesendete Daten
38
uint8_t MT (uint8_t SlvAdd, uint8_t *Data, uint8_t lenmax) {
39
   uint8_t len=1;
40
    
41
   TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);   //sende start
42
   waitTWINT();
43
   if ((TW_STATUS != TW_START) &&   (TW_STATUS != TW_REP_START)){   // chk Start | repeated start
44
      goto ENDE;
45
   }
46

47
   TWDR = SlvAdd + TW_WRITE;               //Addresse des Slaves angeben, SLA+W
48
   TWCR = _BV(TWINT) | _BV(TWEN);               // sende sla_w
49
   waitTWINT();
50
   if (TW_STATUS != TW_MT_SLA_ACK) {            // chk sla_ack
51
      goto STOP;
52
   }
53

54
   do {
55
      TWDR = *Data++;                // Datum laden
56
      TWCR = _BV(TWINT) | _BV(TWEN);            // sende Datum
57
      waitTWINT();
58
      if (TW_STATUS != TW_MT_DATA_ACK) {         // chk data_ack
59
         goto STOP;
60
      }
61
   } while (len++<lenmax);
62

63
STOP:
64
   TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);   // sende stop, kein warten auf TWINT
65

66
ENDE:
67
   return len-1;
68
}
69

70
// *********** MasterReceiver *************
71
// empfangene Daten nach *Data, Speicher muss bereitgestellt sein,
72
// lenmax #Daten empfangen, MR #empfangene Daten
73
uint8_t MR (uint8_t SlvAdd, uint8_t *Data, uint8_t lenmax) {
74
   uint8_t len=1;
75

76
   TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);   //sende start
77
   waitTWINT();
78
   if ((TW_STATUS != TW_START) &&   (TW_STATUS != TW_REP_START)){   // chk Start | repeated start
79
      goto ENDE;
80
   }
81

82
   TWDR = SlvAdd + TW_READ;                  //Addresse des Slaves angeben, SLA+r
83
   TWCR = _BV(TWINT) | _BV(TWEN);               // sende sla_r
84
   waitTWINT();
85
   if (TW_STATUS != TW_MR_SLA_ACK) {            // chk sla_ack
86
      goto STOP;
87
   }
88

89
   while (1) {          // endlos, verlassen via break in if TW_Status
90
      if (len<lenmax) {
91
         TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);      //receive, ACK,
92
      } else {
93
         TWCR =             _BV(TWEN) | _BV(TWINT);      //receive, NACK,
94
      }
95
      waitTWINT();
96
      if (TW_STATUS != TW_MR_DATA_ACK) break;         // LOOP VERLASSEN
97
      *Data++ = TWDR; len++;                     // Daten verarbeitet
98
   }
99

100
   if (TW_STATUS == TW_MR_DATA_NACK) {
101
      *Data++ = TWDR; len++;                     // Daten verarbeitet
102
      goto STOP;
103
   }
104

105
STOP:
106
   TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);   // sende stop, kein warten auf TWINT
107
ENDE:
108
   return len-1;
109
}
110

111

112
// *********** SlaveReceiver *************
113
// empfangene Daten nach *Data, Speicher muss bereitgestellt sein,
114
// lenmax #Daten empfangen, SR #empfangene Daten
115
uint8_t SR (uint8_t *Data, uint8_t lenmax) {
116
   uint8_t len=1;                  // lenmax >= 1, min ein Byte empfangen!
117

118
// auf SLA warten
119
   while (bit_is_clear(TWCR, TWINT));             // beliebig lange warten oder pollen
120

121
// jetzt geht's los
122
   if (TW_STATUS != TW_SR_SLA_ACK) {            // chk SLA+W
123
      goto STOP;
124
   }
125

126
   while (1) {          // endlos, verlassen via break in if TW_Status
127
      if (len<lenmax) {
128
         TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);      //slave receive, TWEA > ACK,
129
      } else {
130
         TWCR =             _BV(TWEN) | _BV(TWINT);      //slave receive, TWEA > NACK,
131
      }
132
      waitTWINT();
133
      if (TW_STATUS != TW_SR_DATA_ACK) break;         // LOOP VERLASSEN
134
      *Data++ = TWDR; len++;                     // Daten verarbeitet
135
   }
136

137
   if (TW_STATUS == TW_SR_DATA_NACK) {               // Datum mit NACK beantwortet
138
      *Data = TWDR; len++;                     // im Prinzip noch ein Datum verfügbar
139
   }
140

141
STOP:   // (TW_STATUS == TW_SR_STOP)  einzig anderer möglicher Status, von ARBs abgesehen
142
   TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);   //slave receive, TWEA > ACK,
143
   return len-1;
144
}
145

146
// *********** SlaveTransmitter *************
147
// Daten in *Data, lenmax #Daten senden, ST #gesendete Daten
148
uint8_t ST (uint8_t *Data, uint8_t lenmax) {
149
   uint8_t len=0;                  // lenmax >= 1, min ein Byte senden!
150

151
// auf SLA warten
152
   while (bit_is_clear(TWCR, TWINT));             // beliebig lange warten oder pollen
153

154
// jetzt geht's los
155
   if (TW_STATUS != TW_ST_SLA_ACK) {            // chk SLA+R
156
      goto STOP;
157
   }
158

159
   do {
160
      TWDR = *Data++; len++;
161
      if (len<lenmax) {
162
         TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);
163
      } else {
164
         TWCR = _BV(TWEN) | _BV(TWINT);
165
      }
166
      waitTWINT();
167
   } while (TW_STATUS == TW_ST_DATA_ACK);
168

169
STOP:
170
   TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);   //slave receive, TWEA > ACK,
171
   return len;
172
}
173

174
#endif

der quelltext vom master:
1
init_master();
2
MT(0b11010010, &tosend, 1); 
3

4
    MR(0b11010010,cache, 1);
5
    send(cache[0]); ///send funktion für rs232

der quelltext des slaves:
1
init_Slave(0b11010010);
2
SR(&cache,1);
3
if (cache == 0){ 
4
cache = 0b10101010;
5
ST(&cache,1);
6
}

es müsste also am pc über rs232 immer 170 ankommen,es kommt aber nur in 
ca 70 % der fälle an, die anderen werte sind willkürlcih von 0-255. und 
so hoch kann ja die übertragungsfehlerquote nicht sein oder? die beiden 
atmega werden mit 4 mhz betrieben.

kann mir jemand helfen ich weiß nicht weiter.
Warum werden so viele falsche bytes übertragen?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren