1 Attachment(s)
pic16f72 spi slave - ss pin function
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.
Re: pic16f72 spi slave - ss pin function
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.
Re: pic16f72 spi slave - ss pin function
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
Re: pic16f72 spi slave - ss pin function
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.
Re: pic16f72 spi slave - ss pin function
I will give it a go and reply with results , but not tonight its nearly bed time
Re: pic16f72 spi slave - ss pin function
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.
Re: pic16f72 spi slave - ss pin function
Works like a dream, for 1 byte transfers
Code:
'****************************************************************
'* 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,$4F,$0F,$2F,$AF,$BF,$9F,$1F,$1D,$1C,$5C,$4C,$0C,$04,$24,$A4,$A6,$A7,$87,$97,$D7,$DF,$CF,$8F,$8E,$0E,$2E,$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,$FD,$FC,$F8,$E8,$E0,$E2,$62,$60,$20,$21,$25,$35,$3D,$3C,$BC,$BE,$FE,$7E,$7C,$74,$70,$71,$31,$30,$10,$90,$92,$9A,$9E,$1E,$5E,$5F],Pos
return
spo:
mint=1;
pir1.3=0
@ INT_RETURN