ATMEGA8 - I2C bleibt bei "while(!(TWCR & (1<<TWINT)));" hängen

OP #4137905
Lesenswert?
• ▲
▼
Guten Abend,

ich habe folgendes Problem. Ich will mit meinem ATMEGA8 einen PCF8574 
Port Expander ansprechen. Die Adresse ist auf 0x40 eingestellt. Zudem 
verwende ich die lib von Peter Fleury. Angeschlossen ist soweit alles 
korrekt (Pins über 4,7k an +5V als Pullup), habe soweit alle Spannungen 
durchgemessen. Der Controller bleibt nun einfach bei dieser Zeile hängen
1
while(!(TWCR & (1<<TWINT)));

nachdem die Start-Bedingung mit
1
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

gesendet wurde. Mit einem Oszilloskop habe ich schon nachgesehen, ob 
überhaupt etwas auf den Pins passier, leider bleiben diese komplett tot. 
Daher bleibt wohl auch das Programm hier stehen. Taktrate ist auch 
angepasst im Header und mein C Programm sieht wie folgt aus:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include "i2cmaster.h"
5

6
#define PCF8574_ADDR 0x40
7

8
int main(void)
9
{
10
    sei(); // Enable Interrupts
11

12
    i2c_init(); // I2C initialisieren
13
    _delay_ms(500);
14
    
15
    i2c_start(PCF8574_ADDR | I2C_WRITE);
16
    i2c_write(0xFF);
17
    i2c_stop();
18

19
    while(1)
20
    ;
21

22
    return 0;
23
}

Durch LED ansteuern habe ich auch bereits getestet, dass das Programm 
wirklich bei oben genannter Stelle hängen bleibt. Zudem ist noch meine 
Frage, ob ich über sei() überhaupt die Interrupts global aktivieren muss 
für die TWI Kommunikation? Habe I2C bisher nur mit einem Cortex M3 
verwendet.

MfG
H0rBie
OP #4137929
Lesenswert?
• ▲
▼
Hallo Jörg,

die Geschwindigkeit ist laut dem define auf 100kHz gesetzt, die Leitung 
insgesamt ca. 30cm. Mich wundert allerdings, dass ich nichtmal auf dem 
Oszilloskop auf SDA oder SCL etwas sehen kann. Als wenn der Controller 
überhaupt gar nicht erst etwas überträgt.
OP #4138086
Lesenswert?
• ▲
▼
Hier der Code, hab das ganze nochmal ganz rudimentär versucht und mir 
ist aufgefallen, dass der SCL Pin nun auf 3,3V festhängt und SDA auf 5V. 
Ohne den AVR sind beide sauber auf 5V gezogen über die Pullup 
Widerstände. Habe die Stelle im Quellcode markiert, an der es hängen 
bleibt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4

5
#define PCF8574_ADDR 0x40
6

7
int main(void)
8
{
9
    uint8_t i = 0;
10
    DDRB = 0xFF; // Port B Ausgänge
11

12
    sei(); // Enable Interrupts
13
    _delay_ms(500);
14

15
    /* Blinken, dass resettet wurde */
16
    for(i = 0; i < 10; i++){
17
        PORTB |= (1 << PB0);
18
        _delay_ms(50);
19
        PORTB &= ~(1 << PB0);
20
        _delay_ms(50);
21
    }
22

23
/*****************************************************************/
24

25
    TWSR = 0;  // no prescaler
26
    TWBR = 52; // speed for 100kHz @ 12MHz CPU clock
27

28
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
29
    while(!(TWCR & (1<<TWINT))); // Hier hängt es schon fest.
30
    _delay_ms(50);
31

32
    TWDR = (0x20<<1) | 0;
33
    TWCR = (1<<TWINT) | (1<<TWEN);
34
    _delay_ms(50);
35

36
    TWDR = 0x0F;
37
    TWCR = (1<<TWINT) | (1<<TWEN);
38
    _delay_ms(50);
39

40
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
41
    _delay_ms(50);
42

43
    PORTB |= (1 << PB0);
44

45
    while(1)
46
    ;
47

48
    return 0;
49
}

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