- 12V Akku mit 280 Ah bauen         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 14 von 14

Thema: TWI kommunikation, Slave läuft nicht

  1. #11
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    38
    Beiträge
    388
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Jetzt geht mir langsam ein Licht auf.

    Das heisst ich muss meine Twi funktion aufteilen.
    Ich habe ja jetzt nur twi_init und twi_senden(diese beinhaltet start, adresse, senden und stop)

    Dann werde ich diese aufteilen und wie folgt vorgehen.

    erstens initialisieren
    starten
    bufferplatz senden
    senden 1
    senden 2
    senden 3
    und anschliessend stop.

    Bei neuen werten einfach bei starten wieder vorfahren, aussert die slave adresse ändert; dann neu initialisieren

    Ist das so richtig wen ich 3 Werte in den buffer schreiben möchte?

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    38
    Beiträge
    4.255
    Ja das ist die richtige Reihenfolge (wenn du die Adressierung zum Start dazurechnest).

    Wenn du von Slave lesen willst, geht das so:
    initialisieren
    starten
    Adresse+Write
    bufferplatz senden
    repeated start
    Adresse+Read
    lesen 1
    lesen 2
    lesen 3
    und anschliessend stop.

  3. #13
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    38
    Beiträge
    388
    Ich habe versucht die Sache umzuschreiben. Aber leider läuft jetzt garnix mehr. Und ich weis einfach nicht warum.
    MASTER:
    Code:
    #include <avr/io.h>         // I/O Port definitions 
    #include <avr/interrupt.h>   // Interrupt macros 
    #include <util/twi.h>
    #include <util/delay.h>
    
    #define F_CPU 16000000UL	//CPU Tackt
    
    unsigned volatile char adresse;
    unsigned volatile char daten;
    
    void twi_init(void);
    void twi_start(char adresse);
    int twi_senden( char daten);
    void twi_stop(void);
    
    int main(void) 
    {
    
    	twi_init();
    	adresse = 0x40;
    
    	while(1)
    	{
    		twi_start(adresse);
    		daten = 1;
    		twi_senden( daten);
    		_delay_ms(100);
    		daten = 100;
    		twi_senden(daten);
    		_delay_ms(100);
    		daten = 200;
    		twi_senden( daten);
    		_delay_ms(250);
    		twi_stop();
    
    	};
    
    }
    
    void twi_init(void)
    {
    	DDRC &= !((1<<DD0) | (DD1));
    	PORTC = (1<<DD0) | (1<<DD1);
    	TWSR = 0x00;		//Prescaler 
    	TWBR = 12;		//TWI 400khz
    };
    void twi_start(char adresse)
    {
    	uint8_t twst;
    	while(1)
    	{
    		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);		//TWI aktivieren und Start condition auslösen
    		while(!(TWCR & (1<<TWINT))); 	//Warten auf Start condition
    		twst = TW_STATUS & 0xF8;
    		//if((TWSR & 0xF8) != 0x08);
    		if ((twst != TW_START) && (twst != TW_REP_START))continue;
    
    		TWDR = adresse /*& (0xFE)*/;		//Adresse mit Schreibbit(xxxxxxx0) in Register
    		TWCR = (1<<TWINT) | (1<<TWEN);	//senden
    		//if((TWSR & 0xF8) != 0x18);
    		while(!(TWCR & (1<<TWINT)));	//warten auf ACK oder NACK
    		twst = TW_STATUS & 0xF8;
    		if ((twst == TW_MT_SLA_NACK) || (twst == TW_MR_DATA_NACK))
    		{
    			TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
    			while(TWCR & (1<<TWSTO));
    			continue;
    		}
    		break;
    	}
    }
    
    int twi_senden(char daten)
    {
    
    	
    	TWDR = daten;					//Byte in Datenregister laden
    	TWCR = (1<<TWINT) | (1<<TWEN);	//senden
    	while (!(TWCR & (1<<TWINT)));	//warten auf ACK oder NACK
    	//if ((TWSR & 0xF8) != 0x28);
    
    	//TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);	//STOP Conditions auslösen
    	return 0;	
    	
    };
    
    void twi_stop(void)
    {
    	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
    	while(TWCR & (1<<TWSTO));
    }
    SLAVE:
    Code:
    #include <avr/io.h>       		  //I/O Port definitions 
    #include <avr/interrupt.h>  	 //Interrupt macros 
    #include <util/twi.h>			//TWI STATUS
    
    #define F_CPU 16000000UL		//CPU Tackt
    #define buffer_size 3
    
    unsigned volatile char adresse, daten; //Slaveadresse, Daten
    volatile uint8_t buffer_adr;
    volatile uint8_t rxbuffer[buffer_size];						
    
    //1000 = 1ms(links), 1500 = 1,5ms(mitte), 2000 = 2ms(rechts)
    volatile int schulter= 0;		
    volatile int huefte = 0;			
    volatile int knie = 0;			
    
    void twi_slave(char adresse)		//TWI initialisieren
    {
    	TWAR = adresse;					//Slaveadresse
    	TWCR &= ~(1<<TWSTA) | (1<<TWSTO);
    	TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE); 	//ack, TWI enable, Interupt
    	TWSR = 0;
    	buffer_adr=0xFF;
    };
    
    //ACK nach empfangenen Daten senden/erwarten
    #define TWCR_ACK TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWWC)
    //NACK nach empfangenen Daten senden/erwarten
    #define TWCR_NACK TWCR =(1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWWC) 
    
    ISR(TWI_vect)						//TWI Interupt (Ausgelöst bei Bus Ereignis)
    {
    
    	switch(TW_STATUS)					//TWI-Statusregister prüfen und agieren
    	{
    		case TW_SR_SLA_ACK:					//0x60, Slave Receiver wurde adressiert
    		TWCR_ACK;
    		buffer_adr = 0xFF;							//ACK
    		break;
    
    		case TW_SR_DATA_ACK:				//0x80, Slave Receiver Daten empfangen
    		daten = TWDR;						//Daten auslesen
    		TWCR_ACK;
    		if (buffer_adr == 0xFF)
    		{
    			if(daten<=buffer_size)
    			{
    			buffer_adr = daten;
    			}
    			else
    			{
    			buffer_adr=0;
    			}
    			TWCR_ACK;
    		}
    		else
    		{
    			rxbuffer[buffer_adr] = daten;
    			buffer_adr++;
    			if (buffer_adr<(buffer_size-1))
    			{
    			TWCR_ACK;
    			}
    			else
    			{
    			TWCR_NACK;
    			}
    		}
    
    	break;
    
    	TWCR_NACK;							//Ende
    	}
    
    	TWCR |= 0b10000000;
    };
    
    
    
    int main(void) 
    {
    
    	sei(); 										//Globale Interupts zulassen
    		adresse = 0x40;								//Slave 1
    	twi_slave(adresse);							//TWI initialisieren
    
    	DDRB |= (1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3);			//B... AUSGANG
    	PORTB &= ~((1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3));		//B.. Low
    
    	while(1)
    	{
    		
    		schulter = rxbuffer[1];
    		huefte = rxbuffer[2];
    		knie = rxbuffer[3];
    		if(schulter == 100)
    		PORTB |= (1<<PORTB1);
    		if (huefte == 200)
    		PORTB |= (1<<PORTB2);
    		
    
    	}
    
    }
    Ich hoffe es hat jemand(du?) eine Idee

  4. #14
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    38
    Beiträge
    388
    Hat keiner eine Idee warum das nicht läuft?

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

Labornetzteil AliExpress