Buscar

Apostila sobre SPI

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

ITAndroids	 “Ser a melhor equipe de robótica do mundo” 
Tutorial de SPI
Autor: Igor Franzoni Okuyama T-16
Data: 12/12/2012
1. Introdução
	O Serial Peripheral Interface (SPI) é um protocolo de comunicação síncrono que opera em modo duplex. Ele é síncrono, porque usa um clock externo para mandar informações e é duplex, pois usa duas linhas de transmissão de dados, uma para enviar e outra para receber dados.	
	Nesse protocolo, é importante a distinção entre Master e Slave. O Master, ou mestre é aquele que controla a comunicação. Ele é que decide quando o Slave (escravo) vai mandar ou receber algum dado. No SPI, há apenas um Master, mas pode haver vários Slaves.
	Esse tutorial será baseado no PIC16F877A, e usaremos o compilador do MikroC.
2. Interface
	O SPI usa basicamente 4 pinos:
· Serial Data Out (SDO) – RC5/SDO: Pino de saída de dados. (OUTPUT);
· Serial Data In (SDI) – RC4/SDI/DAS: Pino de entrada de dados (INPUT);
· Serial Clock (SCK) – RC3/SCK/SCL: Pino que envia ou recebe o clock. (OUTPUT para Master e INPUT para Slave);
· Slave Select (SS) – RA5/AN4/SS/C2OUT: Pino usado para ativar ou desligar um Slave e é usado apenas nos Slaves. 0 (zero) significa que o Slave está ativo, e 1 significa inativo. Os Slaves desligados não receberão dados do Master, ou enviarão dados para ele. Use o Slave Select apenas quando houver mais de um Slave. (INPUT para Slave somente. Master controla o SS com um pino de output qualquer).
Veja um esquema da pinagem para 1 Master e 1 Slave:
Legenda:	
· SCLK: serial clock (saída do master, entrada no slave);
· MOSI: master output, slave input (saída do master, entrada no slave);
· MISO: master input, slave output (saída no slave, entrada no master);
· SS: slave select (saída no master, entrada no slave).
Agora um esquema para 1 Master e 3 Slaves (independentes):
	
	
3. Registradores
Os registradores ligados ao SPI são 4:
· SSPCON 
· SSPSTAT
· SSPBUF	
· SSPRS
Olhe o datasheet do PIC16F877A para entender o que eles fazem. Comentaremos um pouco sobre alguns no próximo item.
4. Operação
	Aqui explicaremos como funciona o protocolo SPI no PIC16F877A.
	A figura a seguir será usada na explicação:
	Tudo começa com um dado (byte) sendo escrito no buffer (SSPBUF) do Master. Esse byte é copiado para o Shift Register (SSPSR) e a transmissão começará. O clock inicia-se e a cada mudança do clock (ver o bit 6 CKE do SSPSTAT) um bit é enviado para o Slave (do mais significativo para o menos significativo). Cada bit enviado é guardado no Shift Register do Slave até formar o byte completo.
	Quando o clock se inicia, o Slave também começa a enviar o byte que foi colocado em seu buffer previamente. Assim, ao mesmo tempo em que o Master envia um byte para o Slave, o Slave envia um byte para o Master, caracterizando a transmissão duplex.
	Quando um byte foi totalmente recebido pelo Master ou pelo Slave o flag SSPSTAT.BF (Buffer Status bit) fica com estado alto e ocorre a interrupção do SPI (flag SSPIF). Não usaremos a interrupção nesse tutorial.
	É importante notar que a transmissão de um dado só é completada se a recepção de um dado for completada. Por isso, o flag SSPSTAT.BF é importante.
	Quando o flag SSPSTAT.BF fica alto, deve-se ler o buffer para que ele volte ao estado baixo. Se isso não for feito, o flag ficará sempre alto e não poderemos detectar se o PIC recebeu algum dado. Ler o buffer também é importante para evitar overflow, isto é, evitar que um novo byte seja recebido, enquanto o buffer ainda guarda o byte anterior que não foi lido.
	OBS*: Comentaremos sobre os flags WCOL e SSPOV do SSPCON1. 
	Se você tentar transmitir um dado (escrever dado no buffer) enquanto estiver transmitindo outro, o flag WCOL ficará alto e o novo byte a ser enviado será ignorado. Por isso, sempre verifique se o WCOL está alto antes de enviar algum dado.
	O flag SSPOV ficará alto se ocorrer overflow, como explicamos acima: se você tem um byte não lido no buffer e receber outro, acontece overflow. Se SSPOV ficar alto, significa que você não leu o buffer. Sempre leia o buffer, mesmo que ele seja não seja importante.
	
	
