Habe eine Atmega32 16Mhz TC74 Sensor mit I2C verbunden ( Pull up sind dran) 1 Schritt Frequenz einstellen TWSR = 0; TWBR = ((F_CPU/SCL_CLOCK)-16)/2; // 72 2 Schritt Startbedingung TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while(!(TWCR & (1<<TWINT))); // Prüfen 3 Schritt Adresse ( 7 Bit) + Low (1 Bit) Für das Schreiben I2C_sende(0x90); // Hier kommt immer Kein ACK void I2C_sende(int daten) { TWDR = daten; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); // Warte bis gesendet if((TWSR & 0xF8) != TW_MT_DATA_ACK) { USART_putstring("Kein ACK"); } else { USART_putstring("ACK"); } } Was mache ich Falsch ? Habe es schon mit Adresse 0x00 Probiert auch kein Ack
:
Verschoben durch Moderator
The TC74 is internally programmed to have a default SMBus/I2C address value of 1001 101b. Fehlt noch RW-Bit => 0x9A bzw. 0x9B
Mein Code leider geht es immer noch nicht. Hast du ein anderen Tipp? #define F_CPU 16000000UL #define BAUD 9600 // define baud #define BAUDRATE ((F_CPU)/(BAUD*16UL)-1) #define SCL_CLOCK 100000 //100 kHz #include <avr/io.h> #include <util/delay.h> #include <util/twi.h> #include<stdbool.h> #include "USART.h" #include <avr/io.h> void I2C_sende(int daten) { TWDR = daten; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); // Warte bis gesendet if((TWSR & 0xF8) != TW_MT_DATA_ACK) { USART_putstring("Kein ACK!!!"); } else { USART_putstring("ACK"); } } void I2C_start(int adresse) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while(!(TWCR & (1<<TWINT))); int twst = TW_STATUS & 0xF8; if ( (twst != TW_START) && (twst != TW_REP_START)) { USART_putstring("Fehler beim Start "); } else { USART_putstring("Kein Fehler beim Start "); } I2C_sende(adresse); } void I2C_init(void) { DDRC &= !((1<<DD0)|(1<<DD1)); PORTC = (1<<DD0)|(1<<DD1); TWSR = 0; /* no prescaler */ TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ } int main(void) { USART_init(); I2C_init(); TWSR = 0; TWBR = ((F_CPU/SCL_CLOCK)-16)/2; // 72 I2C_start(0x9B); while(1) { //TODO:: Please write your application code } }
Statt einfach bloss "Bäh!" auszugeben könntest du den Status ausgeben. Soweit ich mit erinnere ist der bei Adresse und Daten verschieden.
Der gelieferte Inhalt von TW_STATUS. Das was dir nicht passt. Konkret: Bei z.B. Master Write gibts 0x18 nach der Adresse und 0x28 nach einem Datenbyte. Du sendest eine Adresse und erwartest die Quittung für ein Datenbyte.
TW_STATUS passt mir ja, dass klappt alles. BZW. Start Codition wird gesendet. Bekomme einfach kein ACK Mein TWSR ist 64 = 0100 0000 (Binär) falls du das meinst.
:
Bearbeitet durch User
Joe M. schrieb: > TW_STATUS passt mir ja, dass klappt alles. Deine Aussage war bisher doch, du würdest auf die Adresse kein ACK kriegen. Dein Code dafür sieht bisher so aus:
1 | if((TWSR & 0xF8) != TW_MT_DATA_ACK) |
2 | {
|
3 | USART_putstring("Kein ACK!!!"); |
4 | }
|
Dieser Code ist jedoch nur für Datenbytes im Master-Transmit geeignet,
nicht aber für das Adressbyte in egal welchem Modus, da die Statemachine
des TWI auch bei einer erfolgreichen Adressierung des Slave
keinesfalls TW_MT_DATA_ACK liefert.
Eben darauf wollte ich dich mit dem Hinweis stossen, dass es wesentlich
sinnvoller wäre, statt
USART_putstring("Kein ACK!!!");
sowas wie
USART_puthex("TWI Status=", TWST);
auszugeben. Damit du siehst, was tatsächlich passiert.
> Bekomme einfach kein ACK
Basierend auf Oszi/LA-Anzeige, oder basierend auf dem obigen Code? Dein
Code ist für diese Aussage nicht geeignet. Der zeigt nur, dass du nicht
jenen Status kriegst, den du erwartest hast.
:
Bearbeitet durch User
Joe M. schrieb: > Bekomme einfach kein ACK > > Mein TWSR ist 64 = 0100 0000 (Binär) falls du das meinst. Dann schau doch mal in deine <util/twi.h> und schau nach was die 64 (oder 0x40 als hex) bedeuten. Vielleicht wird dir dann klarer was dir A.K. sagen will
Habe es Danke sehr vielen dank :-D Jetzt klappt das ACK. ok Jetzt das 2 Problem. Der Sensor sendet keine Daten i2c_init(); i2c_start(0x9A); // Start Cond+ Sendet Adresse + SchreibBit i2c_write(0x00); // Code für das lesen der Temp. i2c_start(0x9A+1); //Start Cond+ Adresse + LeseBit int a = i2c_readNak(); // Hier kommt leider nur 0 raus :-( i2c_stop(); Was im I2C Angezeigt wird: s (Start Cod.) 9A A (Sendet 9A bekommt ACK) 00 A (Sendet 00 bekommt ACK) Sr (Start Cod.) 9B A (Sendet 9B bekommt ACK) 00 N (Beim lesen überträgt er nur 0er Bits) p ( Stop bed.)
:
Bearbeitet durch User
Der TC74 schafft 8 Samples/Sec, also alle 125 ms eine. Du versuchst es aber glich nach dem Start. Gib ihm einfach mal etwas Zeit.
Hallo, ich versuche gerade die RTC RV-3029-C2 in Betrieb zu nehmen, leider ohne Erfolg. Ich nutze Altmelstudio 7 mit Codevision-Plugin. Zum lesen und schreiben über I2C/TWI nutze ich die twi_master_trans(). Andere I2C Busteilnehmer konnte ich damit erfolgreich auslesen und schreiben. Zu Testzwecken ist die RTC nun alleine am BUS. In Anhang findet Ihr ein Oszi Bild. Dort ist zu sehen das die RTC kein ACK sendet. Pullups sind jeweils 2,7k. Wo könnte der Fehler liegen? Achso, die twi_master_trans() Funktion gibt auch zurück das ein ACK fehlt. SCL Rate ist 400k bps. 100k bps geht aber auch nicht. Danke schon im Vorraus :-) Elektrischer Anschluss: PIN1: 3,29V (gemessen) PIN2: Offen PIN3: Offen PIN4: SCL (siehe Oszibild - CH Gelb) PIN5: SDA (siehe Oszibild - CH Blau) PIN6: 0V (gemessen) PIN7: Offen PIN8: 0V (gemessen, über 10k Pulldown an GND angeschlossen) PIN9: Offen PIN10: Offen Quellcodeausschnitt: #define I2C_ADRESSE 0xAC //Nachrichten IDs typedef enum { //Controll Page RTC_CONTROL1 = 0x00 , // RTC_CONTROL_INT , RTC_CONTROL_INT_FLAG , RTC_CONTROL_STATUS , RTC_CONTROL_RESET , // Clock Page RTC_SECONDS = 0x08 , RTC_MINUTES , RTC_HOURS , RTC_DAYS , RTC_WEEKDAYS , RTC_MONTHS , RTC_YEARS , // ALARM PAGE RTC_SECOND_ALARM = 0x10 , RTC_MINUTE_ALARM , RTC_HOUR_ALARM , RTC_DAY_ALARM , RTC_WEEKDAY_ALARM , RTC_MONTH_ALARM , RTC_YEAR_ALARM , // TIMER PAGE RTC_TIMER_LOW = 0x18 , RTC_TIMER_HIGH , // TEMPERTUR PAGE RTC_TEMPERATURE = 0x20 , // EEPROM USER PAGE RTC_EEPROM_USER1 = 0x28 , RTC_EEPROM_USER2 , // EEPROM CONTROL PAGE RTC_EEPROM_CONTROL = 0x30 , RTC_EEPROM_XTAL_OFFSET , RTC_EEPROM_XTAL_COEF , RTC_EEPROM_XTAL_T0 , // EEPROM CONTROL PAGE RTC_USER_RAM = 0x38 , // Size RTC_SIZE = 0x3F , }tRTC_REG_ID; void twie_init(void) { // General TWIE initialization // External Driver Interface: OFff // SDA Hold: Off twi_init(&TWIE,false,TWI_SDAHOLD_OFF_gc); // Note: The directions of the SDA_IN (PORTE Pin 0), SCL_IN (PORTE Pin 1), // SDA_OUT (PORTE Pin 2) and SCL_OUT (PORTE Pin 3) signals are configured // in the ports_init function // TWIE Master initialization // Master interrupt: Low Level // Peripheral Clock frequency: 32000000 Hz // SCL Rate: 400000 bps // Real SCL Rate: 400000 bps, Error: 0,0 % twi_master_init(&twie_master,&TWIE,TWI_MASTER_INTLVL_LO_gc, TWI_BAUD_REG(32000000,400000)); // TWIE Slave is disabled TWIE.SLAVE.CTRLA=0; } void RTC_SetRegister(tRTC_REG_ID StartReg, uint8_t *Data, uint8_t Anz) { uint8_t TX_Buffer[16]; TX_Buffer[0] = StartReg; if(Anz < 16) { memcpy(&TX_Buffer[1], Data, Anz); twi_master_trans(&twie_master, I2C_ADRESSE, TX_Buffer, Anz + 1, 0, 0); } } void RTC_GetRegister(tRTC_REG_ID StartReg, uint8_t *Data, uint8_t Anz) { uint8_t TX_Buffer[32]; TX_Buffer[0] = StartReg; twi_master_trans(&twie_master, I2C_ADRESSE, TX_Buffer, 1, Data, Anz); }
ehrlich? ich würde die Fleury LIB installieren. http://homepage.hispeed.ch/peterfleury/avr-software.html Als letztes Zeichen muss ja NACK kommen und nicht ACK. Ich würde nicht immer auf 16 Zeichen Antwort warten, ich weiss doch wie viel Zeichen ich erwarte und für das letzte muss es NACK sein. Dann gibt es noch I2C Stretching auch das wäre zu prüfen, da neheme ich immer die Arduino LIB und versuche den Slave solange anzusprechen bis er wieder antwortet, kann ja auch mit einem Timeout kombiniert werden.
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.