UNIVERSIDAD PRIVADA DEL VALLE
FACULTAD DE INFORMÁTICA Y
ELECTRÓNICA INGENIERÍA BIOMEDICA
Evaluación
CAMPUS TIQUIPAYA
MICROPROCESADORES I
Informe de Práctica de Laboratorio N° 9
COMUNICACIÓN SPI
GRUPO “A”
Estudiante: Chambi Ribera
Carrera: IBI
Docente: Ing. Gerson Perez Villarroel
Cochabamba 25 de noviembre del 2024
Gestión II-2024
1. Objetivos generales
Estudiar y comprender el funcionamiento de la comunicación SPI (Serial Peripheral
Interface) en un microcontrolador, abarcando su configuración tanto en modo maestro
como en modo esclavo, mediante el análisis teórico y su implementación en el laboratorio
2. Marco teórico
La SPI fue desarrollada por Motorola (ahora parte de NXP Semiconductors) aproximadamente en
1985. Se trata de una interfaz serial síncrona prevista para la comunicación entre dispositivos a
corta distancia. Desde entonces, se ha convertido en un estándar de-facto empleado por muchos
fabricantes de semiconductores, especialmente en microprocesadores y microcontroladores.
El motivo de la popularidad de SPI radica en sus muchas ventajas. La primera es que es una
interfaz direccionada de hardware simple que ofrece completa flexibilidad para la cantidad de bis
transferidos. Usa un modelo de maestro-secundario con un maestro simple y puede manejar
varios dispositivos secundarios usando comunicaciones dúplex que operan a velocidades de reloj
de hasta 50 MHz. No usa un protocolo estándar y transfiere solo paquetes de datos, lo que la hace
ideal para transferir flujos de datos largos.
SPI usa un máximo de cuatro líneas de señal (Figura 1). El dispositivo maestro, por lo general un
procesador o controlador, suministra y controla el reloj (SCK) y líneas de selección de chip (CS). La
operación multiplexor completa se maneja a través de las líneas de datos Master Out Slave In
(MOSI) y Master In Slave Out (MISO). En un maestro individual simple, con configuración del
dispositivo secundario individual, la línea de selección de chip puede eliminarse y se puede forzar
la entrada de CS al dispositivo secundario al estado lógico habilitado. Si el dispositivo secundario
solo puede enviar datos (comunicación semidúplex), luego la línea MOSI también puede
eliminarse, y así reducir el conteo de señales adicionalmente. Los datos salen a través de la señal
del reloj de tal forma que la transferencia de datos se asemeja a un registro de turnos con un bit
cambiado para cada reloj.
Figura 1: La conexión dúplex SPI básica usa dos líneas de datos (MOSI, MISO), una
línea de reloj (SCK) y una línea de selección de chip (CS). MOSI en un dispositivo
secundario es, a veces, rotulada como entrada de datos de dispositivo secundario
(SDI). MISO puede denominarse como salida de datos secundarios (SDO). (Fuente
de la imagen: DigiKey)
3. Enunciado de la Experiencia
Configurar uno de los microcontroladores como maestro y el otro como esclavo SPI
(usar el modo 3). El maestro realiza la lectura de un voltaje analo´gico (en un potencio
´metro) y enví´a e´ste valor por el puerto SPI. El esclavo recibe el valor enviado desde
el maestro SPI y muestra el valor en un LCD y tambie´n lo enví´a por el puerto serial
para que se visualice en un terminal serial.
4. Diseño
MAESTRO
#define F_CPU
16000000UL #include
<avr/io.h> #include
<util/delay.h>
#define MOSI 3
#define SCK 5
#define SS 2
int
main(void)
{
uint8_t i = 0; DDRB=(1<<MOSI)|
(1<<SS)|(1<<SCK); PORTB|=(1<<SCK);
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL)|(1<<CPHA);
_delay_ms(10);
ADCSRA =
0b10000111; DIDR0|
=(1<<0);
while (1)
{
ADMUX=0b01100000; ADCSRA|
=(1<<ADSC);
while((ADCSRA&(1<<ADIF))==0)
; i=ADCH;
SPDR=i;
while(!(SPSR & (1<<SPIF)));
_delay_ms(10);
}
}
ESCLAVO
#define F_CPU
16000000UL #include
<avr/io.h> #include
<stdio.h> #include
<string.h> #include
<util/delay.h>
#include <math.h>
#define LCD_DPRT
PORTD #define
LCD_DDDR DDRD #define
LCD_DPIN PIND #define
LCD_D4 PD4 #define
LCD_D5 PD5
#define LCD_D6 PD6
#define LCD_D7 PD7
#define LCD_CPRT
PORTD #define
LCD_CDDR DDRD
#define LCD_CPIN
PIND
#define LCD_RS PD2 //LCD
RS #define LCD_EN PD3
//LCD EN
//Prototipos DEL LCD Y
UART void
lcdWrite4(uint8_t); void
lcdCommand(uint8_t cmd);
void lcdData(uint8_t
data); void lcdInit(void);
void lcdGotoxy(uint8_t x, uint8_t
y); void lcdPrint(char * str);
void envia_caracter_uart(unsigned
char); void
enviar_cadena_uart(char*);
float dig;
float j=0;
int
main(void)
{
char variable[8];
UCSR0A =
0b00000000;
UCSR0B =
0b00011000;
UCSR0C =
0b00000110; UBRR0
= 103;
DDRB |= (1<<4);
SPCR |=
(1<<SPE);
_delay_ms(100);
lcdInit();
lcdPrint("LABORATORIO 9");
lcdCommand(0xC0);
enviar_cadena_uart("LABORATORIO
9"); envia_caracter_uart(13);
while (1)
{
SPDR = 0x00;
while(!(SPSR &
(1<<SPIF)));
dig=SPDR*0.019608;
float dig1 = roundf(dig*100)/100;
_delay_ms(10);
lcdCommand
(0xCA);
lcdGotoxy(0,1);
lcdPrint("V=");
dtostrf(dig,4,2,variable);
lcdGotoxy(2,1);
lcdPrint(variable);
lcdGotoxy(6,1);
lcdPrint("[V]");
if (dig1!=j)
{
j=dig1;
enviar_cadena_uart("V=");
enviar_cadena_uart(variable
);
enviar_cadena_uart("[V]");
envia_caracter_uart(13);
_delay_ms(10);
}
}
}
void envia_caracter_uart(unsigned char caracter)
{
while(!(UCSR0A&(1<<5)));//UDRO0 este
lleno; UDR0=caracter;
}
void enviar_cadena_uart(char* cadena)//cadena de caractere de tipo char;
{
while(*cadena != 0x00)
//a el caracter nulo;
{
envia_caracter_uart(*cadena);//transmite los caracteres de cadena;
cadena++;//incrementa la ubicacion de los caracteres en cadena;
//para enviar el siguiente caracter de cadena;
}
}
/* <<--FUNCIONES DEL LCD-->>*/
void lcdWrite4(uint8_t dato) //Enviar nibble alto a D4-D7.;
{
LCD_DPRT = (LCD_DPRT & 0x0F) | (dato & 0xF0);
LCD_CPRT |= (1<<LCD_EN); //EN = 1, pulso de alto a bajo.;
_delay_ms(2); //Retardo para pulso.;
LCD_CPRT &= ~(1<<LCD_EN); //EN = 0, pulso de alto a bajo.;
}
void lcdCommand(uint8_t cmd) //OJO solo parte del puerto es del LCD. |=.;
{
LCD_CPRT &= ~(1<<LCD_RS); //RS = 0 para comandos.;
lcdWrite4(cmd); //Enviar nibble alto a D4 – D7.;
_delay_us(100);
lcdWrite4(cmd << 4); //Enviar el nibble bajo a D4-D7.;
_delay_us(100);
}
void lcdData(uint8_t data) //OJO solo parte del puerto es del LCD. |=.;
{
LCD_CPRT |= (1<<LCD_RS); //RS = 1 para datos.;
lcdWrite4(data); //Nibble alto.;
_delay_us(100);
lcdWrite4(data << 4); //Nibble bajo.;
_delay_us(100);
}
void lcdGotoxy(uint8_t x, uint8_t y)
{
uint8_t firstCharAdr[] = {0x80, 0xC0, 0x94, 0xD4};
lcdCommand(firstCharAdr[y] + x);
_delay_us(100);
}
void lcdPrint(char * str)
{
uint8_t i = 0;
while(str[i] != 0)
{
lcdData(str[i]);
i++;
}
}
void lcdInit(void)
{
LCD_DDDR |= (1<<LCD_D4) | (1<<LCD_D5) | (1<<LCD_D6) | (1<<LCD_D7);
LCD_CDDR |= (1<<LCD_RS) | (1<<LCD_EN);
_delay_ms(50); //Espera inicialización de encendido de
LCD.; LCD_CPRT &= ~(1<<LCD_EN);//LCD_EN = 0;
LCD_CPRT &= ~(1<<LCD_RS); //RS = 0 para comandos.;
lcdWrite4(0x30);
_delay_ms(5);
lcdWrite4(0x30)
;
_delay_us(100);
lcdWrite4(0x30)
;
lcdWrite4(0x20)
;
lcdCommand(0x28); //2 lineas, caracter5x7.;
lcdCommand(0x0C); //Display ON, cursor OFF.;
lcdCommand(0x01); //Limpiar LCD.;
_delay_ms(2);
lcdCommand(0x06); //Desplazar cursor a la derecha.;
}
5. Simulación
Figura 2 simulacio´n de circuito en proteus
Figura 3 Implementacio´n del circuito del laboratorio
6. Cuestionario
Explicación del funcionamiento de la comunicación SPI:
La comunicación SPI opera bajo una arquitectura maestro/esclavo, en la cual un dispositivo
maestro coordina uno o varios dispositivos esclavos. Este intercambio de datos se realiza a través
de una línea de reloj (SCK) y dos líneas de datos: MOSI (Master Out, Slave In) y MISO (Master In,
Slave Out).
El maestro genera la señal de reloj y dirige la transferencia de información. Para enviar datos, el
maestro coloca la información en la línea MOSI, que es recibida por el esclavo en su línea
correspondiente. De manera inversa, para recibir datos, el maestro emite pulsos de reloj mientras
el esclavo envía la información a través de MISO para que el maestro la lea por MOSI.
SPI emplea un esquema de transmisión en serie, donde los bits se envían de forma secuencial. La
velocidad de esta transmisión depende de la frecuencia del reloj, y es posible ajustar la
sincronización mediante configuraciones específicas de polaridad y fase.
Explicación de la configuración del puerto SPI en el microcontrolador, como maestro y
como esclavo:
Configuración como maestro: En el modo maestro, el microcontrolador controla la comunicación y
envía los datos a uno o varios dispositivos esclavos. Se debe configurar el microcontrolador para
establecerlo como maestro y se deben asignar los pines correspondientes para la línea de reloj
(SCK), datos de salida (MOSI) y datos de entrada (MISO). Además, se pueden establecer
parámetros como la velocidad de transmisión y los modos de polaridad y fase.
Configuración como esclavo: En el modo esclavo, el microcontrolador recibe comandos y datos del
dispositivo maestro. Se debe configurar el microcontrolador para establecerlo como esclavo y
asignar los pines correspondientes para la línea de reloj (SCK), datos de salida (MISO) y datos de
entrada (MOSI). También se pueden configurar parámetros como la velocidad de transmisión y los
modos de polaridad y fase.
7. Conclusiones
La comunicación SPI es un protocolo síncrono eficiente y ampliamente utilizado para el
intercambio de datos entre dispositivos electrónicos, basado en una arquitectura maestro/esclavo
que emplea una línea de reloj y dos líneas de datos. La capacidad de configurar un
microcontrolador como maestro o esclavo, junto con la correcta asignación de pines, es esencial
para garantizar una transferencia de datos efectiva. Asimismo, comprender tanto los fundamentos
teóricos como los aspectos prácticos de la configuración del puerto SPI resulta crucial para
implementar con éxito esta interfaz en proyectos electrónicos.
8. Bibliografía
Smith, J. (2018). Understanding Serial Peripheral Interface (SPI) in Embedded
Atmel Corporation. (2016). Atmel AVR1281: 8-bit AVR Microcontroller with 128K Bytes In-System
Programmable Flash.
Texas Instruments. (2014). Serial Peripheral Interface (SPI).
https://www.digikey.es/es/articles/why-how-to-use-serial-peripheral-interface-simplify-
connections-between-multiple-
Pini, A. (2019, 14 de febrero). Por qué y cómo usar la interfaz periférica serial para simplificar las
conexiones entre distintos dispositivos. DigiKey Electronics. Recuperado de
https://www.digikey.com