CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SPI with PIC16F690

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
geshsoft



Joined: 01 May 2007
Posts: 14
Location: California

View user's profile Send private message

SPI with PIC16F690
PostPosted: Wed Oct 10, 2007 12:44 am     Reply with quote

Hi, I am trying to setup SPI between 2 PICs and currently I only tested sending data out with spi_write() from 16F690. I looked the output waveforms. The SCK apears to be working, but I see no data on the SDO. In fact I think it appears only at the first execution of the while loop and after it never appears again. Here is the code that I typed:



#include "C:\Program Files\PICC\Projects\MasterSPI TEST\main.h"
#int_SSP

void SSP_isr(void)
{

}
//=============================================================================
//Global Variables
int8 datain;
//=============================================================================
void main()
{

setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);

delay_ms(2000);
while(1)
{
delay_us(10);
spi_write(0xff);
datain = spi_read();
}

}


The compiler version is 4.058
Ttelmah
Guest







PostPosted: Wed Oct 10, 2007 2:45 am     Reply with quote

Why have you got the SPI interrupt enabled....
What is happening, is that your code sends one byte. The SDO line will simply be high all the time (after all, you are sending all "1's"). Then when the byte is sent, the SPI interrupt will trigger, saying that a byte is ready in the input buffer. Your interrupt handler gets called, does not clear the input buffer, is called again, and the code is hung.
You either need to get rid of the SPI interrupts, or move the 'read' command into the interrupt handler.

Best Wishs
geshsoft



Joined: 01 May 2007
Posts: 14
Location: California

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 1:50 am     Reply with quote

I just tried both removing the interrupt or reading the ISP buffer during ISR - none worked. The PIC still sends the 0xff only once and then it stops doing it, but the SCK keeps on going.
Ttelmah
Guest







PostPosted: Thu Oct 11, 2007 2:10 am     Reply with quote

What else do you expect to happen?.
The code as currently shown, will just keep clocking.
It is doing exactly what it should.
First, understand, there will be no clocks for the read. In SPI, a byte is transfered in both directions at the same time. For every byte that is sent, one is read. The SPI_READ command, will just return the byte that it in the buffer, read when the write command was generated. What you should see from the commands as shown, is the SDO line going high, eight clocks from the master oscillator/16, a pause of just 10uSec, and then another sequence of eight clocks, etc. etc.. Nothing else will happen. This sounds to be exactly what you are seeing...

Best Wishes
geshsoft



Joined: 01 May 2007
Posts: 14
Location: California

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 7:52 am     Reply with quote

I understand this and this is exactly what I was expecting to see actually, but the data out goes low after the first time data is clocked out. In other words the clock keeps on clocking data out but the data being clocked would be 0x00 since data out line is low all the time, so this does not look like exactly what I was expecting. As the code is in a while loop I was expecting to see it ending 0xff infinitely. Thanks.
geshsoft



Joined: 01 May 2007
Posts: 14
Location: California

View user's profile Send private message

PostPosted: Sat Oct 13, 2007 3:11 am     Reply with quote

Ok it seems that the pic was actually clocking the datat out correctly but when I hooked the scope probe on only SCK or SDO it will stop sending it for some weird reason. If I use 2 probes - one for SDO and one for SCK then it all works on the matster side when we are talking about writing to the SPI only. Reading does not work in either the master or the slave, and I tried with spi_read() and directly writing and reading from the buffer. On top of that when I look at the data that is being sent by the slave it looks exactly the same as the one being sent by the master eventhough I wrote different value to the buffer in the slave. Here is the last code that I used:

MASTER

#include "C:\Program Files\PICC\Projects\MasterSPI TEST\main.h"
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte SPIBUF = 0x13
#int_SSP


//=============================================================================
//Global Variables
int8 datain;
//=============================================================================

void SSP_isr(void)
{
datain = SPIBUF;
}
//=============================================================================
void main()
{

setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);


delay_ms(2000);
while(1)
{
delay_ms(1000);
if(datain == 0xee)
{
output_bit(PIN_A5, 1);
delay_ms(200);
output_bit(PIN_A5, 0);
}
SPIBUF = 0xee;
//spi_write(0xee);

}

}





SLAVE



#include "c:\Program Files\PICC\Projects\MasterSPI TEST SLAVE\main.h"
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte SPIBUF = 0x13
#int_SSP


