# Clarifying PIC SPI communication and settings

#### camerart

Joined Feb 25, 2013
2,680
Hi,
For some time, I've been using SPI for PIC to peripheral communication e,g, compass module.
I've just moved a compass from an 18LF4620 working, to an 18F4431 not working.

In my program, I noticed that SSPCON1 is commented out, so I checked the data sheet, and was remined of the many settings for SPI.
I need to re-learn SPI. This page looks a good start: https://microcontrollerslab.com/spi-communication-pic-microcontroller/

Any suggestions or similar pages welcome, please.
Camerart.

#### jpanhalt

Joined Jan 18, 2008
11,088
That page looks pretty complete. What else do you need? Are you clear on how to set modes in PIC devices? Wikipedia covers the differences between PIC and other MCU's.

#### jjw

Joined Dec 24, 2013
690
Hi,
For some time, I've been using SPI for PIC to peripheral communication e,g, compass module.
I've just moved a compass from an 18LF4620 working, to an 18F4431 not working.

In my program, I noticed that SSPCON1 is commented out, so I checked the data sheet, and was remined of the many settings for SPI.
I need to re-learn SPI. This page looks a good start: https://microcontrollerslab.com/spi-communication-pic-microcontroller/

Any suggestions or similar pages welcome, please.
Camerart.
Are you now using HW SPI?
If you use Oshonsoft SW SPI, it has its own settings ( used pins and their settings)

Last edited:

#### jjw

Joined Dec 24, 2013
690
Here is another
Hi,
For some time, I've been using SPI for PIC to peripheral communication e,g, compass module.
I've just moved a compass from an 18LF4620 working, to an 18F4431 not working.

In my program, I noticed that SSPCON1 is commented out, so I checked the data sheet, and was remined of the many settings for SPI.
I need to re-learn SPI. This page looks a good start: https://microcontrollerslab.com/spi-communication-pic-microcontroller/

Any suggestions or similar pages welcome, please.
Camerart.
https://deepbluembedded.com/spi-tutorial-with-pic-microcontrollers/#SPI_Clock_Configurations_Summary

#### camerart

Joined Feb 25, 2013
2,680
That page looks pretty complete. What else do you need? Are you clear on how to set modes in PIC devices? Wikipedia covers the differences between PIC and other MCU's.
Hi J2,
I'm at the bewilderment stage at the moment, but as I unravel it, I'll ask more questions.
Here's one, that I may have just figured out, although it is not particularly rememberable
Thanks,
C

#### Attachments

• 62.1 KB Views: 2

#### jpanhalt

Joined Jan 18, 2008
11,088
This is from Wikipedia:

Those settings, I believe, apply to all PIC mid-range. I don't have a clue what Oshonsoft does. When I am working on code, I don't even try to keep them straight. I have a routine that I paste in drafts where I can just pick the conventionally named mode and see how it works. For one device, that is never a problem, but with two slave devices, you may need to see which one(s) work for both.

#### camerart

Joined Feb 25, 2013
2,680
Hi J,
Thanks for the link, I think it maybe better than my posting, and I'd rather stick to one, so I'll use yours.

I may be using both! I think you have reminded me what the difference is.
The HW settings, shown below, top
and SW setting of CLOCK polarity.
Is this correct?
______________________________________________________________________
e,g 18LF4620 EDIT
'SPI Config (OSHONSOFT)
Define SPI_SCK_REG = PORTD
Define SPI_SCK_BIT = 3
Define SPI_SDI_REG = PORTD
Define SPI_SDI_BIT = 2
Define SPI_SDO_REG = PORTD
Define SPI_SDO_BIT = 1
''Define SPICLOCK_INVERT = 1 'AK8963C, BMP280 SCL resting HIGH !!!!![[[[[[DOES THIS NEGATE SSPCON??]]]]
-----------------------------------------------
'Initialise Compass
SSPCON = %00110000 '5=Enables SCK,SDO,SDI as serial ports. 4= Clock polarity, 1 idle h, 0 idle l
'END initialise Compass
_______________________________________________________________________
Can anyone post what their procedure is for setting deep settings like this, please.
C

Last edited:

#### camerart

Joined Feb 25, 2013
2,680
This is from Wikipedia:

