ATmega328P: Módulo SPI

Contenido:

Módulo SPI del ATmega328P

El módulo SPI (Interfaz Periférica en Serie) del ATmega328P es un sistema de comunicación serie síncrono utilizado para la transferencia de datos entre dispositivos digitales. El puerto SPI está formado por cuatro pines:

  • MOSI: Master Output Slave Input (Salida Maestro Entrada Esclavo)
  • MISO: Master Input Slave Output (Entrada Maestro Salida Esclavo)
  • SCK: Clock del Sistema
  • SS: Slave Select (Seleccionar Esclavo)

El ATmega328P puede funcionar como maestro o esclavo en la comunicación SPI. Como maestro, el microcontrolador inicia la comunicación y controla la transferencia de datos. Como esclavo, el microcontrolador espera la señal de selección del maestro para iniciar la transferencia de datos.

El módulo SPI se puede configurar para diferentes modos de transferencia, que determinan la fase y la polaridad de la señal de reloj. También se pueden configurar la velocidad del reloj y la orden de transmisión de bits (MSB primero o LSB primero).

En resumen, el módulo SPI del ATmega328P es una interfaz versátil para la comunicación entre dispositivos digitales y se puede configurar para adaptarse a diferentes requisitos de transferencia de datos.

✅ Si quieres conocer la descripción de cada uno de los registros, además de varios ejemplos adicionales de los que encontrarás en este post, te invito a que adquieras la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 dando clic ⭐ aquí ⭐. Adicionalmente recibirás los sketch de Arduino IDE y de Microchip Studio, incluyendo los archivos de simulación en Proteus Profesional v8.10.

Video Tutorial

Ejemplo 1: Intercambiar 4bits entre el Master y el Slave, los bits serán ingresados con un DipSwitch y serán visualizados en el otro dispositivo.

Para intercambiar 4 bits con el protocolo SPI se realiza dos programas, uno para el Master y otro para el Esclavo. El Master es el encargado de generar la señal de reloj el cual, utilizando el preescaler 16 se obtiene una frecuencia de 1MHz, de igual manera controla el ciclo de inicio de comunicación cuando el pin SS se pone en LOW, los datos se transmiten por la línea MOSI y se reciben por la línea MISO.

El esclavo recibe la señal de reloj y la señal de inicio del ciclo de comunicación para que pueda recibir datos por la línea MOSI y transmitir datos por la línea MISO.

En ambos casos se debe leer el Puerto D pero como las resistencias pull-up de las entradas están activadas van a tener un 1 lógico, al momento de activar el DipSwitch las entradas tendrían un cero lógico, estos datos se transmiten hacia el otro dispositivo, los datos que se reciben son ubicados en el bit que les corresponde y posteriormente son escritos en el Puerto C.

Arduino:

at328p spi ejm1 1
Figura 1: Circuito con Arduino para el Ejemplo 1 del Módulo SPI.

Master:

//Sketch Master

void setup() {
  // 0 Entrada, 1 Salida
  // SCK=PB5 (1), MISO=PB4 (0), MOSI=PB3 (1), SS=PB2 (1)
  DDRB = 0b00101100;
  // El esclavo no se comunica al inicio
  PORTB |= 0b00000100;
  // Puerto C
  DDRC = 0b00001111;
  PORTC = 0b00000000;
  // Puerto D
  DDRD = 0b00000000;
  PORTD = 0b11110000;
  // Sin interrupcion, Habilito SPI, Mas significativo, Modo Master, Clock en bajo, Detección en flanco de subida, Preescaler 16
  SPCR = 0b01010001;
  // Sin velocidad doble
  SPSR = 0b00000000;
  _delay_ms(10);
  // Inicia comunicacion con el esclavo
  PORTB &= 0b11111011;
}

void loop() {
  // TX
  SPDR = PIND;
  while (!(SPSR & 0b10000000)); // Comprueba que termine de transmitir
  // RX
  while (!(SPSR & 0b10000000)); // Espera que complete la recepcion
  PORTC = SPDR >> 4;
  _delay_ms(100); // Retardo 100ms
}

Slave:

//Sketch Slave

void setup() {
  // 0 Entrada, 1 Salida
  // SCK=PB5 (0), MISO=PB4 (1), MOSI=PB3 (0), SS=PB2 (0)
  DDRB = 0b00010000;
  // Puerto C
  DDRC = 0b00001111;
  PORTC = 0b00000000;
  // Puerto D
  DDRD = 0b00000000;
  PORTD = 0b11110000;
  // Sin interrupcion, Habilito SPI, Mas significativo primero, Modo Esclavo
  SPCR = 0b01000000;
  // Sin velocidad doble
  SPSR = 0b00000000;
  _delay_ms(10);
}

void loop() {
  while (PINB & 0b00000100); // Espera hasta que exista comunicacion
  // RX
  while (!(SPSR & 0b10000000)); // Espera que complete la recepcion
  PORTC = SPDR >> 4;
  // TX
  SPDR = PIND;
  while (!(SPSR & 0b10000000)); // Comprueba que termine de transmitir
}

Lenguaje C:

at328p spi ejm1 2
Figura 2: Circuito con ATmega328P para el Ejemplo 1 del Módulo SPI.

Master:

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Slave:

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Deja un comentario