Forum: Mikrocontroller und Digitale Elektronik Problem mit TWI-Schnittstelle


von B.L.M (Gast)


Lesenswert?

Hi
Ich habe folgendes Problem:

Ich möchte mit folgendem Code eine Verbindung und damit eine 
Kommunikation zu einem I2C-bus-Analyzer herstellen.
Leider funktioniert das Programm im vornherein noch nicht ganz.

Fehler:
Beim herunterladen ist ein kurzes aufleuchten der Leds bemerkbar, wobei 
ich eigentlich eine Status-Anzeige des Statusregisters TWSR ausgeben 
möchte. Ich glaube dass das Programm irgendwo stecken bleibt, und zwar 
gleich nach der Initialisierung.
1
#include <inttypes.h>
2
#include <avr/io.h>    
3
#include <avr/delay.h>
4
#include <util/twi.h> 
5
#include <stdlib.h>
6
7
8
//-----------------------------------------------------------------------------------------------
9
// read and write address, A15 is uesd for communication between ATmega128 and DLP-USB245M
10
#define ADDRESS 0x8000
11
12
int SendeByte(unsigned char datenbyte, unsigned char adresse);
13
14
//----------------------------------------------------------------------------------------------
15
16
17
void sysinit(void)
18
{
19
  SFIOR=SFIOR|0x04;      // interne Pull-Ups abstellen, Seite 70 datenblatt 
20
  MCUCR=MCUCR|0x80;      // activate the external memory interface, P29
21
  XMCRA=0x00;          // The entire external memory address space is treated as one sector.
22
  XMCRB=0x00;          // Writing XMBK to one enables the bus keeper on the AD7:0 lines.
23
  
24
  DDRC=0xFF;          // Output
25
  DDRD=0xFF;          // Output
26
  DDRB=0xFF;          // Output
27
  DDRE=0xFF;          // Output
28
  DDRF=0xFF;          // Output
29
  PORTB=0x00;
30
  PORTE=0x00;
31
  PORTF=0x00;  
32
  PORTD=0xFF;          // Leds dunkel
33
34
35
36
  TWAR=0x03;          // Adresse 0x02 = erster und einziger Slave
37
  TWBR=0x01;          // Bit Rate Register -> SCLf = (CPUf/(16+2(01)*4^1))) = 149kHz
38
  TWCR=0x45;          // Control Register TWINT / TWEA / TWEN / TWIE -> "high"
39
//  TWDR=0xFF;          // Data Register
40
  TWSR=0xF8;          // Status Register
41
42
}
43
44
45
// CPUf = 3596400
46
  
47
int main(void)
48
{
49
  sysinit();
50
  
51
  unsigned char adresse, i;
52
  i=0x01;
53
  while(1)          //Hauptschleife
54
  {            
55
/*    PORTD = 0x01;
56
    _delay_ms(10);      // Blinklicht test (geht auch nicht)
57
    PORTD = 0x02;
58
    _delay_ms(10); */
59
      
60
    if(i==0x80) i=0x01;    //wenn am linken Ende, von vorne anfangen
61
    else i<<=1;        //ansonsten nach links schieben  
62
    PORTD = TWSR;
63
    _delay_ms(500);      //500ms warten
64
    SendeByte(adresse, i);  //Wert an Leds übertragen 
65
  }
66
67
  return 0;
68
}
69
70
int SendeByte(unsigned char datenbyte, unsigned char adresse)
71
{
72
  DDRC &= !((1<<DD0)|(1<<DD1));        //SDA und SCL lesen
73
  PORTC= (1<<DD0)|(1<<DD1);          //und Pullups aktivieren
74
75
  TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);    //TWI aktivieren und Start-Kondition auslösen
76
  while(!(TWCR & (1<<TWINT)));        //warten auf Start-Kondition
77
78
//  PORTD = TWSR;
79
//  _delay_ms(5000);
80
81
  if((TWSR & 0xF8) != TWSTA) return 0;    //Wenn keine Start-Kondition gesendet wurde, abbrechen
82
83
  
84
  TWDR=adresse & (0xFE);            //Adresse mit Schreibbit (XXXXXXX0) in Datenregister laden...
85
  TWCR= ((1<<TWINT)|(1<<TWEN));        //... und senden
86
  while(!(TWCR & (1<<TWINT)));        //warten auf ACK oder NAK
87
  if((TWSR & 0xF8) != TW_MT_SLA_ACK) return twiStop();    //Wenn kein Slave reagiert
88
                    
89
  TWDR=datenbyte;                //Byte in Datenregister laden...
90
  TWCR= ((1<<TWINT)|(1<<TWEN));        //... und senden
91
  while(!(TWCR & (1<<TWINT)));        //warten auf ACK oder NAK
92
  if((TWSR & 0xF8) != TW_MT_DATA_ACK) return twiStop();    //Wenn nicht von Slave akzeptiert, abbrechen
93
94
  TWCR= ((1<<TWINT)|(1<<TWSTO)|(1<<TWEN));  //STOP-Kondition
95
  return 0;                  
96
}

Ich benutze AVR-Studio 4 mit einem STK500 Board und dem STK501 Aufsatz.

Über eine Idee oder einen Lösungsansatz wäre ich sehr froh, denn ich 
sitze nun seit etwa 3 Tagen am gleichen Problem.

Freundliche Grüsse
B.L.M

von B.L.M (Gast)


Lesenswert?

Hat sich erledigt...

Lösung:
1
SFIOR=SFIOR|0x04;      // interne Pull-Ups abstellen, Seite 70 datenblatt   LÖSCHEN!! 
2
  MCUCR=MCUCR|0x80;      // activate the external memory interface, P29   LÖSCHEN!!
3
  XMCRA=0x00;          // The entire external memory address space is treated as one sector.   LÖSCHEN!!    
4
  XMCRB=0x00;          // Writing XMBK to one enables the bus keeper on the AD7:0 lines.   LÖSCHEN!!
5
  
6
  DDRC=0xFF;          
7
  DDRD=0xFF;          
8
  DDRB=0xFF;          
9
  DDRE=0xFF;          
10
  DDRF=0xFF;          
11
  PORTB=0x00;
12
  PORTE=0x00;
13
  PORTF=0x00;  
14
  PORTD=0xFF;          // Nur die PORTs angeben die ihr braucht
15
16
17
18
  TWAR=0x03;          // Adresse 0x02 = erster und einziger Slave
19
  TWBR=0x01;          // Bit Rate Register -> SCLf = (CPUf/(16+2(01)*4^1))) = 149kHz
20
  TWCR=0x45;          // Control Register TWINT / TWEA / TWEN / TWIE -> "high"   LÖSCHEN!!
21
  TWDR=0xFF;          // Data Register   LÖSCHEN!!
22
  TWSR=0xF8;          // Status Register   LÖSCHEN!!

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.