You are on page 1of 5

Gestin del bus spi desde C

Enviado por Javi y clasificado en Informtica Escrito el 13 de Enero de 2010 en espaol con un tamao de 9,49 KB

INTRODUCCIN:
El Bus SPI (Serial Peripheral Interface) es un estndar de comunicaciones, usado principalmente para la transferencia de informacin entre circuitos integrados en equipos electrnicos. Es un bus serie, sncrono y trabaja en modo full dplex. Incluye una lnea de reloj, dato entrante, dato saliente y un pin de chip select, que conecta o desconecta la operacin del dispositivo con el que uno desea comunicarse.

GESTIN DEL BUS SPI DESDE C:


Existen 4 funciones en lenguaje C asociadas con el mdulo SPI, pero todas ellas son utilizables nicamente si el microcontrolador seleccionado dispone de mdulo hardware SSP. No existe implementacin software del mdulo SPI. Las funciones mencionadas son las siguientes: setup_SPI():

void setup_SPI(const modos); Esta funcin sirve para inicializar y configurar el Interfaz de Puerto Serie (SPI) ya que define el modo de trabajo de esta comunicacin. En el fichero de cabeceras del dispositivo microcontrolador (.h) estn definidas una serie de etiquetas que estn asociadas a los modos de funcionamiento y que se separan en 3 grupos: a) Modo:

SPI_MASTER: configura el dispositivo como maestro. SPI_SLAVE: configure el dispositivo como esclavo. SPI_SS_DISABLED: desactiva el pin de seleccin SS. b) Flanco: configura los modos de transmisin sobre SPI segn las siguientes combinaciones:

SPI_L_TO_H: flanco de bajo a alto (flanco de subida). SPI_H_TO_L: flanco de alto a bajo (flanco de bajada). // MOTOROLA | MICROCHIP | CCS //----------------------------------------------------------------------------------------------------// SPI Mode 0,0 | CKP = 0, CKE = 1 | SPI_L_TO_H | SPI_XMIT_L_TO_H // SPI Mode 0,1 | CKP = 0, CKE = 0 | SPI_L_TO_H // SPI Mode 1,0 | CKP = 1, CKE = 1 | SPI_H_TO_L // SPI Mode 1,1 | CKP = 1, CKE = 0 | SPI_H_TO_L | SPI_XMIT_L_TO_H CKP=Clock Polarity Select bit

CKE=Clock Edge Select bit

c) Frecuencia: define la frecuencia a la que oscilar el reloj. Solo se utiliza si el dispositivo se configura como maestro ya que es quien genera la seal de reloj. SPI_CLK_DIV_4 SPI_CLK_DIV_16 SPI_CLK_DIV_64 SPI_CLK_T2 Las etiquetas anteriores se enlazan mediante el operador OR (|). Veamos algunos ejemplos:

configurando el dispositivo como maestro, modo B (0,1) y con una velocidad de reloj: setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);

configurando el dispositivo como esclavo, modo C (1,0) y con el pin de seleccin desactivado: setup_spi(SPI_SLAVE | SPI_H_TO_L | SPI_SS_DISABLED); spi_write():

void spi_write(char c); Esta funcin selecciona el siguiente carcter a escribir en el puerto SPI. Si el dispositivo es maestro genera una seal de reloj y se enva el valor inmediatamente. Si el dispositivo es esclavo, el valor no se enva hasta que el maestro se lo indica con una seal de reloj. spi_read():

char spi_read([char c]); Esta funcin tiene distinto efecto en funcin de que el dispositivo sea Maestro o Esclavo. La funcin devuelve un dato ledo a travs del SPI y puede llevar un dato como parmetro o no. Si el dispositivo es Maestro SPI, la funcin enva el valor c cuando un nuevo valor se ha recibido (d=spi_read(c)). Si no hay datos para enviar pero hay que hacer una operacin de lectura, se le pasa cero a la funcin (d=spi_read(0)). Si se ha utilizado previamente la funcin spi_write() y queremos leer un dato durante la escritura utilizaremos esta funcin sin pasarle ningn parmetro (d=spi_read()). Si el dispositivo es Esclavo, la funcin spi_read() espera a que el dispositivo maestro enve la seal de reloj y el dato por el puerto SPI. Mientras el nuevo dato se recibe, se enva el dato c al otro dispositivo. Para saber si hemos recibido un dato por el puerto SPI utilizamos la funcin spi_data_is_in(). spi_data_is_in():

char spi_data_is_in();

Esta funcin devuelve TRUE si se ha recibido un dato a travs del puerto SPI. Veamos un ejemplo de utilizacin de las funciones explicadas. El ejemplo consiste en la comunicacin de un maestro por un lado, y de un esclavo por otro. Para compilar el maestro, descomentar #define MASTER_DEVICE. #include <16f877.h> #fuses HS,NOWDT #use delay(clock=10000000) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) #use standard_IO(D) // #define MASTER_DEVICE #ifdef MASTER_DEVICE // (maestro) //un Microchip pic16f877

void main() { int8 c,d; setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16); printf(Presiona una tecla para empezar: ); while(1) { c=getchar(); output_D(0xFF ^ c); //enciende los LEDs correspondientes del // portD //las siguientes dos lneas representan un mtodo spi_write(c); d=spi_read(); //datos enviados usando write //datos ledos usando read

//mtodo alternativo a las dos lneas anteriores //d=spi_read(c); putchar(c); //escribe y lee datos usando read

} } #else // (esclavo)

void main() { int8 c; setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_CLK_DIV_16); while(1) { //flash C2 para mostrar cuando se activen output_low(PIN_C2); delay_ms(100); output_high(PIN_C2); delay_ms(100); //un metodo comprueba que los datos estn listos antes de //hacer la lectura if(spi_data_is_in()) { c=spi_read(); output_D(0xFF ^ c); //lee los datos //enciende los LEDs correspondientes //del port D spi_write(c); //espera la seal del maestro para //enviar y escribe los datos } // mtodo alternativo: // c=spi_read(c); //escribe los datos antiguos y lee los nuevos //retardo de 100 ms

//output_D(0xFF ^ c); //enciende los LEDs del port D //correspondientes } } #endif Existen numerosas libreras ms complejas que permiten la utilizacin de funciones ms especficas para la gestin del bus SPI.