• Pensado para comunicación con otros Microcontroladores o Periféricos: EEPROM serie (almacenamiento de datos no volátiles) Registros de Desplazamiento (expansión de entradas y/o salidas) Drivers de Displays (reducción de conexiones) Conversores A/D (digitalización externa de señales) • Modos de Operación posibles del módulo SPI:
• Permite la transmisión y recepción síncrona simultánea de datos de 8 bits. • Para la comunicación debe existir un dispositivo Maestro (genera la señal de reloj)y uno ó varios esclavos (reciben la señal de reloj).
ENVÍO/RECEPCIÓN SIMULTÁNEA Situación Inicial
Situación Inicial
Situación Final Intercambiados los 8 bits de datos
• SSPSR (registro de desplazamiento) envía y recoge los bits simultáneamente • SSPBUF tiene doble función: para “cargar” el registro SSPSR para envío de datos y para “recoger” los datos recibidos en SSPSR
Si antes de leer el dato anterior se completa la recepción de un nuevo dato, se perdería el dato previamente recibido, se da error de “OVERFLOW” (SSPOV=1). Este error sólo es posible si el dispositivo es ESCLAVO Un microcontrolador MAESTRO inicia una nueva transferencia cargando el dato en SSPBUF
ESPECIFICACIÓN DEL MODO SPI EN LA INICIALIZACIÓN •Modo de funcionamiento: Maestro (SCK salida) o Esclavo (SCK entrada) •Polaridad del Reloj: Estado Inactivo del Reloj (SCK) a “1” ó a “0” •Flancos activos del Reloj: Salida de bits en flancos de subida o bajada en SCK •Muestreo bits de datos: Muestreo de entrada en el “centro” o al “final” del bit •Frecuencia de Reloj: SÓLO SI ES MAESTRO, frecuencia en salida SCK •Modo de Selección: SÓLO SI ES ESCLAVO - Control externo de SDI y SDO con entrada SS - Sin control externo con pin SS
HABILITACIÓN DE LOS PINES DE ENTRADA/SALIDA de SSP • Para habilitar el módulo SSP, es necesario que el bit SSPEN se encuentre a 1. Si se desea “resetear” el módulo SSP, se debe poner a 0 este bit y luego volverlo a 1
• Para que la funcionalidad de los pines SDI, SDO, SCK y /SS sea la determinada por los bits de configuración, es necesario además que los bits de dirección de datos (en TRISA y en TRISC) tengan la dirección adecuada: SDI (RC4) debe tener TRISC<4> = 1 para ser entrada de datos SDO (RC5) debe tener TRISC<5> = 0 para que sea salida de datos SCK (RC3) debe tener TRISC<3> = 0 si el microcontrolador es MAESTRO y TRSC<3> = 1 si se define como ESCLAVO /SS (RA5) debe ser TRISA<5> = 1 si es ESCLAVO y tiene control externo
Cualquier función no deseada en el puerto serie puede ser omitida si en el registro de dirección de datos (TRIS) se configura el valor opuesto P.ej.: Si en modo Maestro sólo se van a enviar datos, SDI puede usarse como una salida de propósito general del microcontrolador cargando TRISC<4>=0
Interface SPI en el módulo SSP
La estructura principal de configuración del periférico spi es: Especifica modo maestro o esclavo: SPI_MODE_MASTER SPI_MODE_SLAVE Typedef struct { uint32_t Mode uint32_t Direction uint32_t DataSize uint32_t CLKPolarity uint32_t CLKPhase uint32_t NSS uint32_t BaudRatePrescaler uint32_t FirstBit uint32_t TIMode }SPI_InitTypeDef;
Especifica el tipo de configuración que tendrá el esclavo con el maestro: SPI_DIRECTION_2LINES SPI_DIRECTION_2LINES_RXONLY SPI_DIRECTION_1LINE Especifica el tamaño de los bit a transmitir: SPI_DATASIZE_8BIT SPI_DATASIZE_16BIT Especifica la polaridad de SDK: SPI_POLARITY_LOW (OL=0) SPI_POLARITY_HIGH (OL= 1) Especifica la fase de SDK: SPI_PHASE_1EDGE (HA=0 ) SPI_PHASE_2EDGE (HA=1 ) Especifica la fase de SDK: SPI_PHASE_1EDGE (HA=0 ) SPI_PHASE_2EDGE (HA=1 )
La estructura principal de configuración del periférico spi es:
Typedef struct { uint32_t Mode uint32_t Direction uint32_t DataSize uint32_t CLKPolarity uint32_t CLKPhase uint32_t NSS uint32_t BaudRatePrescaler uint32_t FirstBit uint32_t TIMode }SPI_InitTypeDef;
Especifica el comportamiento del pin NSS: SPI_NSS_SOFT SPI_NSS_HARD_INPUT SPI_NSS_HARD_OUTPUT Especifica el valor del preescalador de velocidad en baudios que se utilizará para configurar el reloj SCK de transmisión y recepción. Nota: El reloj de comunicación se deriva del reloj maestro. El reloj esclavo no necesita ser configurado. SPI_BAUDRATEPRESCALER_2 SPI_BAUDRATEPRESCALER_4 SPI_BAUDRATEPRESCALER_8 SPI_BAUDRATEPRESCALER_16 SPI_BAUDRATEPRESCALER_32 SPI_BAUDRATEPRESCALER_64 SPI_BAUDRATEPRESCALER_128 SPI_BAUDRATEPRESCALER_256
La estructura principal de configuración del periférico spi es:
Typedef struct { uint32_t Mode uint32_t Direction uint32_t DataSize uint32_t CLKPolarity uint32_t CLKPhase uint32_t NSS uint32_t BaudRatePrescaler uint32_t FirstBit uint32_t TIMode }SPI_InitTypeDef;
Especifica si las transferencias de datos comienzan desde MSB o un bit LSB. Este parámetro puede ser: SPI_FIRSTBIT_MSB SPI_FIRSTBIT_LSB
Especifica si el modo TI está habilitado o no. Este parámetro puede ser: SPI_TIMODE_DISABLE SPI_TIMODE_ENABLE
Para inicializar la configuración del periférico se ejecuta la función: HAL_SPI_Init (SPI_HandleTypeDef * hspi); Para el Envío y Recepción de bytes de datos se usan la funciones provistas dentro de la librería HAL. FUNCIONES POR SONDEO PARA LA CONFIGURACION MAESTRO Y ESCLAVO • HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); • HAL_SPI_ Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); Si el dispositivo esclavo tiene la capacidad de entablar la comunicacion Full-Duplex se puede usar la siguiente funcion para realizar la transmission y recepcion de manera simultaneal. • HAL_SPI_ TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); FUNCIONES POR INTERRUPCION PARA LA CONFIGURACION MAESTRO Y ESCLAVO • HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); • HAL_SPI_ Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
Parámetros de las funciones • hspi: Puntero a la estructura SPI_HandleTypeDef que contiene la información de la configuración spi específica. • pData: Puntero al buffer de datos. Especifica los bytes a enviar si es transmisor o los bytes a recibir si es receptor. • Size: Cantidad de datos a enviar PARA HABILITAR LA INTERRUPCION SE DEBE USAR LA FUNCION • SPIX_IRQHandler( ); Las funciones de interrupcion llama a la function SPIX_IRQHandler( ); que a su vez llamara a una de las siguientes subrutinas predefinidas: • HAL_SPI_TxltCallback(SPI_HandleTypeDef *hspi); • HAL_SPI_RxltCallback(SPI_HandleTypeDef *hspi);