Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

SPI, and my inability to make it work...

Status
Not open for further replies.

Sam Jelfs

New Member
Hi all,

Just after a quick bit of help, I'm trying to get the SPI interface on a 16F873A to work, without much luck... if you could have a look at the code below and let me know where I've gone wrong that would be good :)

I've got the micro linked up to a shift register, which in turn is linked to 8 LED's. The enable and strobe pins of the shift register are linked to porta of the micro, and data to SDO, clock to SCK. When i put a probe across enable and strobe, they pulse as they should, but i get no output from SCK and SDO.

Code:
	movlw	B'00100000'	;set port A bits according to their function, ;1=input, 0=output
	movwf	trisa	
	movlw	B'10010000'
	movwf	trisc		;and port C bits
;set up SPI
	movlw	B'00110001'
	movwf	SSPCON
	movlw	B'00000000'	
	movwf	SSPSTAT

		movlw	00
		clrf	porta
		clrf	portb
		clrf	portc
loop	bsf		porta,sipo_strobe
		bcf		porta,sipo_enable
		call	delay200
		movlw	B'10101010'
		movwf	sspbuf
		call	delay200
		bcf		porta,sipo_strobe
		bsf		porta,sipo_enable
		call	delay1000
		bsf		porta,sipo_strobe
		bcf		porta,sipo_enable
		call	delay200
		movlw	B'01010101'
		movwf	sspbuf
		call	delay200
		bcf		porta,sipo_strobe
		bsf		porta,sipo_enable
		call	delay1000
		goto	loop

Cheers

Sam J
 
You don't appear to have any bank switching code. With the code posted above then porta would not pulse as you state.

Mike.
 
ah sorry, i see what you mean, i "pruned" that out when i was copying my code across from mplab along with a load of stuff thats not to do with this...

Code:
	org 00
	bcf	status,rp1
	bsf	status,rp0 		;select memory bank 1
	movlw	B'00100000'	;set port A bits according to their function, ;1=input, 0=output
	movwf	trisa		
	movlw	B'10001010'
	movwf	trisb		;also port B bits
	movlw	B'10010000'
	movwf	trisc		;and port C bits
	movlw	B'00000110'
	movwf	adcon1		;set port A for digital i/o function
	movlw 	D'249'      ;sets PWM period. (alternative values can be used)
	movwf	pr2	
	bcf	status,rp0 		;select bank 0
;set up PWM
	movlw	B'00000100'	;switch on Timer2, no pre or postscale
	movwf	t2con
	movlw	B'00001100' ;enable PWM
	movwf	ccp1con
	movwf	ccp2con
;set up SPI
	movlw	B'00110001'
	movwf	SSPCON
	movlw	B'00000000'	
	movwf	SSPSTAT
;------------------------------------------------------------------

		movlw	00
		clrf	porta
		clrf	portb
		clrf	portc
loop	bsf		porta,sipo_strobe
		bcf		porta,sipo_enable
		call	delay200
		movlw	B'10101010'
		movwf	sspbuf
		call	delay200
		bcf		porta,sipo_strobe
		bsf		porta,sipo_enable
		call	delay1000
		bsf		porta,sipo_strobe
		bcf		porta,sipo_enable
		call	delay200
		movlw	B'01010101'
		movwf	sspbuf
		call	delay200
		bcf		porta,sipo_strobe
		bsf		porta,sipo_enable
		call	delay1000
		goto	loop
 
In order for that to happen then the port has to be setup as output. The TRIS registers are in bank 1 but you are accessing them in bank 0.

Mike.
 
Your accessing SSPSTAT in bank 0 which is writing over SSPCON.

Mike.
 
Thanks for that... foolishly I copied that section of code from an embedded systems book I have, assuming it to be correct...

I've moved
movlw b'00000000'
movwf sspstat

to before the bcf status,rp0 so it should now be accessing memory bank 1. I'm now getting output on the pins, but only a constant high on the clock, flickering for a moment once every time through the loop, and I'm getting an alternating logic level on the output pin, high for half the loop, low for the second half.

Any ideas?
 
also I forgot to note, I have put a pull-up resistor, linked to Vdd, on RA5 (pin 6) as this is the chip select pin.
 
Are you looking at it with a scope. The clock will be changing at around 250KHz and the data will continue to stay at it's last value hence the alternation. It may actually be working correctly. I would check the polarity of your enable/strobe signals.

Mike.
 
enable and strobe are fine as they haven't altered since i was loading the shift register via bit bashing. I've got it on a 20MHz scope, and it isn't showing any change in the clock, and it works fine for the 4MHz crystal osc.
 
The alternating data line indicates that the data is being sent. You can confirm this by sending the same data twice and the alternation should stop. Could the flicker on the clock line be it working - maybe the scope is triggering late / off screen. I can't see how you can get data being output without a clock unless something is physically stopping it like a solder bridge/short.

Mike.
 
i'm monitoring directly at the output pins of the chip, so solder joints aren't an issue. ive just changed SSPCON to 00110010 which should allow make the SPI interface run at 64th the osc frequency, 62KHz... plenty easy enough to detect on the scope, and still nothing... im guessing it must be a config word issue, but can't find anything.

cheers for your help

Sam J
 
The only thing I can suggest is that the overflow error somehow disables the SSP module. Try reading SSPBUF after every byte.

Mike.
 
Just did a search and found this,
When one “transmits” data, the incoming data must be read before attempting to
transmit again. If the incoming data is not read, then the data will be lost and the
SPI module may become disabled as a result. Always read the data after a transfer
has taken place, even if the data has no use in your application.

This was in this document.

Mike.
 
I've added a line, movf sspbuf,0 after each of the transmissions, but to no avail, still gettng the same results. think im going to give in for the night, given that it is 2.40am, will come back to it in a few hours and go get a more user friendly scope to check it all out on.

Thanks.

sam J
 
I cannot say whats the issue is on your end, but will provide a segment of my code, the SPI EEPROM protocal portion. Whenever my PIC peripheral pins cannot be used, I instead use my own protocals, like lcd, spi, rs232, microwire on any available pins I wish. Or for devices that do not support those built in features.

Enjoy
 

Attachments

  • EEPROM-SPI-PROTOCAL.txt
    6 KB · Views: 140
Last edited:
I'll probably be in bed when you get up as it's currently midday here.

May I suggest the following sequence to write to SSPBUF
Write to SSPBUF
Wait for BF flag
Read SSPBUF

Mike.
 
Last edited:
cheers Pommie, I'll try that.

donniedj - from mu understanding of your code, you are bit bashing the data, rather than using the on board SPI interface?
 
*hangs head in shame* wasn't a programming error after all... dead shift register. suppose thats what you get for reusing parts from an unknown past...
 
Nothing wrong with re-using, but always test first.
 
Status
Not open for further replies.

Latest threads

Back
Top