Tengo el siguiente problema:
Quiero hacer dos AVR Atmega 328P-Pu comunicándose juntos con I2C
En el esclavo se habilita la respuesta a llamada general (dirección 0x00) y funciona. O, al menos, puedo ver que ingresa el ISR (TWI_vect) en el esclavo con el código más abajo.
Sin embargo, cuando intente llamar al salve con su propia dirección (0x02), no responderá. Todo lo demás permanece igual (circuito, resistencias pull-up, etc.)
Además, intentar bombardear el bus con llamadas a todas las direcciones posibles hasta 128 no produce respuesta del esclavo.
Estoy seguro de que es un error tonto en alguna parte, pero me estoy quedando sin idea de por qué es así. Cualquier ayuda es bienvenida.
en maestro
La comunicación I2C se inicia así
uint8_t i2c_start(uint8_t address)
{
// reset TWI control register
TWCR = 0;
// transmit START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// check if the start condition was successfully transmitted
if((TWSR & 0xF8) != TW_START){ return 1; }
// load slave address into data register
TWDR = address;
// start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 2;
return 0;
}
En el llamado principal del Maestro se hace así
uint8_t address=1;
addr=address<<1;
i2c_start(addr|I2C_WRITE); // I2C_WRITE =0x00
en esclavo
void I2C_init(uint8_t address){
// load address into TWI address register
TWAR = (address << 1);
TWAR = (1<<TWGCE); //respond to general call ! WARNING
// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
TWCR=0x0; //WARNING
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
}
El principal en el esclavo se ve así.
I2C_init(slaveaddress);
sei();
LED_PORT_DDR |= _BV(LED_BIT);
for(;;){
wdt_reset();
if(debug==1) //Debug is set to 1 in the ISR(TWI_vect)
{
LED_PORT_OUTPUT |= _BV(LED_BIT); //set to 1 e.g
}
}
Está configurando la dirección esclava en 0x00 (7 bits) cuando habilita la llamada general. Utilice TWAR |= (1<<TWGCE);
en su lugar.
SoreDakeNoKoto
uhoras
chris stratton
SoreDakeNoKoto
uhoras
usuario198530