View attachment 224098

Those settings, I believe, apply to all PIC mid-range. I don't have a clue what Oshonsoft does. When I am working on code, I don't even try to keep them straight. I have a routine that I paste in drafts where I can just pick the conventionally named mode and see how it works. For one device, that is never a problem, but with two slave devices, you may need to see which one(s) work for both.
Hi J2,
See #7, this is one of the areas, I'm confused about.
I need to check what I have to set in HW and SW first, and get that clear.
C.

#### geekoftheweek

Joined Oct 6, 2013
692
Hardware and software SPI are totally different concepts.
_____________________________________________________________________
'SPI Config (OSHONSOFT)
Define SPI_SCK_REG = PORTD
Define SPI_SCK_BIT = 3
Define SPI_SDI_REG = PORTD
Define SPI_SDI_BIT = 2
Define SPI_SDO_REG = PORTD
Define SPI_SDO_BIT = 1
''Define SPICLOCK_INVERT = 1 'AK8963C, BMP280 SCL resting HIGH !!!!![[[[[[DOES THIS NEGATE SSPCON??]]]]
-----------------------------------------------
Is a software version where all the pins are directly manipulated by software. The hardware itself has nothing to to with SPI other than the program is changing pins.

'Initialise Compass
SSPCON = %00110000 '5=Enables SCK,SDO,SDI as serial ports. 4= Clock polarity, 1 idle h, 0 idle l
'END initialise Compass
_______________________________________________________________________
Is the beginnings of hardware SPI (except all the mode setting bits are '0'). Neither of the two has any affect on the other one besides if you try to use the hardware SPI pins for the software version (oshonsoft in this case) at the same time. Using hardware SPI you simply write a byte to SSPBUF and the hardware itself handles the pins while the software either waits for the BF flag to be set to '1' by the SPI hardware or it can do other tasks and check BF now and again to see if the SPI hardware is still busy. With your particular PIC the hardware SPI pins are permanently set and can not be changed. The datasheet has them listed.

The first sample code in your original post gives a pretty good basic program. void SPI_init() sets up the hardware while void SPI_write(char data) writes a byte and char SPI_read(char dummy) reads a byte.

#### jjw

Joined Dec 24, 2013
690
Hi J,
Thanks for the link, I think it maybe better than my posting, and I'd rather stick to one, so I'll use yours.

I may be using both! I think you have reminded me what the difference is.
The HW settings, shown below, top
and SW setting of CLOCK polarity.
Is this correct?
______________________________________________________________________
'SPI Config (OSHONSOFT)
Define SPI_SCK_REG = PORTD
Define SPI_SCK_BIT = 3
Define SPI_SDI_REG = PORTD
Define SPI_SDI_BIT = 2
Define SPI_SDO_REG = PORTD
Define SPI_SDO_BIT = 1
''Define SPICLOCK_INVERT = 1 'AK8963C, BMP280 SCL resting HIGH !!!!![[[[[[DOES THIS NEGATE SSPCON??]]]]
-----------------------------------------------
'Initialise Compass
SSPCON = %00110000 '5=Enables SCK,SDO,SDI as serial ports. 4= Clock polarity, 1 idle h, 0 idle l
'END initialise Compass
_______________________________________________________________________
Can anyone post what their procedure is for setting deep settings like this, please.
C
This is setup for Oshonsoft SW SPI.
Don't touch SSPCON in compass setup and elsewhere if HW SSPI is not used.

#### camerart

Joined Feb 25, 2013
2,680
Hi,
I got it backwards. Of course Oshonsoft is software, not hardware.
I'll go back to the start and re-read it all.
Thanks, C.

#### camerart

Joined Feb 25, 2013
2,680
Hi,
I had problems understanding HW SW previously, and in this instance it looks like I've been mixing both together.
I've been using the SW Oshonsoft SPI settings, and making the PCB and connecting the Osh SPI settings to the PIC HW SPI pins. See #7, and using 18LF4620.
Now I'm thinking it would be better to stop using the Oshonsoft SPI and use the Harware pins on the PIC along with the correct HW settings.
Is this correct?
C

#### camerart

Joined Feb 25, 2013
2,680
Hi,
I've used a modified HW example and old program header for this:
Does this look ok correct start to a HW set-up using SPI?
EDITED
C

