Progra 2
Progra 2
#include <Wire.h>
void setup() {
// Iniciar I2C como maestro
Wire.begin();
}
void loop() {
// Enviar carácter A al esclavo 1
Wire.beginTransmission(1); //compienza la
transmisión al esclavo
Wire.write('A'); // Escribe la letra A en
espera de ser leida por esclavo 1
Wire.endTransmission(); //Finaliza la transmisión.
delay(100);
//Esclavo 1
#include <Wire.h>
void setup() {
// Pines en modo salida
pinMode(2, OUTPUT); //Declarar como salida pin 2
pinMode(4, OUTPUT); //Declarar como salida pin 4
// Iniciar monitor serial
Serial.begin(9600);
// Esclavo se une al bus I2C asignando dirección 1
Wire.begin(1);
// Evento a ejecutar al detectar recepcion
Wire.onReceive(receiveEvent);
}
void loop() {
}
void receiveEvent(int numBytes) {
// Leer el byte recibido
byte letraRecibida = Wire.read();
switch(letraRecibida) {
// Si se recibe un carácter 'A' se enciende el led rojo
case 'A':
digitalWrite(2, HIGH);
digitalWrite(4, LOW);
Serial.println("Letra A recibida y Led rojo encendido
");
break;
// Si se recibe un carácter 'B' se enciende el led verde
case 'B':
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
Serial.println ("Letra B recibida y Led verde
encendido.");
break;
}
}
//Esclavo 2
#include <Wire.h>
void setup() {
// Pines en modo salida
pinMode(13, OUTPUT);
// Iniciar monitor serial
Serial.begin(9600);
// Esclavo se une al bus I2C asignando dirección 2
Wire.begin(2);
// Evento a ejecutar al detectar recepcion
Wire.onReceive(receiveEvent);
}
void loop() {
}
void receiveEvent(int numBytes) {
// Leer el byte recibido
byte letraRecibida = Wire.read();
switch(letraRecibida) {
// Si se recibe un carácter 'C' se enciende el led rojo
case 'C':
digitalWrite(13, HIGH);
Serial.println("Letra C recibida y Led rojo encendido
");
break;
// Si se recibe un carácter 'D' se enciende el led verde
case 'D':
digitalWrite(13, LOW);
Serial.println ("Letra D recibida y Led rojo
apagado.");
break;
}
}
Inicializar SPI como Maestro
Aquí veremos la inicialización de SPI con el ATmega328P como maestro. Asumimos que
tenemos un dispositivo y estamos usando PINB2 como seleccione con chip.
void SPI_init()
{
// set CS, MOSI and SCK to output
SPI_DDR |= (1 << CS) | (1 << MOSI) | (1 << SCK);
Las líneas MOSI, MIS0, y Reloj para el ATmega328P son PINB3, PINB4 y PINB5. Aquí
usamos declaraciones definidas para referirnos a ellas por su función, en lugar de nombre
de pin. Ya que estamos operando como maestro, CS, MOSI y SCK necesitan ser
establecidos como salida. MISO es una entrada, que se establece por defecto.
A continuación, tenemos que habilitar SPI en el registro de control SPI. Hacemos esto
escribiendo un 1 a SPCR. Además, especificamos que estamos operando como maestro
escribiendo 1 a MSTR. Finalmente, tenemos que fijar la tarifa del reloj. Por defecto, se
establece en F osc /4. Sin embargo, esto puede ser demasiado rápido para ciertos
dispositivos. Si no está seguro de cuál es la velocidad máxima de reloj del dispositivo que
está transmitiendo, debe establecer el reloj a la velocidad más lenta posible. Aquí hacemos
eso escribiendo 1 a SPR1 y SPR0, que da un reloj de fosc/128
Transmitir
Transmitir un byte como maestro SPI es extremadamente simple. He aquí una función que
hará eso:
Primero cargamos los datos que necesitamos transmitir en el registro de datos SPI, SPDR
A continuación, votamos el Registro de Estado del SPI, SPSR, esperando a que la bandera
del SPIF despeje.
Recibir
Recibir datos sobre SPI es muy similar a la transmisión.
uint8_t SPI_masterReceive()
{
// transmit dummy byte
SPDR = 0xFF;
Usted notará que nuestra función es casi idéntica a la transmisión. La principal diferencia es
que siempre transmitimos 0xFF y devolvemos el registro de datos SPI cuando terminamos.
0xFF se transmite ya que necesitamos generar un reloj para que el esclavo nos transmita los
datos. Simplemente transmitimos 0xFF como un byte fieado para generar esta señal de
reloj.
Una alternativa a esto es combinar estas funciones. Usted podría, por ejemplo, escribir la
función de tal manera que siempre se necesita un byte de entrada para transmitir y siempre
devuelve el registro de datos SPI. Por ejemplo:
byte val;
void setup()
{
void loop()
{
val = SPI_transact(10); //Asignar a variable el valor de la transacción SPI
Serial.println(val);
}
void SPI_initMaster(){
DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB5); //Configurar MOSI, SCK y SS pins como salida
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Habilitar SPI como Maestro
}
//Esclavo
#include <SPI.h>
/*
* La libreria SPI pre-define las siguientes constantes
* para poder usar las lineas del bus SPI para las placas
* Arduino UNO
*
* SS - Slave Select en en pin 10
* MOSI - Master Out, Slave In en el pin 11
* MISO - Master In, Slave Out en el pin 12
* SCLK - Serial Clock en el pin 13
*
*/
byte val;
void setup()
{
SPI_initSlave(); // Habilita el bus SPI en modo esclavo
Serial.begin(9600);
Serial.println("Y empezamos");
}
void loop()
{
val = SPI_transact(20); //Asignar a variable el valor de la transacción SPI
Serial.println(val);
}
void SPI_initSlave(){
DDRB |= (1<<PB4); //Configurar MISO como salida
SPCR = (1<<SPE); //Habilitar SPI como esclavo
}