Forum: Mikrocontroller und Digitale Elektronik ATMeaga8 TWI Slave blockiert


von Fabian S. (jacky2k)


Lesenswert?

Hallo,
ich habe hier mal wieder ein herbes Problem mit TWI. Kommunizieren 
sollen zwei ATMega8 untereinander (später auch mehr). Für den Master 
verwende ich die Lib von Peter Fleury.
Den Slave habe ich Interruptbasiert selbst geschrieben.

Master:
1
  while(1)
2
  {
3
    uint8_t ret;
4
    ret = i2c_start(0x10+I2C_READ);       // set device address and write mode
5
    if(ret)
6
    {
7
      i2c_stop();
8
      uart_putcc("Failed to read!\r\n");
9
    }
10
    else
11
    {
12
      if(i2c_readAck()!=2) uart_putc('E');
13
      if(i2c_readAck()!=2) uart_putc('E');
14
      if(i2c_readAck()!=2) uart_putc('E');
15
      if(i2c_readAck()!=2) uart_putc('E');
16
      if(i2c_readAck()!=2) uart_putc('E');
17
      if(i2c_readNak()!=2) uart_putc('E');
18
      i2c_stop();
19
      uart_putc('r');
20
    }
21
    sleep_10ms(100);
22
  }

Slave:
1
#include "TWISlave.h"
2
3
uint8_t counter;
4
uint8_t sender;
5
uint8_t volatile watchdog;
6
7
void twi_init()
8
{
9
  TWAR= 0x10; //Adresse setzen
10
  TWCR &= ~(1<<TWSTA)|(1<<TWSTO);
11
  TWCR|= (1<<TWEA) | (1<<TWEN)|(1<<TWIE);
12
  
13
  //fifo_init(&twi_fifo_out,  twi_buffer_out,  TWI_BUFFERSIZE_OUT);
14
  //fifo_init(&twi_fifo_in,  twi_buffer_in,  TWI_BUFFERSIZE_IN);
15
  watchdog=0;
16
  counter=0;
17
  sender=0;
18
}
19
20
ISR(TWI_vect)
21
{
22
  uint8_t data, event;
23
  event=TWSR & 0xF8;
24
  switch (event)
25
  {
26
    case 0x00: // Error detected
27
      counter++;
28
      uart_putcc("TWI: Error!\r\n");
29
      break;
30
31
    /* Transmitter */
32
    case TW_ST_DATA_NACK: // last byte send, NACK received
33
      TWDR=0x01;
34
      TWCR_ACK;
35
      uart_putc('w');
36
      break;
37
    case TW_ST_SLA_ACK:   // slave was adressed, Master wants to read first byte
38
      counter=0;
39
      uart_putc('a');
40
    case TW_ST_DATA_ACK:  // master wants to read next byte...
41
      TWDR=0x02;
42
      counter++;
43
      TWCR_ACK
44
      uart_putc('s');
45
      break;
46
    case TW_ST_LAST_DATA: //0xC8  last data byte in TWDR has been transmitted (TWEA = 0); ACK has been received
47
      //TWDR=0x03;
48
      TWCR_ACK;
49
      uart_putc('l');
50
      break;
51
52
    /* Reciver */
53
    case TW_SR_SLA_ACK: // 0x60 slave was adressed as receiver, no byte send yet
54
      TWCR_ACK;
55
      break;
56
    case TW_SR_DATA_ACK:   // got data from master
57
      data=TWDR;
58
      TWCR_ACK
59
      //fifo_put(&twi_fifo_in, data);
60
      break;
61
    case TW_SR_DATA_NACK: //0x88
62
    case TW_SR_STOP:
63
      TWCR_ACK
64
      break;
65
    default:
66
      counter++;
67
      uart_putcc("TWI: unknown event: ");
68
      uart_puti(event);
69
      uart_putcc("\r\n");
70
      break;
71
  }
72
}

Nach ein paar Übertragungen (i.d.R. 4) friert alles ein und nichts 
passiert mehr. SDA und SCL liegen auf Low, wenn ich den Master rausziehe 
sind sie immernoch auf Low, wenn ich dann noch den Slave rausziehe nicht 
mehr, also muss der Slave Mist bauen würde ich sagen.
Kann jemand da was erkennen? Bin am verzweifeln :(

Edit:
Ausgabe Slave: asssssswasssssswasssssswassssssw
Ausgabe Master: rrrr

von TWI Master (Gast)


Lesenswert?

Moin,

AVR Application Notes AVR311/315 durcharbeiten und Stück für Stück auf 
deine Bedürfnisse anpassen. Auf Basis der 2 Beispiele ist hier ein 
Multimaster System entstanden, das im produktiven Einsatz noch keine 
Probleme machte.

viel Erfolg.

von Fabian S. (jacky2k)


Lesenswert?

Ohh cool, die kannte ich noch garnicht. Vielen Dank erstmal, hab sie 
schon ausgedruckt und werde sie mir gleich reinziehen ;)

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.