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.

Trouble with SPI out on 16F819

Status
Not open for further replies.

futz

Active Member
Is there some sneaky trick to getting SPI master out to work on a PIC? I've written working SPI code for 68HC11, HC12, various AVRs and other MCU's, but I've never gotten the big fat zero like I always get with PICs (well... once, but that was different) :p

The datasheet gives very little detail (not enough). The manuals are very helpful for asynchronous and have pages about i2C. Only a couple small paragraphs about SPI.

I could bit-bang it probably, but I want to use the hardware. I'm already doing my own CS control because I want to send 16-bit packets and I don't know any other way to do that.

I'll post my code tonight if necessary. I don't have it on this machine.
 
Nigel Goodwin said:
Have you tried looking on the PICList?, if there are any problem it may well be mentioned there.
I was there last night. Didn't find anything useful. Googled far and wide - nothing useful. Dug through the Microchip stuff - really nothing helpful.

The mid-range manual does go into more detail, but still didn't tell me much more than the datasheet. There were a few clues in there though that made me think I was on the right track.

Usually if I'm close I get my display blinking gibberish or at least lighting up somehow. It hasn't done anything yet - totally blank (well, it lit up a couple times, so at least I know it has power). It's a 4-digit LED display I built years back with a Maxim 7219 controller.
 
Have you looked at the erratas for this chip? There is even one errata specific to SSP bugs. Here's the link -> **broken link removed**


There is nothing special to PIC SPI - it works more or less as described. If reading erratas won't help I'd like to see your code.
 
Well, without the code yet, we can't do much but I will say this:

1) Double check the 'tris' port settings. As far as I'm aware, unlike the USART on PIC's its common sense SDI - input, SDO/SCLK = output.
2) You sure you're selecting the right bank to move the SPI byte into SSBUF? (whatever its called :D ) 'banksel SSPBUF' before you move the byte in will make sure.
3) I find that simple shift registers are the best way to debug SPI

The tutorial for SPI/I2C on microchipsd website is handy. Step by step setting up...I'm sure its something simple, we've all spent a few nights scratching our heads over something like bank selection.

Blueteeth
 
I'm on the road at the moment and entering this with my Sidekick, but I have simple working SPI code for a 18F4620 to ENC28J60. I'll post it when I get home if you still need it.
 
Thanks everyone for trying to help. I finally got it going. Part of the problem may have been a bad connector. Once I fixed that I started to see the "getting close" symptoms: lighting up when the code starts but displaying nothing real.

Then it was the usual tinkering with the clock polarity and edge bits. Finally tried something I saw in nickelflippr's Microchip tutorial link, where they say SPI is data exchange and you should take input while transmitting, even if it's not real, read it and throw it away at the end. Of course I thought, "that's crazy!", but it works. :eek: Guess that might be the "sneaky trick" I spoke of. :D I've never done that before on other MCU's. And I saw other PIC code that doesn't do it either - but of course that method wouldn't work for me.

Here's the quick and dirty test code:
Code:
	LIST	p=16F819
	include "P16F819.inc"
	__config _INTRC_IO & _WDT_OFF & _LVP_OFF

	org	0x0000
init	
	BANKSEL	TRISA		;select bank 1
	clrf	TRISA		;PORTA all outs
	movlw	b'00000010'
	movwf	TRISB
	BANKSEL	PORTA		;select bank 0
	clrf	PORTA
	clrf	PORTB
spiinit	bsf	PORTB,0		;CS high
	BANKSEL	SSPSTAT		;select bank 1
	movlw	b'11000000'	;init SPI Master
	movwf	SSPSTAT
	BANKSEL	SSPCON		;select bank 0
	clrf	SSPCON
	movlw	b'00000010'
	movlw	SSPCON
	bsf	SSPCON,SSPEN

