PDA

View Full Version : pic16f72 spi slave - ss pin function



richard
- 8th January 2015, 10:38
I'm trying to figure out a method of using the spi module in slave mode , but I don't quite get what function the ss pin has . the data sheet indicates that it resets the spi module (why ? what good does that do ?) .
I really want it to inform the program that a spi request needs to be answered (ie an interrupt) . I have used up all the interrupt pins and don't want to start again pcb wise and polling the pin seems inefficient and the chips have pretty limited resources 128 bytes ram 2k flash .I think I'm missing something here , has anybody got any tips on a good approach for an interrupt driven spi slave device.
I have got a whole bunch of these bourne absolute (8 bit grey scale) rotary encoders and a pile of pretty useless pic16f72's that combined might be useful.

HenrikOlsson
- 8th January 2015, 11:05
Hi Richard,
I've never used the (M)SSP module in SPI Slave mode but here's the way I understand it:
The SS\ pin, when enabled is an active low input. When high (inactive) the (M)SSP module is held in reset meaning no data will be clocked in.
Only when the SS\ pin is low (active) will data actually be clocked in. This is of course so you can have multiple slaves on the bus and individually selecting which one to talk to by pulling the specific slaves SS\ line low - as you would with any SPI device pretty much.

In slave mode, the SSPIF (PIR1.3) gets set when 8 bits have been shifted in, look at figures 9.3 and 9.4, if SSPIE is set and interrupts enabled an interrupt will be tripped. The SSPIF flag needs to be cleared by your interrupt service routine.

/Henrik.

richard
- 8th January 2015, 11:33
hi henrik
that makes good sense , I can follow that . if I preload data into spbuff am I correct in thinking that as the master clocks its byte in the data already in spbuff would be clocked out at the same time , I would then get the irq and could then process the received byte and reply to it by reloading spbuff with data and letting the master clock it out.
seems like a plan

HenrikOlsson
- 8th January 2015, 12:01
Hi Richard,
Yes, I think that will work. When you load SSPBUF it's content will be transparently transfered to the actual shift register (SSPSR, which you can't access "manually") and then just sit there.
When the SS pin on the slave goes low and clock pulses appears on the SCK pin the data in SSPSR get shifted out thru the SDO pin while at the same time SSPSR gets "refilled" from the other end by the data on the SDI pin.

If the SS pin goes high in the middle of the transfer the data in SSPBUF will be untouched. Only when 8 bits have been shifted out/in the data now in SSPSR gets tranfered to SSPBUF where you can grab it and SSPIF gets set.

At least that's how I interpret it.

/Henrik.

richard
- 8th January 2015, 12:17
I will give it a go and reply with results , but not tonight its nearly bed time

peterdeco1
- 8th January 2015, 18:43
On the ISD chips I use, the SS pin is a chip select/enable so you can parallel multiple chips and select which one to enable.

richard
- 9th January 2015, 07:04
Works like a dream, for 1 byte transfers



'************************************************* ***************
'* Name : are.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 1/17/2013 *
'* Version : 1.0 *
'* Notes : spi read of bourne rotary encoder *
'* : 16f72 *
'************************************************* ***************
#CONFIG
cfg = _HS_OSC
cfg&= _WDT_ON
cfg&= _PWRTE_ON
cfg&= _CP_OFF
cfg&= _BOREN_ON
__CONFIG cfg

#ENDCONFIG


include "dt_ints-14.bas"
include "REENTERPBP.bas"
asm
INT_LIST macro
INT_HANDLER SSP_INT, _spo, asm,YES
endm
INT_CREATE
INT_ENABLE SSP_INT
ENDASM

wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
'Wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
pos var byte
old_pos var byte
mint var portc.0
tmp var byte

DEFINE OSC 20

adcon1=6
trisc=%11011110
option_reg.7=0
mint=1
SSPSTAT.6=1
sspcon.5=1
sspcon.4=0
sspcon.2=1
pir1.3=0
PIE1.3=1
INTCON=$c0
gosub getp
old_pos=pos
pause 2000

MAIN
gosub getp
if (pos != old_pos )&& (mint) then
old_pos=pos
sspbuf=pos;
mint=0;
endif
GOTO MAIN


GETP:
tmp= (porta&$f)|((portb&$f)<<4)
Lookdown tmp,[$7F,$3F,$3E,$3A,$38,$B8,$98,$18,$08,$48,$49,$4D,$4 F,$0F,$2F,$AF,$BF,$9F,$1F,$1D,$1C,$5C,$4C,$0C,$04, $24,$A4,$A6,$A7,$87,$97,$D7,$DF,$CF,$8F,$8E,$0E,$2 E,$26,$06_
,$02,$12,$52,$53,$D3,$C3,$CB,$EB,$EF,$E7,$C7,$47,$ 07,$17,$13,$03,$01,$09,$29,$A9,$E9,$E1,$E5,$F5,$F7 ,$F3,$E3,$A3,$83,$8B,$89,$81,$80,$84,$94,$D4,$F4,$ F0,$F2,$FA,$FB,$F9,$F1,$D1,_
$C1,$C5,$C4,$C0,$40,$42,$4A,$6A,$7A,$78,$79,$7D,$F D,$FC,$F8,$E8,$E0,$E2,$62,$60,$20,$21,$25,$35,$3D, $3C,$BC,$BE,$FE,$7E,$7C,$74,$70,$71,$31,$30,$10,$9 0,$92,$9A,$9E,$1E,$5E,$5F],Pos
return


spo:
mint=1;
pir1.3=0
@ INT_RETURN