INTRODUCCION
- El Bus SPI (del inglés Serial Peripheral Interface) es un estándar de comunicaciones, usado principalmente para la transferencia de información entre circuitos integrados en equipos electrónicos. El bus de interfaz de periféricos serie o bus SPI es un estándar para controlar casi cualquier dispositivo electrónico digital que acepte un flujo de bits serie regulado por un reloj (comunicación sincrónica).
- Incluye una línea de reloj, dato entrante, dato saliente y un pin de chip select, que conecta o desconecta la operación del dispositivo con el que uno desea comunicarse. De esta forma, este estándar permite multiplexar las líneas de reloj.
- Muchos sistemas digitales tienen periféricos que necesitan existir pero no ser rápidos. La ventajas
de un bus serie es que minimiza el número de conductores,pines y el tamaño del circuito integrado. Esto reduce el coste de fabricar montar
y probar la electrónica. Un bus de periféricos serie es la opción más flexible
cuando se tiene tipos diferentes de periféricos serie. El hardware consiste en
señales de reloj, data in,
El SPI es un protocolo síncrono. La sincronización y la
transmisión de datos se realizan por medio de 4 señales:
·
SCLK (Clock): Es el pulso que marca la sincronización. Con cada pulso
de este reloj, se lee o se envía un bit. También llamado TAKT (en Alemán).
·
MOSI (Master Output Slave Input): Salida de datos del Master y
entrada de datos al Slave. También llamada SIMO.
·
MISO (Master Input Slave Output): Salida de datos del Slave y entrada
al Master. También
conocida por SOMI.
·
SS/Select: Para seleccionar un Slave, o para que
el Master le diga al Slave que se active. También llamada SSTE.
La Cadena de bits es enviada de manera síncrona con los
pulsos del reloj, es decir con cada pulso, el Master envía un bit. Para que
empiece la transmisión el Master baja la señal SSTE ó SS/Select a cero, con esto
el Slave se activa y empieza la transmisión, con un pulso de reloj al mismo
tiempo que el primer bit es leído. Nótese que los pulsos de reloj pueden estar
programados de manera que la transmisión del bit se realice en 4 modos
diferentes, a esto se llama polaridad y fase de la transmisión:
·
1. Con el flanco de subida sin retraso.
·
2. Con el flanco de subida con retraso.
·
3. Con el flanco de bajada sin retraso.
·
4. Con el flanco de bajada con retraso.
- Ejemplo de Frame SPI;
- OBJETIVO.
Para
iniciar la comunicación SPI con la tarjeta Zedboard debemos tener previamente
un esclavo y un maestro que valide el sistema de comunicación. Para ello se
propone un esquema de microcontroladores como el de la siguiente imagen:
- El esquemático está compuesto por dos microcontroladores PIC18F2550 configurados con oscilador interno a 8 Mhz, velocidad de 2 Mhz en SPI, una terminal RS232 y un led de estatus en el PIN_B7.
- La transmisión de ambos microcontroladores está configurada en MODO_A o MODO_0 como se muestra en la siguiente figura:
- En la siguiente figura se muestran armados en un protoboard:
- La idea es transferir 64 bytes del maestro al esclavo y este a su vez los retransmite nuevamente al maestro.
- Maestro [0, 1, 2, … 63] à Esclavo [0, 1, 2, … 63] à Maestro [0, 1, 2, … 63]
- En la siguiente figura se muestra las transmisiones recibidas entre ambos:
- Los códigos hexadecimales los puedes bajar de aquí:
ESCLAVO:
MAESTRO:
- Ahora desarrollaremos la etapa del SPI Maestro con la Zedboard. Iniciando con la construcción de bloques en vivado de la siguiente manera:
- La configuración en Zynq del SPI se muestra a continuación:
- El código en SDK de eclipse es:
/*****************************
Include Files *********************************/
#include "xparameters.h" /* SDK generated
parameters */
#include "xspips.h" /* SPI device
driver */
#include "xil_printf.h"
#include "xgpio.h"
/**************************
Constant Definitions *****************************/
/*
* The following constant map to the XPAR
parameters created in the
* xparameters.h file. They are defined here
such that a user can easily
* change all the needed parameters in one
place.
*/
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
#define GPIO_EXAMPLE_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID
#define LED_CHANNEL 1
/*
* The following constant specify the max
amount of data the slave is
* expecting to receive from the master.
*/
#define TEST_BUFFER_SIZE 64
//**************************
Function Prototypes ******************************/
int SpiPsMasterPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId);
/**************************
Variable Definitions *****************************/
/*
* The instances to support the device drivers
are global such that they
* are initialized to zero each time the
program runs. They could be local
* but should at least be static so they are
zeroed.
*/
static XSpiPs
SpiInstance;
XGpio
Gpio; // The Instance of the GPIO Driver
/*
* The ReadBuffer is used to read to the data
which it received from the SPI
* Bus which master has sent.
*/
u8
SendBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Transmitting Data */
u8
RecvBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Receiving Data */
/*****************************************************************************/
/**
*
* Main
function to call the SPI Slave Example.
*
* @param None
*
* @return
* - XST_SUCCESS if
successful
* - XST_FAILURE if not
successful
*
* @note None
*
******************************************************************************/
int main(void)
{
int
Status;
// Initialize the
GPIO driver
Status = XGpio_Initialize(&Gpio,
GPIO_EXAMPLE_DEVICE_ID);
if
(Status != XST_SUCCESS) {
return XST_FAILURE;
}
// Clear the LEDs
XGpio_DiscreteWrite(&Gpio,
LED_CHANNEL, 0);
xil_printf(" Microcarsil,
2014\n");
xil_printf("Running SpiPS Master Polled Example \r\n");
/*
* Run the SpiPs Slave Polled example.
*/
Status =
SpiPsMasterPolledExample(&SpiInstance, SPI_DEVICE_ID);
if
(Status != XST_SUCCESS) {
xil_printf("SpiPs Master Polled Example Failed \r\n");
return XST_FAILURE;
}
xil_printf("Successfully ran SpiPs Master Polled Example \r\n");
return
XST_SUCCESS;
}
/*****************************************************************************
*
* The purpose
of this function is to illustrate how to use the XSpiPs
* device
driver in Slave mode. This function reads data from a SPI Master
* and will
echo it back to the Master.
*
* @param SpiDeviceId is the Instance Id of SPI in the
system.
*
* @return
* - XST_SUCCESS if
successful
* - XST_FAILURE if not
successful
*
* @note None
*
*
*****************************************************************************/
int SpiPsMasterPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId)
{
int
Status;
unsigned
char i=1;
int
Index;
XSpiPs_Config
*SpiConfig;
for
(Index = 0; Index < TEST_BUFFER_SIZE; Index++)
{
SendBuffer[Index]
= Index;
RecvBuffer[Index]
= 0;
}
/*
* Initialize the SPI driver so that it's ready
to use
*/
SpiConfig =
XSpiPs_LookupConfig(SpiDeviceId);
if
(NULL == SpiConfig) {
return XST_FAILURE;
}
Status =
XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig,
SpiConfig->BaseAddress);
if
(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to check
hardware build
*/
Status =
XSpiPs_SelfTest(SpiInstancePtr);
if
(Status != XST_SUCCESS) {
return XST_FAILURE;
}
XSpiPs_SetOptions(SpiInstancePtr,
XSPIPS_MASTER_OPTION |
XSPIPS_FORCE_SSELECT_OPTION | XSPIPS_DECODE_SSELECT_OPTION |
XSPIPS_MANUAL_START_OPTION//);// | control_val
|
XSPIPS_CLK_PHASE_1_OPTION | XSPIPS_CLK_ACTIVE_LOW_OPTION );
XSpiPs_SetDelays(SpiInstancePtr,
255,255,255,255);
XSpiPs_SetClkPrescaler(SpiInstancePtr,
XSPIPS_CLK_PRESCALE_128); // 1.25 Mhz
XSpiPs_SetSlaveSelect(SpiInstancePtr,
0x1);
while(1)
{
XGpio_DiscreteWrite(&Gpio,
LED_CHANNEL, i++);
for(Index = 0; Index < TEST_BUFFER_SIZE;
Index ++)
{
XSpiPs_PolledTransfer(SpiInstancePtr,
&SendBuffer[Index], NULL,1);
usleep(50); // 50 us
}
usleep(50000); // 50 ms
for(Index = 0; Index < TEST_BUFFER_SIZE;
Index ++)
{
XSpiPs_PolledTransfer(SpiInstancePtr,
&RecvBuffer[Index], &RecvBuffer[Index],1);
usleep(50); // 50 us
}
/*
* Verify received data
is correct.
*/
for(Index = 0; Index < TEST_BUFFER_SIZE;
Index ++)
{
xil_printf(" Master[%d] =
%d\n",Index,RecvBuffer[Index]);
}
usleep(2000000);
}
return
XST_SUCCESS;
}
No hay comentarios.:
Publicar un comentario