Jump to content

Recommended Posts

mityeltu    0

OK. I have banged on this for many hours, but I finally have not only a working master and slave, but I have them talking back and forth to one another. I could not find a decent example that didn't use a bunch of built in routines that don't let me know what's really going on. SO. Below are the codes for the master and slave along with the hex files and the schematic I used to make this work. The CPP files can be copies directly into a stand alone project and should compile withouit any trouble. I hope this helps someone else struggling to learn how SPI works.

18F4520-SPI-Master.cpp

18F4520-SPI-Slave.cpp

SPI-Schematic-Working.pdf

18F4520-SPI-Master.hex.txt

18F4520-SPI-Slave.hex.txt

Share this post


Link to post
Share on other sites
JorgeF    0

Hi

 

Nice job, as a first approach for newbies.

 

But exactly because it was published as a first trial example, I would leave here a few comments and sugestions about it for the newbies that will use it has a guide.

 

 

= MASTER =
Code is using RA1 as SS signal but schematic shows RA1 unconnected.
What seems to be the SS signal is connected to RA2 in the schematic.
In communications in general we do not assume the timing of the slave.
What I suggest is that after sending the request, you keep sending "NULL" (0x00) repeateadly up to an sensible timeout, until the reply arrives.
In a more elaborated application send the request as soon as possible, do any other stuff, ask for the reply (send NULL to generate the clock) only when necessary. Even so send the NULLs repeatadly until the reply is received or a sensible timeout occurs.
For SPI comms is more eficient to test for the end of a transmition before sending and not after.
This way you send one byte, go do something usefull while the SPI hardware does its job alone, and check for the end of transmition before trying to send the next byte.
Chances are that when you get back to send the next byte you don't need to wait because the transmition as already finished.
Instead of
sspbuf = dat;
while(!test_bit(pir1,3)){};

do it this way

while(!test_bit(pir1,3)){};
sspbuf = dat;
= SLAVE =
Code is listening to RA7 for the SS signal from the master, but that pin doesn't even exist.
What seems to be the SS signal in the schematic is conected to RA5.
Code is oscilating RA0 with 150mS period but there is nothing connected to it.
If it was for flashing a LED then its connected to RA1.
= PIC =
The PIC18F4520 features accessible output latch registers (lat_) so instead of writing to the "port_" we should write to the "lat_".
= BOOST C =
As of ver 7.xx of BoostC the macros "set_bit", "clear_bit" and "test_bit" are deprecated.
Versions 7.xx of BoostC support the dot (.) syntax for accessing the bits in a byte, like if the byte was a structure.
= C =
You don't need an empty blocks "{}" when there is nothing to do.
= PROGRAMMING ANY LANGUAGE =
Don't use "magic numbers" in the code, they make it very confusing even for yourself when you get back in a couple of months.
Its better to define sensible names for any used constants, and even better to use them when they were already defined for you, like with the PIC pins and SFR register bits.
Given the above:
set_bit(porta, 0);

would become

porta.RA0 = 1;

and

while(!test_bit(pir1,3)){};

should be

while(!(pir1.SSPIF == 1));

To me it looks much more readable.

 

 

EDIT ADD:

The SPI bus is supposed to be shared by multiple slaves.

So in order to be shared by several slaves, each slave must keep its SDO line in high impedance (input) until it detects its the SS signal. Then it can set SDO to output for the duration of the SS signal, and then set it to input again.

Don't forget to keep an eye in the SS signal the whole time as it can be removed even with the communication in progress due to an hardware failure or the master aborting the communication.

BTW, SDO (serial data out) id the naming convention for the I2C protocol, the correct name for that line in terms of the SPI protocol is MISO (master in slave out). But has the MSSP of the PICs implements both protocols, the mix is acceptable in the context.

 

 

EDIT CORRECT: Missing "!" in the last example.

 

 

Just my 2 cents....

 

Best regards
Jorge
Edited by JorgeF

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoticons maximum are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×