//=============================================================================
//Global Variables
int8 datain;
//=============================================================================

void SSP_isr(void)
{
datain = SPIBUF;
SPIBUF = 0xdd;
}
//=============================================================================


void main()
{

setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SLAVE|SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);

delay_ms(2000);
while(1)
{
output_bit(PIN_B7, 1);
delay_ms(500);
output_bit(PIN_B7, 0);
delay_ms(500);
if(datain == 0xee)
{
output_bit(PIN_A5, 1);
delay_ms(200);
output_bit(PIN_A5, 0);
delay_ms(200);
}

}
}
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Sat Oct 13, 2007 6:39 pm     Reply with quote

I am no SPI expert, but there are a few here and they post quite frequently.You may want to search on this. I would try without the interrupts first (just have the slave hang on a while loop until something is received).

Also remember that the data is clocked from the master-to-the-slave at the same time the data is clocked back from the slave-to-the-master. Otherwise, your data will be offset (or garbage).

This post has some similar behavior: http://www.ccsinfo.com/forum/viewtopic.php?t=26183&highlight=spi+slave+wishes
geshsoft



Joined: 01 May 2007
Posts: 14
Location: California

View user's profile Send private message

PostPosted: Sun Oct 14, 2007 1:01 pm     Reply with quote

Ok, I tried on the slave without interrupts and there is some progress. It seems like when I enable interrupts this messes up the data being clocked out by the slave. Either way, the problem I have now is that even though I write to the SSPBUF after I read the last 8 bits sent by the master, the data that is being clocked out is still what I received by the master. Here is my code for master and slave:



MASTER




#include "C:\Program Files\PICC\Projects\SSP Master\SSPM.h"
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte SSPBUF = 0x13

//=============================================================================
//Global Variables
int8 datain = 0, dataout;
//=============================================================================
//Function Prototypes
void decode(int8 data);
//=============================================================================

//=============================================================================
void main()
{

setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);

set_tris_a(0b00111000);
set_tris_b(0b00010000);
set_tris_c(0b00000000);
while(1)
{

SSPBUF = dataout;
dataout++;
if(dataout == 256){dataout = 0;}
datain = SSPBUF;
decode(datain);
delay_ms(500);
}

}
//=============================================================================
void decode(int8 data)
{
portc = (data & 0x3F);
porta = (data >> 6) & 0x03;

}





SLAVE




#include "C:\Program Files\PICC\Projects\SSP Slave\SSPS.h"

#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte SSPBUF = 0x13
#byte SSPSTAT = 0x94

int8 datain;

void main()
{

setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SLAVE|SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);


while(1)
{
while(!(SSPSTAT&0x80)){;}
datain = SSPBUF;
SSPBUF = 0xFF;

}



}




In other words, I expect to see 0xFF when I display the value on LEDs (the decode routine), but I rather see the data I sent out echoed... I am staying away from interrupts on this chip for now as it seems that they mess up everything to begin with... Any help is appreciated.
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Sun Oct 14, 2007 3:56 pm     Reply with quote

I can only offer a few questions:

  1. Have you looked at SDI on the master to verify data is clocked in from the slave?
  2. Could you re-arrange the Master code such that you allow the SSPBUF to clear the clock-out/clock-in operation, such that the register now holds whatever was clocked in? See below:
    Code:
    SSPBUF = dataout;
    dataout++;
    if(dataout == 256){dataout = 0;}
    delay_ms(500);
    datain = SSPBUF;
    decode(datain);


Hope it helps.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 14, 2007 5:36 pm     Reply with quote

Quote:
while(1)
{
while(!(SSPSTAT & 0x80)){;}
datain = SSPBUF;
SSPBUF = 0xFF;
}

You're doing a lot of strange things in your code. For example, in the
code above you are testing the SMP bit. That's a configuration bit, not
a status bit.


Quote:
#int_SSP
//=====================
//Global Variables
int8 datain;
//=====================

void SSP_isr(void)
{
datain = SPIBUF;
}

Then here, you have placed the #INT_SSP directive so it's floating
around somewhere above the global variables, instead of being placed
immediately above the interrupt service routine, which is where it belongs.



Try this example program. It shows how to make an interrupt-driven
SPI slave. In this example, the master code is contained in the same
PIC as the slave, and the master SPI signals are "bit banged".
http://www.ccsinfo.com/forum/viewtopic.php?t=26888
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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