-         

Ergebnis 1 bis 3 von 3

Thema: TWI will nicht so wie ich wohl will

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.381

    TWI will nicht so wie ich wohl will

    Anzeige

    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
    Alter
    48
    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
    33
    Beiträge
    2.381
    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
  •