Está en la página 1de 6

UNIVERSIDAD DEL VALLE

PRE-INFORME

Estudiante: Soto Torrico Henry Daniel Fecha: 16/05/22


Carrera: IMT Grupo: A
Docente: Perez Villaroel Gerson Laboratorio: Microprocesadores I
Practica N: 7 Título de laboratorio: Comunicación SPI
Firma del estudiante: Firma docente:

1. Enunciado:
7.1 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 analógico
(en un potenciómetro) y envía este valor por el puerto SPI. El esclavo recibe el valor
enviado desde el maestro SPI y muestra el valor en un LCD y también lo envía por
el puerto serial para que se visualice en un terminal serial.
2. Código:
* Lab_7_Master.c
*
* Created: 15/05/2022 23:28:16
* Author : Soto
*/
#define F_CPU 16000000UL // 16MHz
#include <avr/io.h>
#include <util/delay.h>
#define DD_SS DDB1
#define SPI_SS PB1 // PINB1 SS
#define DD_MOSI DDB3 //MOSI PINB3
#define DD_MISO DDB4 //MISO PINB4
#define DD_SCK DDB5 // SCK EN PINB5
#define DDR_SPI DDRB // CONFIGURACION PUERTO B
void SPI_MasterInit(void)
{
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK); //MOSI y SCK SALIDA
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); //SPI ENEABLE,MASTER, F_CPU/16,
}
uint8_t SPI_Transfer(uint8_t cData)
{
SPDR = cData; // CUANDO SE LEE EL DATO COMIENZA LA TRANSMISIÓN
while(!(SPSR & (1<<SPIF))); // ESPERAMOS A QUE TERMINE
return(SPDR);
}
int main(void)
{
uint8_t spi_rx, spi_tx;
uint16_t valor_adc1;
uint8_t unidad, decena, centena, u_mil;

DDR_SPI |= (1 << DD_SS); //SPI_SS SALIDA


PORTB |= (1 << SPI_SS); //SS_SPI PULL UP
// CONFIGURACION ADC
ADMUX= 0B01000001; // VREF=VCC, ADC1.
ADCSRA= 0B10000111 ; //ADC ENEABLE, PRESCALER 128
DIDR0 |= (1 << ADC1D);//ADC1 ANALÓGICO
SPI_MasterInit();
_delay_ms(500);
while (1)
{
ADCSRA |= (1 << ADSC); //INICIO DE CONVERSIÓN
while ((ADCSRA & (1 << ADSC)) == 1);// ESPERAMOS A QUE TERMINE
valor_adc1 = ADC;//ASIGNA EL VALOR A LA VARIABLE
u_mil = valor_adc1 / 1000; //SEPARAMOS LAS UNIDADES DE MIL
valor_adc1 %= 1000;
centena = valor_adc1 / 100;//SEPARAMOS LAS CENTENAS
valor_adc1 %= 100;
decena = valor_adc1 / 10;//SEPARAMOS DECENAS
unidad = valor_adc1 % 10;//SEPARAMOS UNIDADES
//INICIO DE TRANSMISIÓN DE DATOS
PORTB &= ~(1 << SPI_SS);//SS_SPI BAJO
spi_rx = SPI_Transfer(u_mil + '0');// ENVIO DE UNIDADES DE MIL
PORTB |= (1 << SPI_SS);//SS_SPI ALTO
_delay_ms(5);
PORTB &= ~(1 << SPI_SS);//SS_SPI BAJO
spi_rx = SPI_Transfer(centena + '0');//ENVIO DE CENTENAS
PORTB |= (1 << SPI_SS);//SS_SPI ALTO
_delay_ms(5);
PORTB &= ~(1 << SPI_SS);//SS_SPI BAJO
spi_rx = SPI_Transfer(decena + '0');//ENVIAR DECENA
PORTB |= (1 << SPI_SS);//SS_SPI ALTO
_delay_ms(5);
PORTB &= ~(1 << SPI_SS);//SS_SPI BAJO
spi_rx = SPI_Transfer(unidad + '0'); //ENVIAR UNIDAD
PORTB |= (1 << SPI_SS);//SS_SPI ALTO
_delay_ms(5);
PORTB &= ~(1 << SPI_SS);//SS_SPI BAJO
spi_rx = SPI_Transfer(10);// NUEVA LÍNEA
PORTB |= (1 << SPI_SS);//SS_SPI ALTO
_delay_ms(5);
PORTB &= ~(1 << SPI_SS);//SS_SPI BAJO
spi_rx = SPI_Transfer(13);// RETORNO DE CARRO
PORTB |= (1 << SPI_SS);//SS_SPI ALTO
_delay_ms(5);
_delay_ms(300); // REFRESCA LA LECTURA CADA 0.3 SEGUNDOS
}
return (0);
}
* Lab_7_Slave.c
*
* Created: 16/05/2022 0:05:13
* Author : Soto
*/

#define F_CPU 16000000UL


