Forum: Mikrocontroller und Digitale Elektronik I²C problem - Hilflos


von Dondolo (Gast)


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?

von Der Einäugige (Gast)


Lesenswert?

> aber x*2 augen

das ist eine Annahme .-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.