PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Atmega32 Probleme mit dem TWI



Kuba
13.06.2014, 10:23
Hallo, ich bin neu hier und ich hoffe hier kann mir wer weiter helfen.

Ich versuche mich zurzeit mit dem i2c.

Benutzen tue ich ein PCF und den ATmega32.

Nun habe ich folgendes Problem.

Benutzen tue ich die internen PULL-UP's sind zwar eigentlich nicht dafür da aber komischerweise funktioniert das ganze damit halb..oder auch nicht..

Also wenn ich die Internen benutze kann ich das SCL Signal mit einem Ozi messen, mit externen nicht.

Zum Daten Signal dies kann ich immer messen ABER NUR wenn ich debugge, sobald ich Stoppe ist es weg ( Eine konstante Spannung ist nun nur da, durch denn Pull-Up). Und es liegt auch nur bei 3,3V. Betrieben wird das ganze mit 5V also liegt im Bereich wo es nicht funktionieren kann ( Wenn ich mich nicht irre).

Externe Pull-Up 3k6 , 4k7, 10k getestet.

Benutzt habe ich die p.Fluery Routine aber auch mal meine eigene beides das selbe..hier mal der aktuelle Code .



#include <avr/io.h>
#define F_CPU 16000000UL
#define SCL_CLOCK 100000L
#include <util/delay.h>
#include <avr/interrupt.h>
#include <util/twi.h>
#include <compat/twi.h>
#include "i2cmaster.h"


void i2c_init(void)
{
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */

TWSR = 0; /* no prescaler */
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */

}/* i2c_init */

unsigned char TWI_ROUTINE(unsigned char SLA_W , unsigned char DATA){

uint8_t twst;

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
TWDR = SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
TWDR = DATA;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))) ;
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);



return 0;
}

int main(void){

DDRB = 0xff;
DDRD = 0x00;
DDRA = 0x00;
//DDRC = (1<<PC0) | (1<<PC1);
//PORTC = (1<<PC0) | (1<<PC1);


i2c_init();


while(1)
{


TWI_ROUTINE(0b01000000 , 0xFF); // PCF A0,A1,A2 = 0 gegen GND


}
}



Im Anhang der Schaltplan, Der PCF ist auf ein Steckboard mit kurzen Strippen verbunden. ( versuche gleich nochmal..der möchte die Grafik nicht hochladen )

- - - Aktualisiert - - -

28370
Hier hoffentlich erkennt man was.

BMS
13.06.2014, 11:42
Hallo,
wieso sind diese beiden Zeilen

//DDRC = (1<<PC0) | (1<<PC1);
//PORTC = (1<<PC0) | (1<<PC1);
auskommentiert?
Ohne die erste Zeile werden SDA und SCL nicht als Ausgang geschaltet und der ATmega kann den I2C-Bus dann nicht als Master bedienen.
Die Zeile mit DDRC=... brauchst du also auf jeden Fall !
Die Zeile PORTC=... brauchst du, wenn keine externen Pullups verwendet werden.
Grüße, Bernhard

Kuba
13.06.2014, 11:57
Es juckt den im Moment nicht ob's ausgeklammert ist oder nicht :S
Eigentlich ist es nicht auskommentiert.