#include <avr/io.h>
#include <util/delay.h>
//DEFINICION PINES LCD PORTD
#define LCD_D4 PD4
#define LCD_PORT_D4 PORTD
#define LCD_DDR_D4 DDRD
#define LCD_D5 PD5
#define LCD_PORT_D5 PORTD
#define LCD_DDR_D5 DDRD
#define LCD_D6 PD6
#define LCD_PORT_D6 PORTD
#define LCD_DDR_D6 DDRD
#define LCD_D7 PD7
#define LCD_PORT_D7 PORTD
#define LCD_DDR_D7 DDRD
#define LCD_RS PB0
#define LCD_PORT_RS PORTB
#define LCD_DDR_RS DDRB
#define LCD_EN PB1
#define LCD_PORT_EN PORTB
#define LCD_DDR_EN DDRB
//DEFINIMOS BAUDRATE
#define UsartBaudRate 9600
#define BaudUBRR (((F_CPU / (UsartBaudRate * 16UL)))-1) //103.166667
// DEFINIMOS PUERTO B CONEXIÓN SLAVE
#define DD_SS DDB2
#define SPI_SS PB2
#define DD_MOSI DDB3
#define DD_MISO DDB4
#define DD_SCK DDB5
#define DDR_SPI DDRB
//INCIAMOS CONFIGURACIÓN LCD
void lcdWrite4(uint8_t dato);
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);
//SPI SLAVE INICIO
void SPI_SlaveInit(void)
{
DDR_SPI = (1<<DD_MISO);//MISO SALIDA
SPCR |= (1<<SPE); //ENEABLE
}
uint8_t SPI_Transfer(uint8_t cData)
{
SPDR = cData; // CUANDO SE LEE EL DATO COMIENZA LA TRANSMISIÓN
while(!(SPSR & (1<<SPIF))); // ESPERAMOS A QUE TERMINE
return(SPDR);
}
void tx_uart(uint8_t data)
{
while((UCSR0A & (1<<UDRE0)) == 0); // ESPERAMOS QUE TERMINE
UDR0 = data; // ESCRIBIMOS EL DATO EN UDR0
}

int main(void)
{
uint8_t spi_rx;

UBRR0H = (BaudUBRR>>8); //BAUDRATE NIBBLE ALTO


UBRR0L = BaudUBRR; //BAUDRATE NIBBLE BAJO
UCSR0B |= (1<<TXEN0); //HABILITACIÓN TX
UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00); //CONFIGURACIÓN 8 BITS

SPI_SlaveInit();
lcdInit();
lcdGotoxy(0,0);
lcdPrint("VALOR ADC1: ");
lcdGotoxy(0,1);
while (1)
{

spi_rx = SPI_Transfer(0x10);
if(spi_rx == 10) // SI NUEVA LÍNEA
{
lcdPrint(" ");
lcdGotoxy(0,1);
tx_uart(spi_rx);
}
else if(spi_rx == 13) // SI VUELTA DE CARRO
{
tx_uart(spi_rx);
}
else
{
lcdData(spi_rx);
tx_uart(spi_rx);
}
}
return (0);
}
// CONFIGURACIÓN LCD
void lcdWrite4(uint8_t dato) //Enviar nibble alto a D4-D7.
{
//LCD_DPRT = (LCD_DPRT & 0x0F) | (dato & 0xF0); //Enviar el nibble alto a
D4-D7.

if ((dato & (1<<4)) != 0)


{
LCD_PORT_D4 |= (1<<LCD_D4);
}
else
{
LCD_PORT_D4 &= ~(1<<LCD_D4);
}

if ((dato & (1<<5)) != 0)


{
LCD_PORT_D5 |= (1<<LCD_D5);
}
else
{
LCD_PORT_D5 &= ~(1<<LCD_D5);
}

if ((dato & (1<<6)) != 0)


{
LCD_PORT_D6 |= (1<<LCD_D6);
}
else
{
LCD_PORT_D6 &= ~(1<<LCD_D6);
}

if ((dato & (1<<7)) != 0)


{
LCD_PORT_D7 |= (1<<LCD_D7);
}
else
{
LCD_PORT_D7 &= ~(1<<LCD_D7);
}

LCD_PORT_EN |= (1<<LCD_EN); //EN = 1, pulso de alto a bajo.


_delay_us(1); //Retardo para pulso.
LCD_PORT_EN &= ~(1<<LCD_EN); //EN = 0, pulso de alto a bajo.
}
void lcdCommand(uint8_t cmd) //OJO solo parte del puerto es del LCD.
{
LCD_PORT_RS &= ~(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_PORT_RS |= (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_DDR_D4 |= (1<<LCD_D4);
LCD_DDR_D5 |= (1<<LCD_D5);
LCD_DDR_D6 |= (1<<LCD_D6);
LCD_DDR_D7 |= (1<<LCD_D7);
LCD_DDR_RS |= (1<<LCD_RS);
LCD_DDR_EN |= (1<<LCD_EN);
_delay_ms(50); //Espera inicialización de encendido de LCD.
LCD_PORT_EN &= ~(1<<LCD_EN); //LCD_EN = 0
LCD_PORT_RS &= ~(1<<LCD_RS); //RS = 0 para comandos.
lcdWrite4(0x30);
_delay_ms(5);
lcdWrite4(0x30);
_delay_us(100);
lcdWrite4(0x30);
_delay_us(100);
lcdWrite4(0x20);
_delay_us(100);
lcdCommand(0x28); //2 lineas, caracter 5x7.
lcdCommand(0x0C); //Display ON, cursor OFF.
lcdCommand(0x01); //Limpiar LCD.
_delay_ms(2);
lcdCommand(0x06); //Desplazar cursor a la derecha.
}
3. Simulación:

También podría gustarte