5. Implementação
Mãos à obra!
5.1. 1 Master e 1 Slave:
	O primeiro circuito que iremos fazer terá apenas um Master e um Slave, trocando informação entre si. O Master enviará potências de 2 para o Slave, e o Slave enviará um contador binário para o Master =D. Veja os códigos:
Código do Master:
//ITAndroids
//1 Master e 1 Slave
//Código para o Master
//Compilado em MikroC 5.3
//by Igor Franzoni Okuyama T-16
char rec;
char x = 0b00000001;
char SPI(char buf)
{
 while(SSPCON.WCOL); //Esperar para não haver colisão de dados (Esperar a transmissão anterior se completar)
 SSPBUF = buf; //Carrega o dado a ser enviado no buffer (A transmissão irá começar)
 while(!SSPSTAT.BF); //Esperar o recebimento de dados ser completado
 return SSPBUF; //Retornar o dado recebido do slave
}
void init()
{
 //Configuração do SPI
 //SSPSTAT:
 SSPSTAT.SMP = 0; //Input data sampled at middle of data output time
 SSPSTAT.CKE = 0; //Transmit occurs on transition from Idle to active clock state
 //SSPCON:
 SSPCON.SSPEN = 1; //Enables serial port and configures SCK, SDO, SDI, and SS as serial port pins
 SSPCON.CKP = 0; //Idle state for clock is a low level
 SSPCON.SSPM3 = 0;
 SSPCON.SSPM2 = 0; //SPI Master mode, clock = FOSC/4
 SSPCON.SSPM1 = 0;
 SSPCON.SSPM0 = 0;
 //Configurando portas
 TRISC.F3 = 0; //SCK, Pino de clock, Master output
 TRISC.F4 = 1; //SDI, Pino de entrada de dados, Master input
 TRISC.F5 = 0; //SDO, Pino de saída de dados, Master output
 TRISD = 0b00000000; //A porta D será usada para vermos o que o Master está recebendo
}
void main()
{
 init();
 while(1)
 {
 delay_ms(10); //Espera Slave carregar buffer. IMPORTANTE! O Slave tem que carregar seu buffer antes de o Master carregar! Teste comentar essa
 //linha. O Master recebe a mesma coisa que ele enviou, pois não dá tempo de o Slave carregar seu buffer.
 rec = SPI(x); //Enviar byte x
 PORTD = rec;
 delay_ms(1000); //Esperar para transmitir dado novamente
 x = x << 1; //Operação shift para esquerda. O bit 1 vai andando
 if(x == 0b00000000)
 x = 0b00000001;
 }
}
Código do Slave:
//ITAndroids
//1 Master e 1 Slave
//Código para o Slave
//Compilado em MikroC 5.3
//by Igor Franzoni Okuyama T-16
char rec;
int cont = 0;
char SPI(char buf)
{
 while(SSPCON.WCOL); //Esperar não haver colisão de dados (Esperar a transmissão anterior se completar)
 SSPBUF = buf; //Carrega o dado a ser enviado no buffer (A transmissão irá começar)
 while(!SSPSTAT.BF); //Esperar o recebimento de dados ser completado
 return SSPBUF; //Retornar o dado recebido do slave
}
void init()
{
 //Configuração do SPI
 //SSPSTAT:
 SSPSTAT.SMP = 0; //Input data sampled at middle of data output time
 SSPSTAT.CKE = 0; //Transmit occurs on transition from Idle to active clock state
 //SSPCON:
 SSPCON.SSPEN = 1; //Enables serial port and configures SCK, SDO, SDI, and SS as serial port pins
 SSPCON.CKP = 0; //Idle state for clock is a low level
 SSPCON.SSPM3 = 0;
 SSPCON.SSPM2 = 1; //SPI Slave mode, clock = SCK pin. SS pin control disabled. SS can be used as I/O pin.
 SSPCON.SSPM1 = 0;
 SSPCON.SSPM0 = 1;
 //Configurando portas
 TRISC.F3 = 1; //SCK, Pino de clock, Slave input
 TRISC.F4 = 1; //SDI, Pino de entrada de dados, Slave input
 TRISC.F5 = 0; //SDO, Pino de saída de dados, Slave output
 TRISD = 0b00000000; //A porta D será usada para vermos o que o Slave está recebendo
}
void main()
{
 init();
 while(1)
 {
 rec = SPI(cont); //Enviar cont
 PORTD = rec; //Escrever o que foi recebido na porta D
 delay_ms(100); //Esperar para transmitir dado novamente
 cont++; //Aumentar cont para fazer um contador binário na porta D do Masterif(cont > 255)
 cont = 0;
 }
}
Veja um vídeo do funcionamento do circuito no Proteus: 
5.2 1 Master e 2 Slaves:
	Agora faremos um circuito com 1 Master controlando 2 Slaves. Sendo assim, precisaremos mudar uma configuração nos Slaves. Precisamos ativar o pino Slave Select (RA5). Para isso, configure os 4 primeiros bits do registrador SSPCON1. Além disso, precisamos configurar o pino SS como input. Para isso, além de fazer TRISA.F5 = 1, devemos desativar os conversores analógicos configurando o registrador ADCON1.
	No Master, devemos usar dois pinos quaisquer como output para controlar os Slaves. 0 (zero) significa que o Slave está ativo e 1 significa inativo.
	Nesse exemplo, os Slaves enviam uma informação qualquer para o Master, pois o foco está no envio de informação do Master para os Slaves.
	Seguem os códigos do Master e dos Slaves:
