-         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 24

Thema: I2C Problem

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.07.2004
    Alter
    38
    Beiträge
    196

    I2C Problem

    Anzeige

    Kann mir mal jemand erläutern wie ich meinen µc von einem MasterTransmitter in einen MasterReceiver umschalt??
    irgendwie will der bei mir nicht...bleibt immer im Sendemode.
    Atmel schreibt da von einem write/read bit aber gefunden hab ich das auch noch nicht
    oder hat des mit der slave adresse was zu tun?? weil es ja heisst sla+w, sla+r??? blos ist die doch die selbe wenn ich einmal lesen und danach schreiben will..kein plan..
    muss ich eigentlich immer ein stop vorm wechseln von w/r machen??
    geht das nicht irgendwie in einem rutsch? also zB 1byte senden und 4 byte emfangen ohne den bus runterzufahren?
    da ja die code schnipsel die es überall gibt nur über das Senden viel erzählen (und das funzt gottseidank!) bin ich echt am ende...
    mfg

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Das Write/Read Bit wird in der Slave-Adresse übertragen. Die ersten 7 Bits selektieren den Slave bzw 0000000 für Global Call, danach kommt das ersehnte Bit. 1 für Read und 0 für Write.

    Nach dem Schreiben von Daten musst du die Richtung umschalten auf Lesen. Allerdings kein STOP, sindern mit REPEATED_START, damit dir kein anderer Master dazwischen funkt. Teilweise muss ein 'Dummy Write' gemacht werden, wo nur die Adresse übertragen wird aber keine Nutzdaten. Danach wird dann gelesen.
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.07.2004
    Alter
    38
    Beiträge
    196
    so?:
    TWDR = (adresse<<1) + 1;
    ??? //zum emfangen
    wer hat n sich das ausgedacht???
    ich dacht das general call bit ist dazu da alle geräte anzusprechen??
    na werd mich morgen mal ransetzen..
    danke schon mal wenns so gehen sollte!
    mfg

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Zitat Zitat von tristate
    so?:
    TWDR = (adresse<<1) + 1;
    Yepp. Oder

    TWDR = (adresse<<1) | 1;

    Ist nun mal so in der IIC-Spez. General Call wird AFAIK nicht über ein Bit geregelt, sondern über Adresse 0. Da ist übrigens nur Schreiben sinnvoll.
    Disclaimer: none. Sue me.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.07.2004
    Alter
    38
    Beiträge
    196
    ok danke
    werds mal morgen testen heut hab ich echt keine nerven mehr dafür..
    mfg
    woher weisst du das?? steht doch nirgends!

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    *kopfkratz* eigentlich steht das überall, bin immer ganz erstaunt wie beredt manche Datenblätter sind

    Bisher hab ich fast in jeden Datenblatt zu nen IIC-Teilchen auch ne Darlegung des IIC-Protokolls gesehen. Jedenfalls so weit, wie es vom Bauteil gebraucht wird. Bei den AVRs mit TWI-Hardware steht auch was im Manual: wie Master funktioniert, Arbitration, Global Call, wer wann warum die Arbitration verlieren kann, etc. Probeweise hab ich mal die i2c-Library (meint: Quellpaket) von Peter Fleury getestet. Geht ganz gut. Ist allerdings nur für single Master, hard bzw soft. Nen Multimasterfähigen Slave hab ich mal angefangen, aber ich hab noch sooo viel andere Dinge im Kopf...

    --> http://homepage.sunrise.ch/mysunrise...-software.html
    Disclaimer: none. Sue me.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.07.2004
    Alter
    38
    Beiträge
    196
    hab es doch nicht mehr ausgehalten
    ES LÄUFT!!!! GEIL! \/
    hab gleich mal noch ne "transceive" routine geschrieben..
    von den routinen ala fleury hat ich nicht wirklich viel schreib sowas lieber selber..
    bin überglücklich jetzt kanns weitergehen...
    also danke nochmal
    mfg

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Tristate,
    Glückwunsch!!! Mach weiter so!
    Kannste mal deinen Code posten(Slave und Master)?
    Darüber würde ich mich voll freuen!
    Gruß Michi

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.07.2004
    Alter
    38
    Beiträge
    196
    MASTER sendet 1byte:
    Code:
    #include <avr/io.h>
    #include <compat/twi.h>
    #include <avr/signal.h>
    #include <avr/interrupt.h>
    #include <avr/delay.h>
    
    #define master_adresse 0x01
    
    void I2C_init(void);
    
    void I2C_MASTER_TRANSCEIVE_ERROR(void);
    void I2C_ERROR(void);
    unsigned char transceive(unsigned char, unsigned char);
    void main(void);
    
    void I2C_init(void)
    {
    TWAR = (master_adresse<<1);   //TWI-Addresse des Masters festlegen
    TWSR &= 0b11111100;   //Prescaler auf 1 setzen, Bit 1 und 0 auf 0
    TWBR = 0xD;   //Bitrate auf 12 setzen
    sei();      //Interrupts global aktivieren 
    TWCR=(0<<TWINT)|(1<<TWEA)|(1<<TWEN);
    }
    
    void I2C_MASTER_TRANSCEIVE_ERROR(void)
    {
    PORTE=0x02;
    I2C_ERROR();
    }
    
    void I2C_ERROR(void)
    {
    //STOP
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
    TWCR=(0<<TWEN);
    //neu initialisieren
    I2C_init();
    }
    
    unsigned char transceive(unsigned char slave_adresse,unsigned char transmit_data)
    {	
    	unsigned char received_data=0x00;
    	
    	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);   				//START senden
    	while (!(TWCR & (1<<TWINT)));   								//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x08) {I2C_MASTER_TRANSCEIVE_ERROR();}		//warten auf start 
    																	//Addresse des Slaves angeben
    	TWDR = (slave_adresse<<1);
    	TWCR = (1<<TWINT) | (1<<TWEN);   								//Addresse senden
    	while (!(TWCR & (1<<TWINT)));   								//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x18) {I2C_MASTER_TRANSCEIVE_ERROR();}		//master transmit slave adresse ack
    	TWDR = transmit_data;
    	PORTE =transmit_data;													//DATEN senden
    	TWCR = (1<<TWINT) | (1<<TWEN);
    
    	while (!(TWCR & (1<<TWINT)));									//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x28) {I2C_MASTER_TRANSCEIVE_ERROR();}		//master transmit slave daten ack
    	
    
    	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);  					//REPEATED START senden
    	while (!(TWCR & (1<<TWINT)));   								//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x10) {I2C_MASTER_TRANSCEIVE_ERROR();}	//warten auf rep start
    	TWDR = (slave_adresse<<1) | 1;																
    																	//Addresse des Slaves angeben
    	TWCR = (1<<TWINT) | (1<<TWEN) | (0<<TWSTA) | (0<<TWSTO);   
    	while (!(TWCR & (1<<TWINT)));   								//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x40) {I2C_MASTER_TRANSCEIVE_ERROR();}
    	
    	TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
    	while (!(TWCR & (1<<TWINT)));   								//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x50) {I2C_MASTER_TRANSCEIVE_ERROR();}
    	
    	TWCR = (1<<TWINT) | (0<<TWEA) | (1<<TWEN);
    	while (!(TWCR & (1<<TWINT)));   								//warten bis TWINT gesetzt
    	if ((TWSR & 0xF8) != 0x58) {I2C_MASTER_TRANSCEIVE_ERROR();}
    	received_data = TWDR;
    	
    	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);					//STOP
    	return received_data;
    }
    
    void main(void)
    {
    unsigned char slave_adresse,daten;
    slave_adresse =0x02;
    daten=0x01;
    DDRB=0xFF;
    DDRE=0xFF;
    I2C_init();
    
    	_delay_loop_1(1);
    	
    	
    	PORTB=transceive(slave_adresse,daten);
    	_delay_loop_1(15);	
    	
    
    }
    slave emfängt byte und sendet 1byte zurück:
    Code:
    #include <avr/io.h>
    #include <compat/twi.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    #define slave_adresse 0x02
    
    void init(void)
    {
    TWAR = (slave_adresse<<1);
    TWCR = 0b11000101;
    TWBR = 0xC;
    TWSR &= 0b11111100;
    sei();
    TWCR |= 0b10000000;
    }
    SIGNAL (SIG_2WIRE_SERIAL)
    {
    
       switch(TWSR & 0b11111000)
       {
    	
    	case 0x80:	PORTB=TWDR;						//byte vom master an portb
    				
    				
    				break;
    
    	case 0xB8:									//byte zum master 
    				TWDR=0xF0;
    				
    				PORTE=TWDR;
    				break;
      // default:	//TWSR=0xFF;	
     
       TWCR |= 0b10000000;
    }
    
    void main(void)
    {
    init();
    DDRB=0xFF;
    DDRE=0xFF;
    for(;;);
    }
    bittschö nicht schön aber selten...
    und nun viel spass beim testen

    mfg

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi tristate,
    danke danke!!
    Gruß Michi

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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