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 CCS Technical Support

SPI-Problem send multiple bytes
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

SPI-Problem send multiple bytes
PostPosted: Mon Sep 24, 2018 9:17 am     Reply with quote

Hello,
I would like to send 3 bytes via SPI, first and second Byte for the addressing and the third for data. However, I need answer from slave. I know that I can send one byte and have then one byte as answer. Somehow it does not work. When I rewrite my code just one byte I also get a byte. I have to send 3 bytes and possibly also receive 3. Can you tell me where I make a mistake.

Code Master:

Code:

#include <main.h>
#use spi (MASTER, CLK=PIN_C3, DI=PIN_C4, DO=PIN_C5, ENABLE=PIN_C2, MODE=0, BITS=8, STREAM=SPI_1)
unsigned int8 eingang0=0;
int8 eingang1=0;
int8 eingang2=0;
void main()
{
   port_b_pullups(0xFF);
   output_high(pin_c2);

   while(TRUE)
   {
   if(!input(pin_b0)){while(!input(pin_b0))
output_low(pin_c2);
spi_xfer(0x01);
eingang0=spi_xfer(0);
delay_us(5);
spi_xfer(0x02);
eingang1=spi_xfer(0);
delay_us(5);
spi_xfer(0x03);
eingang2=spi_xfer(0);
output_high(pin_c2);
}
 }
}

Code Slave:
Code:

#include <main.h>
#use spi (SLAVE,SPI1,MODE=1,bits=8, STREAM=SPI_1)

#byte SSP1BUF = 0xfc9
int8 value;
int8 eing;
int8 test[3];
int8 x=0;
void Ausgaenge(void);
#INT_SSP
void  SSP_isr(void)
{

if (x>2){x=0;test[0]=0;test[1]=0;test[2]=0;}
test[x]=SSP1BUF;
x++1;
}

void main()
{
  clear_interrupt(INT_SSP);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

int8 zeit=100;
   while(TRUE)
   {
if (test[0]==0x01){SSP1BUF=0xff;}
if (test[1]==0x02){SSP1BUF=0xaa;}
if (test[2]==0x03){SSP1BUF=0xbb;}
   
 
   
   }

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 10:02 am     Reply with quote

You should be loading your reply in the int_ssp. When this triggers the first time, load the reply you expect to receive for the second transfer.

Also you need to allow time. Problem is int_ssp triggers after the byte has transferred. Your slave needs to load the reply _before_ the master does the next transfer. You don't show your clock rates, but it will take typically about 40 instruction times before the slave can load the reply byte, so the master needs to pause for at least this long before issuing the second (and later) transfers.
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 10:23 am     Reply with quote

8mhz internal clock is used. I have a waiting loop installed in master 5us after each send. How do I calculate something like that? do you have any suggestions for a program?
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 10:31 am     Reply with quote

At 8MHz you are executing 2MIPS. 40 instructions is then 20uSec. You need a little more than this (30uSec), and that only if you load the bytes inside the interrupt. In your code, you don't, you have to get out of the interrupt and read/match the data bytes, which will take several times as long....
Also you don't have any delay after sending the header byte.
Just have a counter, reset by the header byte, and incremented each time the interrupt is called after this, and load the byte based on this counter.
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 10:38 am     Reply with quote

How would you solve the problem? I also have to work outside of interrupt.
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 11:01 am     Reply with quote

Code:

//slave

int8 send[]={0xFF, 0xAA, 0xBB, 0}; //load this with what you want
//to send.

#INT_SSP
void  SSP_isr(void)
{
    temp=spi_xfer_in(); //read the incoming
    if (temp==1)
        {x=0;test[1]=0;test[2]=0;}
    test[x]=temp;
    spi_prewrite(send[x]); //preload the reply bytes
    x++;
}


//master
    output_low(pin_c2);
    spi_xfer(0x01);
    delay_us(50);
    eingang0=spi_xfer(0);
    delay_us(50);
    spi_xfer(0x02);
    eingang1=spi_xfer(0);
    delay_us(50);
    spi_xfer(0x03);
    eingang2=spi_xfer(0);
    output_high(pin_c2);
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 11:16 am     Reply with quote

output_low(pin_c2);
spi_xfer(0x01);
delay_us(50);
eingang0=spi_xfer(0);
delay_us(50);
spi_xfer(0x02);
eingang1=spi_xfer(0);
delay_us(50);
spi_Xfer(0x03);
eingang2=spi_xfer(0);
output_high(pin_c2);

I thank you very much for the approach. With master code are the delay right?
Between first send and receive you have a delay, not between the others. that's wanted, right?
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 11:23 am     Reply with quote

That's why it says //master.

I cut and pasted from your code. Added one extra delay on the first pair of transfers but missed one of the later pairs. Every pair of transfers need a delay between sending one byte and receiving the next.
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 11:41 am     Reply with quote

Thanks, I will try tomorrow. Can we write if I have any questions?
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 12:16 pm     Reply with quote

Yes, there are several people here who can help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Tue Sep 25, 2018 1:37 am     Reply with quote

Looking at it I realise you are missing one fundamental 'point' about SPI.

_Every_ SPI transaction, sends and receives a byte at the same time. You don't want to be clocking extra bytes out to receive the bytes back, use the transfers that are sending the bytes. So:
Code:

//master
    
PostPosted: Mon Sep 24, 2018 5:16 pm    Post subject:
output_low(pin_c2);
spi_xfer(0x01); //single 'send only' transfer to signal start
delay_us(50);
eingang0=spi_xfer(1); //Now each send clocks back a reply
delay_us(50);
eingang1=spi_xfer(2);
delay_us(50);
eingang2=spi_xfer(3);
output_high(pin_c2);


You use the transactions that are sending the bytes, as the transactions to clock the reply back. You don't want/need extra transactions between. I had not realised you were doing these extra transactions, which is why I missed the delays.
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

PostPosted: Wed Sep 26, 2018 1:44 pm     Reply with quote

Code:

//master

PostPosted: Mon Sep 24, 2018 5:16 pm Post subject:
output_low(pin_c2);
spi_xfer(0x01); //single 'send only' transfer to signal start
delay_us(50);
eingang0=spi_xfer(1); //Now each send clocks back a reply
delay_us(50);
eingang1=spi_xfer(2);
delay_us(50);
eingang2=spi_xfer(3);
output_high(pin_c2);

I do not understand red marked. I send 2 times the 1 in the int_ssp but I set x = 0 When temp==1. it will not be overwritten
Sterngleiter



Joined: 07 Jan 2013
Posts: 90

View user's profile Send private message

PostPosted: Wed Sep 26, 2018 1:55 pm     Reply with quote

short question, why can not I simulate proteus spi. send runs but does not receive. the same code runs in the pic real time but not at proteus
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 26, 2018 2:01 pm     Reply with quote

short answer
Proteus is busted ! Has been for YEARS, please read PIC101 sticky.
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Wed Sep 26, 2018 2:08 pm     Reply with quote

Reason is the mode numbers are wrong. The SPI at both ends needs to have the same mode setting. Currently the slave has a different mode to the master resulting in it losing a bit of the transfer....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
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