- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 10

Thema: I2C-Probs

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    16.11.2008
    Ort
    Frankfurt
    Alter
    40
    Beiträge
    21

    I2C-Probs

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi Leute!
    Ich hab mir mit nem Atmega8 ne kleine Erweiterung gebaut. Da hängt ein LCD dran, und ich will von der Base Nachrichten hinschicken, die dann auf dem LCD ausgegeben werden.
    Ich hab den TWI-Master-Code und header im Base-Projekt eingebunden, und den TWI-Slave-Code und header in meinen Code und Makefile für den Atmega8.
    Ich habe mal testweise im Atmega8 readRegisters mit Werten befüllt, und kann diese auch erfolgreich von der Base auslesen. Nur, wenn ich versuche von der Base was in die writeRegisters zu schreiben, kommt dort anscheinend nichts an (Funktion aus Anleitung: transmit3Bytes(SlaveAddr, Reg#, data1, data2).

    Hier ist der Code, der auf der Base läuft (abgespeckt, da läuft noch Example07, die State-Machine drauf):
    Code:
    #include "RP6RobotBaseLib.h" 	
    
    #include "RP6I2CmasterTWI.h"
    
    
    void I2C_transmissionError(uint8_t errorState)
    
    {
    
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    
    	writeInteger(errorState, HEX);
    
    	writeChar('\n');
    
    }
    
    
    int main(void)
    
    {
    
    	initRobotBase(); 
    	// I2C Master initialisieren
    
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
    	powerON();
    
    	while(true) 
    
    	{		
    
                   // versuche, was zu schreiben
    		I2CTWI_transmit3Bytes(15, 0, 1, 3);
    
    		//versuchen was zu lesen, Register 0-3:
    		//I2CTWI_transmitByte(15, 0);
    		uint8_t results[ 4];
    	        I2CTWI_readBytes(15, results, 3);
    		writeString_P("\n Empfangen (0-3): ");
    		for(int i=0; i<3; i++){
    			writeInteger(results[i], DEC);
    			writeString_P(" - ");
    		}
    		writeString_P("\n");
    		
    	}
    
    	return 0;
    
    }
    Und hier der Code der Atmega8-LCD-Erweiterungsplatine:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdio.h>
    #include <stdint.h>
    #include "General.h"
    #include "Delay.h"
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include "lcd-routines.h"
    #include "RP6I2CslaveTWI.h"
    
    #define CMD_ZEILE_1 1
    #define CMD_ZEILE_2 2
    
    int main(void)
    {
        // LCD-INIT -----------------------------------
    	lcd_init();
    	lcd_string("RP6 Robo-LCD");
    	Delay_ms(2500);
    
        // I2C-INIT -----------------------------------
        	I2CTWI_initSlave(15); // Wir haben Adresse 15!
    	set_cursor(0,1);
    	lcd_clear();
    	lcd_string("Waiting.....");
    
        // MAIN-LOOP ----------------------------------
        while(1)
        {
    
    	    // schreib mal irgendwas ins register, was ausgelesen wird
    	    I2CTWI_readRegisters[0] = 5;
    	    I2CTWI_readRegisters[1] = 8;
    	    I2CTWI_readRegisters[2] = 7;
    
    
    	// empfangen und kein Schreibzugriff aktiv
    	if(I2CTWI_writeRegisters[0]!='_' && !I2CTWI_writeBusy){
    		// TEST
    		lcd_clear();
    		set_cursor(0,2);
    		lcd_string("Innere Schleife");
    
    		// speichern 
    		char buffer[20];
    		uint8_t cmd = I2CTWI_writeRegisters[0];
    		I2CTWI_writeRegisters[0] = 0; //zurücksetzen
    		uint8_t param = I2CTWI_writeRegisters[1]; //Parameter
    		if(cmd == CMD_ZEILE_1){
    			lcd_clear();
    			set_cursor(0,1);
    			lcd_string("CMD Zeile 1");
    			Delay_ms(2500);
    			lcd_clear();
    			set_cursor(0,1);
    			itoa(param, buffer, 10);
    			lcd_string(buffer);
    		}else if(cmd == CMD_ZEILE_2){
    		        set_cursor(0,2);
    			itoa(param, buffer, 10);
    			lcd_string(buffer);	       
    		}
    	}
    	
    
        }//while(1)
        return 0;
    }
    Wie gesagt, Register werden erfolgreich ausgelesen, also ist die Verkabelung korrekt. Ich häng da jetzt seit fast zwei Tagen dran und bin kurz vorm durchdrehn, weil ichs einfach nich versteh

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Um es gleich vorweg zu sagen: Ich bin I2C-Laie.

    Zum TWI-Master: Muss nicht die Schreib- und Leseadresse unterschiedlich sein? LesenAdr ist SchreibenAdr+1?

    So war das zumindest beim Nunchuck.
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    16.11.2008
    Ort
    Frankfurt
    Alter
    40
    Beiträge
    21
    ich glaube nicht...also jedenfalls steht dazu in den beispielen und der anleitung nichts, dort wird immer die gleiche adresse für den slave verwendet, egal ob geschrieben oder gelesen wird..
    Beim Lesen soll man erstmal ein Byte mit dem gewünschten Register schicken, dann auslesen.
    Und fürs Schreiben (wenn ich das richtig verstanden habe) an die gleiche Adresse, und zwar 3 Byte (für das slave-example), nämlich Registernummer und zwei Werte für zwei Register..
    was sein könnte, wäre, dass der I2C-Code ohne die RP6Lib nicht funktioniert, aber dann müsste es ja fehler beim compile geben..?
    Wie gesagt hab ich beim Atmega8 die RP6I2Cslave.h eingebunden und im Makefile die RP6I2Cslave.c..

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Mit den I2C-Adresse hat man das Problem, das die einen von 7 Bit, die anderen von 8Bit Adresse ausgehen.
    Je nach Lib wird das RW-Bit intern gesetzt, je nach Modus. Wenn man die Bytes selber auf den Bus schiebt, muss man das RW auch selber behandeln, dann kommt die +1 ins Spiel.

    Offiziell ist die Adresse nur, die oberen, 7 Bit.

  5. #5
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Da beide Kontroller die RP6-TWILib vervenden sollten die Adressen ja passen. Noch ein weiterer Versuch ohne mich in die Untiefen der TWI-Lib des RP6 zu stürtzen:

    In den TWIMaster-Beispielen vom RB6 findet man in der Hauptschleife noch diesen Aufruf:

    task_I2CTWI(); // Call I2C Management routine

    Sind die TWI-Routinen als Task organisiert? Zumindest wenn man die Handler verwendet könnte das so sein.
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    16.11.2008
    Ort
    Frankfurt
    Alter
    40
    Beiträge
    21
    ich hatte das task_I2CTWI() schon im programm stehen, aber laut Anleitung wird das nur gebraucht, wenn man Register "im Hintergrund" auslesen will, also nicht-blockierendes Lesen, und nur Lesen..
    Ja, die Libs sind beide die vom RP6, also sollte es nicht an den Adressen liegen...

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    16.11.2008
    Ort
    Frankfurt
    Alter
    40
    Beiträge
    21
    Hat noch keiner wirklich was damit gemacht, oder nur nicht mit dem Atmega8? Also, die readRegisters kann ich auslesen, auch auf einen general Call reagiert der Atmega.
    Wie funktioniert das eigentlich mit dem general Call? Das ist eine Nachricht, die an Adresse 0 adressiert wird, das ist mir schon klar, aber wie wurde das implementiert? Die Anleitung is hier mehr als schwammig...
    "die Variable I2C_genCALL enthält das zuletzt gesendete Commando.." Hä?! Was für einen Datentyp hat diese Variable? Wenn ich nen General Call mit transmit2Bytes(0, 0, 'x') absetze, kann ich auf dem Atmega das x auslesen. Aber das ist doch kein commando?! Kann man da nicht mehr Zeichen rausschicken, und die dann auch entsprechend vom Slave auswerten lassen?
    Beim Versuch von buffer[i] = I2C_genCall[i] kam nur der Fehler, dass es sich bei I2C_genCall wohl nicht um ein array handelt...

    Und das Problem mit der "richtigen" schreibe, also direkt in die writeRegisters vom Slave zu schreiben ist auch noch nicht gelöst, nichtmal annähernd, da geht nämlich gaaar nix (Code aus dem Beispiel genommen!!!)

    Ich hab mal versucht, den TWI-Code von Mikrocontroller.net zu benutzen, was auch super funktioniert hat, nur blöderweise hats jedesmal mein Programm blockiert Kurz: I2C funktioniert also, nur der Beispielcode nicht...

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Hallo,

    Ich hab Dir gerade auch im AREXX Forum geantwortet.

    Probiers mal mit ner geraden Adresse (z.B. 14)


    Bei den RP6Libs wird immer das gesamte 8Bit Adressbyte übergeben. Das unterste Bit muss frei bleiben - nur die oberen 7 sind die eigentliche Adresse.

    MfG,
    SlyD

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    16.11.2008
    Ort
    Frankfurt
    Alter
    40
    Beiträge
    21
    arrrrrrrgh... DANKE SLYD !!!
    hehe, des könnt ruhig irgendwo stehen, ich hab mir richtig gut den Kopf zerbrochen danke, jetzt gehts!

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Naja in den Beispielprogrammen wird überall ne gerade Adresse verwendet

    Aber Du hast natürlich recht, das wird noch in die nächste Version der Doku mit aufgenommen.

    MfG,
    SlyD

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad