Estoy tratando de transmitir datos desde un microcontrolador (frecuencia de reloj predeterminada ATMega8A) a otro microcontrolador (ATMega16 16MHz-crystal).
He configurado ATMega16 como maestro con
DDRB |= (1 << DDB7) | (1 << DDB5); //Set MOSI, SCK as Output
SPCR |= (1 << SPE) | (1 << MSTR) | (1<<SPIE) | (1 << SPR0);//Enable SPI, Set as Master
tengo una funcion de recibir
unsigned char ReceiveData(unsigned char Data)
{
SPDR = Data;
while(!(SPSR & (1<<SPIF) ));
return(SPDR);
}
El SS'
pin de ATMega8A (esclavo) está conectado PB3
y en el bucle principal que tengo
for(;;)
{
PORTB &= ~(1<<PB3); //clear SS' of slave
Data = ReceiveData(0x05); //sending dummy 0x08 to slave;
if(Data == 0x08)
//TOGGLE(SOME_PORT,SOMEPINWITHLED); toggle #defined
_delay_ms(200);
PORTB |= (1<<PB3);
}
En el dispositivo esclavo que tengo
int main() // slave main module
{
DDRB |= (1<<DDB4); //MISO as OUTPUT
SPCR |= (1<<SPE); //Enable SPI
DDRB |= (1<<DDB0);
char Data = 2, SendValue = 8;
for(;;)
{
TOGGLE(PORTB,PB0); // #define'd TOGGLE(A,B) A ^= (1<<B);
Data = SendData(SendValue); // exact same as ReceiveData() on master.
}
return 0;
}
El led no se enciende en el módulo maestro pero sí en el módulo esclavo. ¿Podría sugerirme qué he hecho mal aquí? Puede ser que el maestro y el esclavo no estén sincronizados.
PD: En el futuro planeo usar múltiples esclavos y un solo maestro.
Editar : corregí deDDRB |= (1 << DDB3) | (1 << DDB5);
El único problema que puedo encontrar es la inicialización del puerto SPI en el Maestro, más el uso de ReceiveData.
En el Maestro, configura B3 y B5 como salidas. Pero de acuerdo con este documento para ATmega16, SS = PB4, MOSI = PB5, MISO = PB6 y SCK = PB7 y su SS es PB3. Entonces deberías tener:
DDRB |= (1 << DDB3) | (1 << DDB5) | (1 << DDB7);
Y según este documento para ATmega8, SS = PB2, MOSI = PB3, MISO = PB4 y SCK = PB5. Deberías tener configurado PB4 como salida para MISO, y lo tienes.
No estoy seguro de para qué estás usando PB0, si es para sincronizar los dos procesadores, no es necesario.
Su método de envío y recepción de datos en ReceiveData es correcto y debe usarse tanto para el Maestro como para el Esclavo (de la transmisión anterior).
Recuerde que cada vez que envía un byte, obtiene un byte de vuelta del otro extremo.
DDRB
están mal, gracias por señalarlo. Lo corregí.
vicatcu
pranfia