PDA

View Full Version : SPI instead of SHIFTOUT - MAX7219



Momboz
- 19th April 2008, 18:24
Hi guys

I have been looking around for a while (almost the whole day) to find an example on how to use the SPI interface on a PIC 16F876 and I couldn't succeed. It works fine with SHIFTOUT but I would liek to try something else :-). This is to drive a MAX7219 display driver.

I am trying to get my PIC sending me data and clock signals via PORT C via the MSSP module in my PIC and no way.

That would be nice if some one could help.

I have been trying the examples given on the Mel web site and these are expecting input on the SPI bus and I couldn't make them running as well.

Here is my basic testing progamme:

' Pic Configuration
' =================
asm
device pic16F876A, hs_osc, wdt_off, lvp_off, protect_off, bod_off
endasm

SSPEN VAR SSPCON.5 'SSP Enable bit
CKP VAR SSPCON.4 'Clock Polarity Select
SSPM3 var SSPCON.3
SSPM2 var SSPCON.2
SSPM1 var SSPCON.1
SSPM0 var SSPCON.0
SMP VAR SSPSTAT.7 'Data input sample phase
CKE VAR SSPSTAT.6 'Clock Edge Select bit
SSPIF VAR PIR1.3 'SPI interrupt flag

TRISC = 0 'set PORTC I/O
'TRISB = 0
ADCON1 = %00000100
TRISA = %00100000
'PORTA = %00100000

SSPEN = 1 'enable SPI pins
CKP = 0 'clock idle low
CKE = 0 'transmit on idle to active transition
SSPIF = 0 'clear buffer full status
SMP = 0 'sample in middle of data

SSPM0 = 1
SSPM1 = 1
SSPM2 = 0
SSPM3 = 0

main:
toggle PORTB.0 ' to see if something is happening
SSPBUF = "A" ' write to SSPBUF to start clock
goto main
end

mister_e
- 19th April 2008, 18:50
What have you on hand to debug? Any PICKit 2, logic analyser, scope?

Any schematic?