Código do Master:
//ITAndroids
//1 Master e 2 Slaves
//Código para o Master
//Compilado em MikroC 5.3
//by Igor Franzoni Okuyama T-16
#define SS1 PORTB.F6
#define SS2 PORTB.F7
char rec;
char x = 0b00000001;
char y = 0b10000000;
char SPI(char buf)
{
 while(SSPCON.WCOL);
 SSPBUF = buf;
 while(!SSPSTAT.BF);
 return SSPBUF;
}
void init()
{
 //Configuração do SPI
 //SSPSTAT:
 SSPSTAT.SMP = 0;
 SSPSTAT.CKE = 0;
 //SSPCON:
 SSPCON.SSPEN = 1;
 SSPCON.CKP = 0;
 SSPCON.SSPM3 = 0;
 SSPCON.SSPM2 = 0;
 SSPCON.SSPM1 = 0;
 SSPCON.SSPM0 = 0;
 //Configurando portas
 TRISB.F6 = 0;
 TRISB.F7 = 0;
 TRISC.F3 = 0;
 TRISC.F4 = 1;
 TRISC.F5 = 0;
}
void main()
{
 init();
 while(1)
 {
 SS1 = 0; //Slave 1 ativo
 SS2 = 1; //Slave 2 inativo
 delay_ms(1);
 rec = SPI(x);
 delay_ms(500);
 x = x << 1;
 if(x == 0b00000000)
 x = 0b00000001;
 
 SS1 = 1; //Slave 1 inativo
 SS2 = 0; //Slave 2 ativo
 delay_ms(1);
 rec = SPI(y);
 delay_ms(500);
 y = y >> 1;
 if(y == 0b00000000)
 y = 0b10000000;
 }
}
Código para os Slaves:
//ITAndroids
//1 Master e 2 Slaves
//Código para os Slaves
//Compilado em MikroC 5.3
//by Igor Franzoni Okuyama T-16
char rec;
char SPI(char buf)
{
 while(SSPCON.WCOL);
 SSPBUF = buf;
 while(!SSPSTAT.BF);
 return SSPBUF;
}
void init()
{
 //Configuração do SPI
 //SSPSTAT:
 SSPSTAT.SMP = 0;
 SSPSTAT.CKE = 0;
 //SSPCON:
 SSPCON.SSPEN = 1;
 SSPCON.CKP = 0;
 SSPCON.SSPM3 = 0;
 SSPCON.SSPM2 = 1; //SPI Slave mode, clock = SCK pin. SS pin control enabled.
 SSPCON.SSPM1 = 0;
 SSPCON.SSPM0 = 0;
 //Configurando portas
 ADCON1.PCFG3 = 0;
 ADCON1.PCFG3 = 1; //Todo o port A é digital
 ADCON1.PCFG3 = 1;
 ADCON1.PCFG3 = 0;
 TRISA.F5 = 1; //Slave Select
 TRISC.F3 = 1;
 TRISC.F4 = 1;
 TRISC.F5 = 0;
 TRISD = 0b00000000;
}
void main()
{
 init();
 while(1)
 {
 rec = SPI(0);
 PORTD = rec;
 delay_ms(1);
 }
}
Vídeo do funcionamento:
6. Bibliografia:
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
Datasheet pic 16F877A
Escreva aqui sua opinião sobre o tutorial. O que podemos melhorar? Alguma parte não está clara? Sugestões?
	Página 13
1 Master 1 Slave.avi
1 Master e 2 Slaves.avi

Continue navegando