Code:
________________________________________________________________________________
'18F4431 XTL 8mHz SPI HW COMP test 051220 1000
'------------- TARGET SETUP  ------------------
'Const pr2set = 125  'use this for the live board: gets 5ms per interrupt
Const pr2set = 2  'use this for fast timing to speed up simulator
Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

'----------- SYSTEM CONFIG  --------------------
'PIC Config
Define CONFIG1L = 0x00
Define CONFIG1H = 0x02  'XTL 8'INT OSC
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04  '04h - PWM outputs disabled upon Reset (default)
Define CONFIG3H = 0x00  '00h - SCK,SDI and SDO multiplexed with RD3, RD2 and RD1
Define CONFIG4L = 0x80  'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40
Define CLOCK_FREQUENCY = 8

Dim x As Byte
Dim dta As Byte
Dim s2m As Byte
Dim ss As Byte

'IO MAP
'SET BITS ON/OFF before TRIS!
Const LATAinit = %00000000  'ON/OFF
Const LATBinit = %00000000
Const LATCinit = %00000000
Const LATDinit = %00000000
Const LATEinit = %00000000  'POSS MCLR RE3

'SET PIN IN/OUT
Const TRISAinit = %11011100  'IN 4QEA-3QEA-2IND
Const TRISBinit = %00100000  '5=In from 4620 send QEIDEG or COMPASS on TX switch
Const TRISCinit = %00000000  '6=TX, 5= DRDY 4=COMP CS
Const TRISDinit = %00100100  '7=rled  6=yled  3= SPISCK, 2=SPISDI 1=SPISDO
Const TRISEinit = %00000000

Call spi_init()

loop:

For x = 1 To 10
Call spi_wr_rd()
dta = dta + s2m
Next x

Goto loop
End
Proc spi_init()

PORTC.4 = 0  'cs
TRISD.3 = 0  'clk
TRISD.2 = 1  'sdi from slave
TRISD.1 = 0  'sdo to slave

'MODE 0,0
ss = 1
SSPSTAT.SMP = 0  'sample a mid data
SSPSTAT.CKE = 1
SSPSTAT.5 = 0  'I2C only
SSPSTAT.4 = 0  'I2C only
SSPSTAT.3 = 0  'I2C only
SSPSTAT.2 = 0  'I2C only
SSPSTAT.1 = 0  'I2C only
SSPSTAT.BF = 0  'If SSPBUF=1=Full

'SSPCON = 0x10  'full whack... at 8mhz 2mhz operation no SS control
SSPCON.WCOL = 0  'No collision
SSPCON.SSPOV = 0  'No overflow
SSPCON.SSPEN = 1  'Enables serial port and configures SCK, SDO and SDI as serial port pins
SSPCON.CKP = 0  'Clock Idle Low, Active High
SSPCON.SSPM3 = 0  '0010 = SPI Master Mode Fosc/64???????????????
SSPCON.SSPM2 = 0
SSPCON.SSPM1 = 1
SSPCON.SSPM0 = 0

End Proc

Proc spi_wr_rd()
ss = 0
WaitUs 10
''While Not SSPSTAT.BF<<<<<<<<<<<<<<<<<<
''Wend<<<<<<<<<<<<<<<<<<<<<
s2m = SSPBUF
WaitUs 2
ss = 1
End Proc
_______________________________________________________________________________________________
_______________________________________________________________________________
Moderators note : please use code tags for pieces of code

Last edited:

#### jjw

Joined Dec 24, 2013
690
Hi,
I had problems understanding HW SW previously, and in this instance it looks like I've been mixing both together.
I've been using the SW Oshonsoft SPI settings, and making the PCB and connecting the Osh SPI settings to the PIC HW SPI pins. See #7, and using 18LF4620.
Now I'm thinking it would be better to stop using the Oshonsoft SPI and use the Harware pins on the PIC along with the correct HW settings.
Is this correct?
C
Why do you want to change the Oshonsoft SPI to HW SPI?

#### camerart

Joined Feb 25, 2013
2,680
Why do you want to change the Oshonsoft SPI to HW SPI?
Hi J,
I'm trying to understand the differences between SW and HW.

