- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: I²C Bus mit C Programmieren

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    26.04.2006
    Beiträge
    18

    I²C Bus mit C Programmieren

    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    kann mir irgendjemand helfen?

    Habe ein Board mit einem Atmel ATmega90CAN128 Controller und einem I²C-Bus und möchte über diesen einen Kompasssensor anschließen, der auf das Erdmagnetfeld ausgerichtet wird.

    Ich habe aber bei der Suche in diesem Forum und bei google bloß ein programmbespiel in Bascom gefunden.

    Hat vielleicht irgendwer schon mal ein Proramm in der Richtung geschrieben oder ne idee, wo ich entsprechende beispiele oder beschreibungen dazu finden kann???

    Gruß Green Hell

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    57
    Beiträge
    1.195
    Steht im Datenblatt nicht ein Beispiel für TWI (=I2C) Ansteuerung?

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Vielleicht auch bei Peter Fleury oder bei den Beispielen von WinAVR (examples/twidemo oder so).
    Disclaimer: none. Sue me.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    26.04.2006
    Beiträge
    18
    ja danke, ich glaube das könnte mir helfen. Wenn nicht werd ich mich wohl dann noch mal melden.

    Gruß Green Hell

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.05.2004
    Ort
    Bergstraße
    Beiträge
    245
    moin moin,
    ich habe ein paar Bibliotheken gesehen, aber ich habe die Links nicht hier. Wenn noch Bedarf besteht, kann ich nochmal nachsehen.
    Ausserdem habe ich mir auch was Eigenes geschrieben. _Scheint_ zu funktionieren, aber nur im single-master-modus (arbitration ist nicht implementiert). Wenn daran Interesse besteht, kann ich die Sourcen mal verbreiten.
    ciao .. bernd

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    26.04.2006
    Beiträge
    18
    Doch, klar besteht noch Interesse sowohl an den Links, als auch an dem Programmcode. Würde mir bestimmt weiterhelfen, da der bus bis jetzt noch nicht funktoniert.

    Gruß Green Hell

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.05.2004
    Ort
    Bergstraße
    Beiträge
    245
    ok, sollte ich am wochenende schaffen

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.05.2004
    Ort
    Bergstraße
    Beiträge
    245
    ich hab's nicht vergessen, ich hab nur im Moment wenig Zeit ...

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    26.04.2006
    Beiträge
    18
    ja alles klar, hab in der zwischenzeit auch ein Programm hiengekriegt, das den i²c-bus benutzt und so einigermaßen (also noch mit einigen macken, deren Ursprung ich noch nicht kenne ) funktioniert. Ich denk aber trotzdem das mir die Links und der Programmcode weiterhelfen können.

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.05.2004
    Ort
    Bergstraße
    Beiträge
    245
    So, hier erstmal meine TWILib.
    Es gibt 6 Routinen:
    2 Initialisierroutinen für Master und Slave, Mastertransmitter, Masterreceiver, Slavetransmitter und Slavetransmitter. Funktion sollte klar sein.
    Insbesondere die Slaveroutinen fehlen meist bei den Beispielen, die man im Netz findet (zB bei WinAVR), weil die Kommunkation da meist mit EEPROMs abläuft.
    Die Routinen scheinen bei mir zu funktionieren, ich habe aber nicht alle mögliche Fehlereinflüsse (Slave funkt rein, oder hört nicht zu, oder ähnliches getestet. Leider habe ich den Multimastermodus noch nicht implementiert.
    Ich bin natürlich für Kritik, Verbesserungen oder Begeisterung (vorzugsweise letzteres) offen.



    Code:
    /* ************************************* 
       TWI Lib Version 5 oder so
       bhm 2006
      ************************************** */
    
    // bislang keinmultimaster support
    // keine Garanie für irgendwas
    // Bemerkungen, Fehlerreports usw willkommen
    
    
    #ifndef _TWILIB_
    #define _TWILIB_ 1
    
    #include <avr/io.h>                                      //Zugriff auf IO's des Controllers
    #include <stdint.h>
    #include <compat/twi.h>
    
    void init_Master (void) {
    	TWSR &= ~(_BV(TWPS0) | _BV(TWPS1)); 	//0b11111100: Prescaler auf 1 setzen, Bit 1 und 0 auf 0 
    	TWBR = 0x0A;   							//Bitrate auf 10 setzen, gibt 220kHz Bustakt bei 8MHz 	
    }
    
    void init_Slave (uint8_t SlvAdd) {
    	TWAR = SlvAdd;		 						// eigene Address, hier ohne general call
    	TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);	//slave receive, TWEA > ACK,	
    }
    
    
    void waitTWINT (void) {
    	uint32_t m=0,mmax=F_CPU; //zZt einfach eine große Zahl
    	
    	while (bit_is_clear(TWCR, TWINT)) {
    		if (m++ > mmax) return;         // bricht waitTWINT ab, TW_Status enthält dann TW_NO_INFO
    	}
    }
    
    // *********** MasterTransmitter *************
    // Daten in *Data, lenmax #Daten senden, MT #gesendete Daten 
    uint8_t MT (uint8_t SlvAdd, uint8_t *Data, uint8_t lenmax) {
    	uint8_t len=1;
    	
    	TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);	//sende start
    	waitTWINT();
    	if ((TW_STATUS != TW_START) &&	(TW_STATUS != TW_REP_START)){	// chk Start | repeated start
    		goto ENDE;
    	}
    
    	TWDR = SlvAdd + TW_WRITE;					//Addresse des Slaves angeben, SLA+W 
    	TWCR = _BV(TWINT) | _BV(TWEN);					// sende sla_w
    	waitTWINT();
    	if (TW_STATUS != TW_MT_SLA_ACK) {				// chk sla_ack
    		goto STOP;
    	}
    	
    	do {
    		TWDR = *Data++; 					// Datum laden
    		TWCR = _BV(TWINT) | _BV(TWEN);				// sende Datum
    		waitTWINT();
    		if (TW_STATUS != TW_MT_DATA_ACK) {			// chk data_ack
    			goto STOP;
    		}
    	} while (len++<lenmax); 
    	
    STOP:	
    	TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);	// sende stop, kein warten auf TWINT	
    
    ENDE:
    	return len-1;
    }	
    
    // *********** MasterReceiver *************
    // empfangene Daten nach *Data, Speicher muss bereitgestellt sein, 
    // lenmax #Daten empfangen, MR #empfangene Daten 
    uint8_t MR (uint8_t SlvAdd, uint8_t *Data, uint8_t lenmax) {
    	uint8_t len=1;
    	
    	TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);	//sende start
    	waitTWINT();
    	if ((TW_STATUS != TW_START) &&	(TW_STATUS != TW_REP_START)){	// chk Start | repeated start
    		goto ENDE;
    	}
    
    	TWDR = SlvAdd + TW_READ;						//Addresse des Slaves angeben, SLA+r 
    	TWCR = _BV(TWINT) | _BV(TWEN);					// sende sla_r
    	waitTWINT();
    	if (TW_STATUS != TW_MR_SLA_ACK) {				// chk sla_ack
    		goto STOP;
    	}
    	
    	while (1) { 			// endlos, verlassen via break in if TW_Status
    		if (len<lenmax) {
    			TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);		//receive, ACK,
    		} else {
    			TWCR =             _BV(TWEN) | _BV(TWINT);		//receive, NACK,
    		}	
    		waitTWINT();
    		if (TW_STATUS != TW_MR_DATA_ACK) break;			// LOOP VERLASSEN
    		*Data++ = TWDR; len++;							// Daten verarbeitet
    	}
    
    	if (TW_STATUS == TW_MR_DATA_NACK) {
    		*Data++ = TWDR; len++;							// Daten verarbeitet	
    		goto STOP;
    	}	
    	
    STOP:	
    	TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);	// sende stop, kein warten auf TWINT	
    ENDE:
    	return len-1;
    }
    
    
    // *********** SlaveReceiver *************
    // empfangene Daten nach *Data, Speicher muss bereitgestellt sein, 
    // lenmax #Daten empfangen, SR #empfangene Daten 
    uint8_t SR (uint8_t *Data, uint8_t lenmax) {
    	uint8_t len=1;						// lenmax >= 1, min ein Byte empfangen!
    	
    // auf SLA warten 
    	while (bit_is_clear(TWCR, TWINT)); 				// beliebig lange warten oder pollen
    
    // jetzt geht's los	
    	if (TW_STATUS != TW_SR_SLA_ACK) {				// chk SLA+W
    		goto STOP;
    	}
    	
    	while (1) { 			// endlos, verlassen via break in if TW_Status
    		if (len<lenmax) {
    			TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);		//slave receive, TWEA > ACK,
    		} else {
    			TWCR =             _BV(TWEN) | _BV(TWINT);		//slave receive, TWEA > NACK,
    		}	
    		waitTWINT();
    		if (TW_STATUS != TW_SR_DATA_ACK) break;			// LOOP VERLASSEN
    		*Data++ = TWDR; len++;							// Daten verarbeitet
    	}
    	
    	if (TW_STATUS == TW_SR_DATA_NACK) {					// Datum mit NACK beantwortet
    		*Data = TWDR; len++;							// im Prinzip noch ein Datum verfügbar
    	}
    
    STOP:	// (TW_STATUS == TW_SR_STOP)  einzig anderer möglicher Status, von ARBs abgesehen
    	TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);	//slave receive, TWEA > ACK,	
    	return len-1;
    }
    
    // *********** SlaveTransmitter *************
    // Daten in *Data, lenmax #Daten senden, ST #gesendete Daten 
    uint8_t ST (uint8_t *Data, uint8_t lenmax) {
    	uint8_t len=0;						// lenmax >= 1, min ein Byte senden!
    	
    // auf SLA warten 
    	while (bit_is_clear(TWCR, TWINT)); 				// beliebig lange warten oder pollen
    
    // jetzt geht's los	
    	if (TW_STATUS != TW_ST_SLA_ACK) {				// chk SLA+R
    		goto STOP;
    	}
    	
    	do {
    		TWDR = *Data++; len++;
    		if (len<lenmax) {
    			TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);
    		} else {
    			TWCR = _BV(TWEN) | _BV(TWINT);	
    		}	
    		waitTWINT();
    	} while (TW_STATUS == TW_ST_DATA_ACK);
    
    STOP:	
    	TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);	//slave receive, TWEA > ACK,	
    	return len;
    }
    
    #endif
    Bei den versprochenen Links habe ich immernoch nicht die Zeit gefunden ...

    ciao ... bernd

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad