Forum: Mikrocontroller und Digitale Elektronik Master am TWI Bus haengt wenn.


von Axel K. (axel)


Lesenswert?

Guten Abend!

Ich habe 2 Atmega8 mittels TWI verbunden. Derzeit sendet nur der Eine im 
Master Transmitmode.

Das Problem ist, dass sobald ich die Warteschleife von 10ms nach senden 
der Startbedingung auf 9ms verkuerze, dann laeuft der Transfer immernoch 
vollstaendig durch, aber es findet kein weiterer statt - so als ob wie 
Bedingung in der while Schleife nie erfuellt wird.

Kann mir da jemand weiterhelfen? Theoretisch sollte eigentlich garkeine 
Warteschleife vonnoeten sein. Bei einem Controllertakt von 1Mhz 
uebrigends funzt alles bei 28ms delay und bei 27ms nicht mehr....

Hier der Code vom Master:
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

gruss Axel

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.