main	bsf	PORTB,3		;LED on
	bcf	PORTB,0		;CS low
	movlw	0x0a		;intensity register
	call	spisend
	movlw	0x0f		;full brightness
	call	spisend
	bsf	PORTB,0		;CS high

	bcf	PORTB,0		;CS low
	movlw	0x0b		;scan limit register
	call	spisend
	movlw	0x03		;display digits 0-3
	call	spisend
	bsf	PORTB,0		;CS high

	bcf	PORTB,0		;CS low
	movlw	0x09		;decode mode register
	call	spisend
	movlw	0x0f		;code B decode for digits 3-0
	call	spisend
	bsf	PORTB,0		;CS high

	bcf	PORTB,0		;CS low
	movlw	0x0c		;shutdown register
	call	spisend
	movlw	0x01		;normal operation
	call	spisend
	bsf	PORTB,0		;CS high

display	bcf	PORTB,0		;CS low
	movlw	0x01		;digit 0
	call	spisend
	movlw	0x04		;4
	call	spisend
	bsf	PORTB,0		;CS high

	bcf	PORTB,0		;CS low
	movlw	0x02		;digit 1
	call	spisend
	movlw	0x03		;3
	call	spisend
	bsf	PORTB,0		;CS high

	bcf	PORTB,0		;CS low
	movlw	0x03		;digit 2
	call	spisend
	movlw	0x02		;2
	call	spisend
	bsf	PORTB,0		;CS high

	bcf	PORTB,0		;CS low
	movlw	0x04		;digit 3
	call	spisend
	movlw	0x01		;1
	call	spisend
	bsf	PORTB,0		;CS high
	bcf	PORTB,3		;LED off
bleh	goto	bleh

spisend	movwf	SSPBUF
	BANKSEL	SSPSTAT
spiloop	btfss	SSPSTAT,BF
	goto	spiloop
	BANKSEL	SSPBUF
	movf	SSPBUF,W
	return

	end
 
Last edited:
felis said:
Have you looked at the erratas for this chip? There is even one errata specific to SSP bugs. Here's the link -> **broken link removed**
Thanks, but that errata doesn't apply to SPI. Only one little thing in i2C. The rest of the sheet is for other models.
 
futz said:
they say SPI is data exchange and you should take input while transmitting, even if it's not real, read it and throw it away at the end. Of course I thought, "that's crazy!", but it works. :eek: Guess that might be the "sneaky trick" I spoke of. :D I've never done that before on other MCU's.

That's not crazy, but very logical.

Are you saying that for some MCUs, one doesn't need to take any action regarding the received SPI data? Many MCUs will alter hardware bit/flag to signal byte received and user must take some action(s) before the next byte is fully received. Can you remember which MCU in particular allows one to forget all about the received SPI byte?

According to my understanding, SPI communication is by nature bi-directional and when you stuff 8 bits down the pipe to the other end, 8 bits will come out automatically at your end and you must handle it. You can choose to throw it away if you don't want it but you must handle it non the less.
 
eblc1388 said:
According to my understanding, SPI communication is by nature bi-directional and when you stuff 8 bits down the pipe to the other end, 8 bits will come out automatically at your end and you must handle it. You can choose to throw it away if you don't want it but you must handle it non the less.

It would depend on whether particular implementation uses separate transmit and receive buffers or just one for both directions. In micros where separate receive buffer is implemented you will get receive overflow if you ignore receive buffer; however, it won't prevent you from transmitting. PIC implementation uses one buffer to save address space; here you need to at least pretend that you care - the only way to clear BF is to read SSPBUF.
 
eblc1388 said:
Are you saying that for some MCUs, one doesn't need to take any action regarding the received SPI data?
That's what I'm saying. I've never run into this before, at least on AVRs and Motorola/Freescale MCUs. I remember years back (took a hiatus from electronics for a few years) when I first tried getting SPI working on a PIC. I got nowhere. Zip. Nada. Zilch. Guess this was the problem. :D

According to my understanding, SPI communication is by nature bi-directional and when you stuff 8 bits down the pipe to the other end, 8 bits will come out automatically at your end and you must handle it. You can choose to throw it away if you don't want it but you must handle it non the less.
Seems like it's that way on PICs, but on the others you just send. It's as simple as can be. If you want to receive (slave), you receive. I assume you can do both simultaneously, as you say. I was only sending so I didn't care.
 
Status
Not open for further replies.

Latest threads

Back
Top