If Oshonsoft SPI settings are used, can any PINs be chosen, or as I have done, chosen the dedicated PINs from the D/S? Does it matter?

When using the OSH SPI (or other module) Do any other settings need to be made, if so which ones? EDIT e,g,SSPCON = %0010000 '5=Enables SCK,SDO,SDI as serial ports. And OSCCON = %01110010 'internal 8Mhz

C.

Last edited:
jjw

#### jjw

Joined Dec 24, 2013
690
Hi J,
I'm trying to understand the differences between SW and HW.

If Oshonsoft SPI settings are used, can any PINs be chosen, or as I have done, chosen the dedicated PINs from the D/S? Does it matter?

When using the OSH SPI (or other module) Do any other settings need to be made, if so which ones? EDIT e,g,SSPCON = %0010000 '5=Enables SCK,SDO,SDI as serial ports. And OSCCON = %01110010 'internal 8Mhz

C.
This has been discussed before.
SW SPI is a function (bitbanged) in Oshonsoft which manipulates the I/O pins, defined in setup:
Define SPI_SCK_REG = PORTD
Define SPI_SCK_BIT = 3
Define SPI_SDI_REG = PORTD
...

HW SPI should be disabled ( I think it is default)
Any free IO pins can be used.

#### camerart

Joined Feb 25, 2013
2,680
This has been discussed before.
SW SPI is a function (bitbanged) in Oshonsoft which manipulates the I/O pins, defined in setup:
Define SPI_SCK_REG = PORTD
Define SPI_SCK_BIT = 3
Define SPI_SDI_REG = PORTD
...

HW SPI should be disabled ( I think it is default)
Any free IO pins can be used.
Hi J,
I'm sorry for the need for repeated questions, but if I can't get something to work, I try looking in the D/S, and often accidently go on the wrong track, as I'm never sure what I'm doing.

This SW HW thing is difficult for me to grasp.

I'll keep trying.
EDIT: I've reverted to the SPI settings and an older program, which is outputing some results, so moved forward, Thanks again.
Thanks, C.

Last edited:

#### ericgibbs

Joined Jan 29, 2010
13,685
hi C,
PIC Hardware:
A Hardware feature physically exists within the PIC
The module hardware is designed to perform a range of specific functions, which function is used, is determined by the program initialisation code for that hardware module.

PIC Software:
Software, in the context you keep referring too, it is a method of controlling the PIC pins to perform a function that would normally done in Hardware [ as above ].

Example:
You could write Code that utilises the inbuilt Hardware module, eg: SPI and its associated pins or you could write Code which does not use the inbuilt module, but simulates a built an inbuilt function, eg: SPI.

Usually the inbuilt functions are faster and require less supporting code than a software coded function that does the same job.

Oshonsoft often uses the Software approach to carry out an inbuilt hardware function, I expect that Vlad has done this so that writing the compiler for different PIC's is easier.

E

#### John P

Joined Oct 14, 2008
1,910
As I said back on Nov 25, I've been having trouble with SPI on a PIC16F18345. I just can't get incoming data to register as anything but all zeros. The chip has peripheral pin select, and I've tried to verify that I've set it right; the clock and data-out pins are functioning fine, but that data-in line just won't give me anything useful. I've had to write a software replacement, which works OK, but it's slower than hardware would be.

If you write a software SPI routine, can anyone beat 4 instructions per bit sent and received? I think that's pretty good. (The method is to deliver the clock as a PWM output, timed to make transitions at the right times for writing/reading the data lines.)

#### camerart

Joined Feb 25, 2013
2,680
Oshonsoft often uses the Software approach to carry out an inbuilt hardware function, I expect that Vlad has done this so that writing the compiler for different PIC's is easier.

E
Hi E,
Regarding the Oshonsoft SPI:
You may be able to see why I am/was puzzled. Vlad had used SW to carry out the HW function. Am I correct then, that it needs the correct HW PINs as the D/S.

As you will recall, I've always used it's software sucessfully. I only questioned it with this 18F4431, as I haven't been able to get it to READ the COMP.

In #17 I said I had results. This is by outputting the RAW DATA, which is early in the sequence. Tomorrow, I'll move it through to the end of the sequence hopefully.
Thanks, C.

Last edited: