- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 3 von 3

Thema: TWI will nicht so wie ich wohl will

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416

    TWI will nicht so wie ich wohl will

    situation: 2 mega8
    10k pullup
    100kHz sollten eingestellt sein

    start condition klappt, address klappt ... nur das databyte haut einfach net hin, da bleiben se hängen, bitte um hilfe

    master
    Code:
    void TWI_Init_Master(void)
    {
    	cli();
    	TWI_RCount = 0;
    	TWI_WCount = 0;
    	TWBR = 32;
    	TWSR &= ~(BV(TWPS0)|BV(TWPS1));
    	TWSR |= BV(TWPS0);
    	TWCR = BV(TWEN);
    	sei();
    }
    
    bool TWI_SendByte(unsigned char target, unsigned char data )
    {
    	char b[3];
    	PORTB = BV(PB1);
    	TWCR |= BV(TWINT)|BV(TWSTA);
    	while(!(TWCR & BV(TWINT)));
    	if (TW_STATUS != TW_START) {
    		PORTB |= BV(PB2);
    		itoa(TW_STATUS, b, 16);
    		USART_Transmit(b[0]);
    		USART_Transmit(b[1]);
    		TWI_ERROR;
    		return false;
    	}
    	TWDR = (target | TW_WRITE);
    	TWCR |= BV(TWINT);
    	while (!(TWCR & BV(TWINT)));
    	if (TW_STATUS != TW_MT_SLA_ACK) {
    		PORTB |= BV(PB3);
    		itoa(TW_STATUS, b, 16);
    		USART_Transmit(b[0]);
    		USART_Transmit(b[1]);
    		TWI_ERROR;
    		return false;
    	}
    	TWDR = data;
    	TWCR |= BV(TWINT);
    	while (!(TWCR & BV(TWINT)));
    	if (TW_STATUS != TW_MT_DATA_ACK) {
    		PORTB |= BV(PB4);  
    		itoa(TW_STATUS, b, 16);
    		USART_Transmit(b[0]);
    		USART_Transmit(b[1]);
    		TWI_ERROR; // <------ steigt aus mit TW_STATUS 0x10
    		return false;
    	}
    	TWCR |= BV(TWINT)|BV(TWSTO);
    	PORTB = 0;
    	return true;
    }
    slave
    Code:
    void TWI_Init_Slave(unsigned char addr) //Even Addr. does not respond to general call
    {
    	cli();
    	TWAR = addr;
    	TWI_RCount = 0;
    	TWI_WCount = 0;
    	TWBR = 32;
    	TWSR &= ~(BV(TWPS0)|BV(TWPS1));
    	TWSR |= BV(TWPS0);
    	TWCR = BV(TWEN)|BV(TWIE)|BV(TWEA);
    	sei();
    }
    
    SIGNAL(SIG_2WIRE_SERIAL)
    {
    	char b[3];
    	PORTB = BV(PB0);
    	if (TW_STATUS != TW_SR_SLA_ACK) {
    		PORTB |= BV(PB1);
    		itoa(TW_STATUS, b, 16);
    		USART_Transmit(b[0]);
    		USART_Transmit(b[1]);
    		TWCR |= BV(TWEA)|BV(TWINT);
    		while(1);
    		return;
    	}
    	TWCR |= BV(TWEA)|BV(TWINT);
    	while(!(TWCR & BV(TWINT)));
    	if (TW_STATUS != TW_SR_DATA_ACK) {
    		PORTB |= BV(PB2);
    		itoa(TW_STATUS, b, 16);
    		USART_Transmit(b[0]);
    		USART_Transmit(b[1]);  <---- steigt aus mit 0xA0
    		while(1);   
      		return;
    	}
    	TWI_ringbuff[TWI_WCount] = TWDR;
    	TWI_WCount++;
    	TWCR |= BV(TWEA)|BV(TWINT);
    	while(!(TWCR & BV(TWINT)));
    	if (TW_STATUS != TW_SR_STOP) {
    		PORTB |= BV(PB3);
    		itoa(TW_STATUS, b, 16);
    		USART_Transmit(b[0]);
    		USART_Transmit(b[1]);
    		TWCR |= BV(TWEA)|BV(TWINT);
    		while(1);
    		return;
    	}
    	PORTB = 0;
    	TWCR |= BV(TWEA)|BV(TWINT);
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    was Probleme machen könnte, wäre, wie Du das TWCR setzt, ich würde das nach Möglichkeit immer komplett neu beschreiben, also mit allen Bits die man braucht, nicht mit |= ändern.
    Genauso TWSR, da spart man sich nix, eher das Gegenteil.

    Und den TWI immer in einem definierten Zustand hinterlassen, bei einem Fehler spingst Du einfach mit return aus der function raus.

    Ed:
    Und ganz übersehen, das mit der ISR für den Slave klappt so nicht, denn nach jedem löschen von TWINT muss die ISR beendet werden, damit die beim nächsten auftreten wieder aufgerufen wird. Also das was beim Master mit der while-Schleife gemacht wird, die wartet bis das TWINT gesetzt ist !
    Deswegen sollte man sich einen Status von ISR-Aufruf zu ISR-Aufruf mitgeben, um damit zu checken ob der Richtige Status zum richtigen Zeitpunkt auftritt. Deswegen hängt er sich jetzt auch. Das Beispiel im Wiki schaut ja soweit ganz gut aus, bis auf das mit TWCR

    Was macht TW_STATUS, bzw wie ist das definiert ?

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    twi.h das ist das statusregistr mit ausmaskierten prescale bits ... warum kann ich in der isr nicht mit while auf twint warten? ich werds mal umbauen .. btw. ich habe den fehlerfall nicht abgefagen sondern blockiere danach um die diioden un fehler auslesen zu können ... quasi zu verstehen wie und wo erhängt .... ausserdem bekomm ichnur für das databate kein ack sonder ein repeat start seltsamerweise...

Berechtigungen

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

Solar Speicher und Akkus Tests