|
|
View previous topic :: View next topic |
Author |
Message |
cjusto
Joined: 26 Apr 2006 Posts: 38 Location: Portugal
|
Master/Slave problem SPI |
Posted: Thu Apr 27, 2006 8:40 am |
|
|
Hi forum.
i'm working on a project where i need to send data between 2 PICs.
i was told that SPI was a good option because it works well and not difficult.
i use 2 16F877
in the slave PIC i have an LCD connected working in 4bit mode.
to begin, i want to send one byte from master to slave, and display it on the LCD. the sspif never changes to 1. what am i doing wrong?
here is the code i have in a separated file for spi initialization:
Code: |
#byte SSPSTAT = 0x94 // SSPSTAT: SYNC SERIAL PORT STATUS REGISTER
#byte ADCON1 = 0x9F // ADCON1 configuration for slave mode
#byte SSPCON1 = 0x14 // SSPCON : SYNC SERIAL PORT CONTROL REGISTER
#bit SSPIE = 0x8C.3 //
#bit SSPIF = 0x0C.3 //
#bit GIE = 0x0B.7 //
#bit PEIE = 0x0B.6 //
void ini_spi_master()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);// turn on interrupts
SET_TRIS_C(0b10010000); // TRISC<5> = 0 e TRISC<3> = 0, para operar em MASTER
SSPSTAT = 0xC0;
SSPCON1 = 0X22;
setup_spi(spi_master | SPI_L_TO_H | spi_clk_div_4); // configura o modulo SSP para funcionar em SPI
}
void ini_spi_slave()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);// turn on interrupts
SET_TRIS_C(0b10011000); // TRISC<5> = 0 e TRISC<3> = 1, para operar em SLAVE
SET_TRIS_A(0b10000); // TRISA<5> = 1 para SS- em SLAVE
SSPSTAT = 0xC0;
SSPCON1 = 0X22;
setup_spi(spi_slave | SPI_L_TO_H | SPI_SS_DISABLED); // configura o modulo SSP para funcionar em SPI
}
|
i include it in both (master and slave).
the master PIC code is this:
Code: |
#include <16F877.h>
#include <ini_spi.h>
#use delay(clock=4000000)
#fuses NOWDT,HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use fast_io(C)
#define spi_ss_out PIN_C2
void main ()
{
delay_ms(1000);
ini_spi_master();
set_tris_b(0x00);
output_high(spi_ss_out);
while (TRUE)
{
output_low(spi_ss_out);
spi_write(0xcc);
output_high(spi_ss_out);
delay_ms(100);
}
}
|
i can see with the oscilloscope that clock and sdi pins on SLAVE PIC is ok.
Slave code:
Code: |
#include <16F877.h>
#include <boot_lcd.h>
#include <ini_spi.h>
#use delay(clock=4000000)
#fuses NOWDT,HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
void main ()
{
int dado_recebido=0;
ini_spi_slave();
lcd_ini();
while (TRUE)
{
lcd_escreve ('\f');
lcd_pos_xy( 1, 1);
printf(lcd_escreve,"gie=%d |peie=%d", GIE, PEIE);
lcd_pos_xy( 1, 2);
printf(lcd_escreve,"sspie=%d|sspif=%d", SSPIE, SSPIF);
delay_ms(1000);
if(spi_data_is_in())
{
dado_recebido = spi_read();
lcd_escreve ('\f');
lcd_pos_xy( 1, 1);
printf(lcd_escreve,"teste SPI:");
lcd_pos_xy( 1, 2);
printf(lcd_escreve,"%d", dado_recebido);
delay_ms(1000);
}
}
}
|
the printf(lcd_escrve, ....) is used to display data on LCD, and it works.
i am displaying the status of GIE, PEIE, SSPIE and SSPIF. Only SSPIF is 0.
what am i doing wrong?
can i do this the way i am trying to?
i hope someone can help me. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 27, 2006 11:28 am |
|
|
You're enabling interrupts, but you have no interrupt service routine.
As a result, the compiler will not put in the interrupt dispatcher code.
So when you get an interrupt, the PIC will jump to interrupt vector
at address 0004 and start executing whatever code is there. In the
case of your program, it will jump to the init code at the start of main().
In other words, your program is crashing.
In your program, you're doing everything by polling. You don't even
need to enable INT_SSP interrupts and GLOBAL interrupts. Delete
those lines. Also, in your test, you're sending bytes to the slave
every 100 ms. But because you have a huge 1000 ms delay in your
slave loop, you can't even service but one in ten of every incoming
bytes, at most. Remove the 1000ms delay from the slave code.
Also, when the SSPIF bit is set, and you detect that condition, you
must clear the bit with a line of code. The SSPIF bit is not automatically
cleared for you. (Though, if you had an #INT_SSP routine, then CCS
puts in code to clear the bit before the routine exits).
Also, my recommendation is to get rid of the #fast_io() statement
and all the TRIS statements and let the compiler handle the TRIS
automatically. It will do that for you, if you get rid of #fast_io()
and only use CCS i/o functions such as output_low(), output_high(), etc. |
|
|
cjusto
Joined: 26 Apr 2006 Posts: 38 Location: Portugal
|
Thanks! |
Posted: Thu Apr 27, 2006 12:08 pm |
|
|
hi. thanks PCM programmer.
actually now it is working. just have to check because of clock's edge and data availability.
thanks, cya around! |
|
|
CARLOS_MOLINA Guest
|
hi |
Posted: Thu May 04, 2006 5:25 pm |
|
|
hi , can you write me the corrections of your program |
|
|
jfunsang
Joined: 29 May 2006 Posts: 3
|
|
Posted: Fri Jun 02, 2006 1:21 pm |
|
|
yeah if you can copy the program that it works, will be great.
I have serious problems with the communication SPI |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|