I see HS OSC... it mean not much than >4MHz to me :(

More details, more help.

Momboz
- 19th April 2008, 19:47
What have you on hand to debug? Any PICKit 2, logic analyser, scope?

Any schematic?

I see HS OSC... it mean not much than >4MHz to me :(

More details, more help.
Hi Mister-e

Many thanks for the quick reaction.

As to the schematic nothing special but a PIC 16F876 with a 20 MHz crystal on a Mel PCB (PICPROTO-USB). I am checking with a scope (PCSU1000) the different signals on the PORTC C, i.e. the Serial Data Out (SDO) and the Serial Clock (SCK). Of course my PIC should be a master (or that's what I am trying to achieve).

Of course this works fine with other compilers like MikroC and CCS PICC on other hardware (EasyPIC5). And I want to have it running with PBP.

Please, let me know whether you need further detail on my system.

Darrel Taylor
- 19th April 2008, 23:38
With SSPM3:0 = 0011, it specifies the SSP clock comes from Timer2/2. But you haven't set-up Timer2.

Since the MAX7219 is a 10mhz device, you can run it at the highest speed available from the PIC.
SSPM3:0 = 0000 -- SPI master mode, clock = FOSC/4

And I think CKE should be 1.

In the Main loop, you need to wait for the SSP to finish sending the last byte, before putting a new one in the buffer.

main:
toggle PORTB.0 ' to see if something is happening
SSPBUF = "A" ' write to SSPBUF to start clock
WHILE !SSPIF : WEND
SSPIF = 0
goto main


Also the MAX7219 needs a Latch(Load) signal from the PIC, to latch the last 16-bit's into the device. Since you're only sending 1 byte, I guess you just haven't made it that far yet though.
<br>

Momboz
- 20th April 2008, 07:57
With SSPM3:0 = 0011, it specifies the SSP clock comes from Timer2/2. But you haven't set-up Timer2.

Since the MAX7219 is a 10mhz device, you can run it at the highest speed available from the PIC.
SSPM3:0 = 0000 -- SPI master mode, clock = FOSC/4

Many thanks Darrel Taylor.

Yes, you are right that's a mistake I have made. I wanted to have SSPM3:0 = 0010, i.e. the lowest speed.



And I think CKE should be 1.

I am not that far, I will check this later on.



In the Main loop, you need to wait for the SSP to finish sending the last byte, before putting a new one in the buffer.

main:
toggle PORTB.0 ' to see if something is happening
SSPBUF = "A" ' write to SSPBUF to start clock
WHILE !SSPIF : WEND
SSPIF = 0
goto main


If I add this while end loop the PIC stops and never gets further. the PORTB.0 is not blinking any more (check with a scope connected to PORTB.0).

It seems I have a problem with the interrupt setting the SSPIF flag never gets set.

What I did in my code is:


INTCON = %11000000 ' Set the interrupts, i.e. enable GIE and PEIE
SSPIE = 1 ' Enable SSPIE interrupt

Is there any mistake I have overlooked in my interrupts setting?



Also the MAX7219 needs a Latch(Load) signal from the PIC, to latch the last 16-bit's into the device. Since you're only sending 1 byte, I guess you just haven't made it that far yet though.
<br>
Yes, you are right, I am not that far in the programming. I am adopting rather a pragmatic approach, i.e. doing things step by step.

Thanks a lot.

Darrel Taylor
- 20th April 2008, 08:38
What I did in my code is:

INTCON = %11000000 ' Set the interrupts, i.e. enable GIE and PEIE
SSPIE = 1 ' Enable SSPIE interrupt

Is there any mistake I have overlooked in my interrupts setting?
NO! You don't want to do that.

You just use the flag to tell when the SSP is finished.
If you enable interrupts without any interrupt Handlers, it goes off into never never land, overflows Stacks and generally just doesn't work.
<br>

Momboz
- 20th April 2008, 08:51
NO! You don't want to do that.

You just use the flag to tell when the SSP is finished.
If you enable interrupts without any interrupt Handlers, it goes off into never never land, overflows Stacks and generally just doesn't work.
<br>
Sorry DT

I wasn't complete in my previous answer.

The first thing I did was to test with the addition of the while loop as you proposed and it wasn't successful, i.e. No toggle on PORTB.0 signal. It looks like the While loop is blocking the process (or like SSPIF is never set). if I suppress the while loop the PORTB.0 will toggle again.

That's the reason why I thought about setting the interrupts.

falingtrea
- 21st April 2008, 15:49
Here is some sample code from meLabs. Maybe that would be of help to you.

http://www.melabs.com/resources/samples/pbp/spimast.bas
http://www.melabs.com/resources/samples/pbp/spislave.bas

Momboz
- 21st April 2008, 17:53
Here is some sample code from meLabs. Maybe that would be of help to you.

http://www.melabs.com/resources/samples/pbp/spimast.bas
http://www.melabs.com/resources/samples/pbp/spislave.bas

@falingtrea

Many thanks for the advice. I have seen these examples and I couldn't succeed since I need a peer to talk to via the SPI. I am intending just to drive a MAX7219.

Vielen Dank nochmals.

Darrel Taylor
- 21st April 2008, 22:00
It looks like the While loop is blocking the process (or like SSPIF is never set). if I suppress the while loop the PORTB.0 will toggle again.

That's the reason why I thought about setting the interrupts.
Works fine here.
Ran your program (with the suggested changes) on an 877, and It sends data from the SSP and blinks the LED.

It's A VERY FAST blink. Not visible to the naked eye (or clothed ones).

Try putting a PAUSE 200 in the Main Loop.
<br>

Momboz
- 26th April 2008, 11:18
Works fine here.
Ran your program (with the suggested changes) on an 877, and It sends data from the SSP and blinks the LED.

It's A VERY FAST blink. Not visible to the naked eye (or clothed ones).

Try putting a PAUSE 200 in the Main Loop.
<br>

Dear DT

I would like, first, to thank you very very much for your support and then I wish to give you a feedback on how far I went with my SPI interface.

After some investigation I could find the reason of the problem I have making SPI running on my board. It is a hardware issue. It's the way I am using the Melabs PICPROTO-USB board. That doesn't mean that Melabs PICPROTO-USB board is faulty.

On that board you have the possibility to use the USB board in high speed. Therefore you need a capacitor C7 (0.470 µF) as shown in the documentation of that Melabs board (http://www.melabs.com/downloads/ppusbsch_06.pdf). This seems to prevent the SPI interface for running properly. I have taken the C7 away and everything went fine with SPI interface.

Maybe we will have a new Melabs board with a jumper that could leave this capacitor out when using the SPI interface

For the time being I have to make a choice for by Melabs board usage: either using USB high speed (and put the C7 capacitor) or using SPI (and take away the capacitor).

Once again many thanks for your help.

Best wishes / Momboz

Darrel Taylor
- 26th April 2008, 22:58
Good find Momboz!

I see you mentioned the PICPROTO-USB up in post #3.
But I never even looked at the schematic. :o


For the time being I have to make a choice for by Melabs board usage: either using USB high speed (and put the C7 capacitor) or using SPI (and take away the capacitor).

If you're using a PIC with USB, the SPI interface will be on different pins, so it shouldn't be a problem.
But you're right. meLabs should have put a jumper in there for the capacitor.

Cheers!