PDA

View Full Version : SPI basics



flotulopex
- 25th June 2010, 13:02
Hello there,

I've been googeling for some time now looking for a simple, commented SPI code example.

I've found lots and lots of projects and their code, but I'm still confused. In fact, I didn't really start to program or build anything since I don't even know...where to start.

In my drawer, there's an SPI 2x16 LCD display I could play with and have a start. My aim is to drive a graphical display (128x64) lateron...but let's start "simple".

Does anyone have a good link or guidance?

Darrel Taylor
- 25th June 2010, 18:15
SPI displays can be interfaced with the SHIFTOUT statement.

It's also possible to use the MSSP module, but it's a little trickier.

flotulopex
- 25th June 2010, 20:38
Thanks Darrel.

I think, I just don't get what SPI is. I assume it is a "better" or "easier" way to make things communicate.

However, I don't understand what and how I do have to implement things.

Again, my goal is to simply send the universal "Hello World!" on a SPI display.

I'm using a 16F690 that has an SSP module; fine. I see, there are two registers SSPSTAT and SSPCON I'll have to define.

Well then, let's enable the SSP module: SSPCON.5=1. Great!

And now, what do I need to do to make my LCD display the famous phrase?

I'm completely lost :(

Darrel Taylor
- 25th June 2010, 23:21
Don't even try using the MSSP module until it's working with SHIFTOUT.

What mfg/model is your SPI LCD?

sayzer
- 26th June 2010, 17:38
IF this thread gets on going by teaching something really useful and the teachings are easy to understand, I will also keep staying on it and try to learn as it goes. I am also on the same track as flotulopex.

I would very much appreciate useful inputs from people who are eager to teach this subject.

Normnet
- 26th June 2010, 19:04
Don't even try using the MSSP module until it's working with SHIFTOUT.
I'll second that.

See Hardware SPI. (http://www.picbasic.org/forum/showthread.php?p=32821#post32821)

Warning, other compiler.

Norm

flotulopex
- 26th June 2010, 21:51
Hi Darrel,

I have several displays that support either parallel or SPI interfacing.

Since I currently use this display (see picture) in 4/8 bits mode (datasheet is here http://www.lcd-module.de/eng/pdf/doma/dog-me.pdf), I think I get the best chance to learn how to get it to work via SPI.

But let's stick on basics, please.

What is SPI all about? What do I need to know to use SPI? What are the minimum requirements to make it work? So many questions....

rsocor01
- 27th June 2010, 01:57
Flotulopex,

Look at the ST7036 LCD controller datasheet

http://www.lcd-module.de/eng/pdf/zubehoer/st7036.pdf

In page 47 you will find the timming sequence for a 4-wire SPI interface, which is what you need.

Robert

Jerson
- 27th June 2010, 03:12
Flotulopex / Sayzer

I wonder if this what you are looking for. SPI is basically a synchronous way of transferring data between a MCU and peripherals.

If you understand asynchronous serial transmission, synchronous is just easier. Asynch is used in RS232 and you might be using it quite easily. Basically, asynch relies on the timing(Baud Rate) to be near accurate for it to work right. Try doing a serial transmission with interrupts on and you will see why it is so important to have a perfect timing.

SPI or any synch protocol for that matter makes life simpler by qualifying the data bit via a clock bit. The simplest analogy would be a serial to parallel shift register like the CD4094. You set up the data bit, CLOCK it in, next data bit, CLOCK it in, and so on.

Now, you will say; but, spi has 4 wires. Yes it does. One of them is for the Chip selection. The communication only works when the chip is selected via the ChipSelect line.

So, one data line going to the Serial-Parallel register SDI, one data line coming from the Parallel-Serial register SDO, one clock line to clock both these registers together and a chipselect that enables all this to work.

Look at this image to understand the concept better.
4573

Advantage of SPI, you can clock in/out the data without strict timing requirements, at your own pace.

flotulopex
- 27th June 2010, 10:12
I understand the difference between both asynch- and synchronous transmission and the advantage of the second one.

Does SPI require always 2 way communication setup? I don't see my display sending some data back to the PIC, does it?

What is the RS line for?

Starting to build-up an SPI communication, I'll need to configure the SSP module by firstly switch it ON (SSPCON.5 = 1). Then, according to my display's datasheet, I think the data is transmitted on rising edge but the setting depends on the CKP mode which I don't know what it is about ?!

Next, there seems to be several ways to send the data; either using SHIFTOUT command or via registers (SSPBUF). Which one is the better way of doing?

What about speed. My display works at 400kbits/s (or am I wrong), what will be the "safest" setting?

4575

PS: I'l be on holiday this week...

Dave
- 27th June 2010, 14:04
What is the RS line for?

The RS line on all displays I have seen is used for determining whether the data going to the display is a command for the display or data to be displayed... It should be in the documentation for the display you are using...

Dave Purola,
N8NTA

Normnet
- 27th June 2010, 17:17
Does SPI require always 2 way communication setup? I don't see my display sending some data back to the PIC, does it?

SPI both sends and receives a byte at the same time.
Just send: SSPBUF = $FF (anything) or receive: dummy = SSPBUF if one way.

Is your program working with SHIFTOUT?

Norm

rsocor01
- 27th June 2010, 18:24
Does SPI require always 2 way communication setup? I don't see my display sending some data back to the PIC, does it?

Yes, the display can send some data back to the PIC. I don't know about this particular display, but most GLCD can send data back to the PIC. This data can be anything from a Register value to the RGB value of the pixels that are been displayed in the screen.

However, if you prefer you can hardwire the display for write-only.

Robert

flotulopex
- 25th July 2010, 17:57
Well then,

Here is my first attempt to write the character "A" on my display via SPI.

As my code is for sure far too simplistic, it doesn't work :( ...anyway, it's not a surprise; I'm unfortunately used to this.

There is that "RS" line I don't really understand how I need to handle it but from the datasheet, I think I can tie it LOW (detail attached).

Any help or advice to get this "A" shining on my display is welcome ;)


<html><head></head><body><!--StartFragment--><pre><code><font color="#000080"><i>' PIC 16F690 Fuses
</i></font><font color="#008000">@ DEVICE FCMEN_OFF
@ DEVICE IESO_OFF
@ DEVICE BOD_OFF
@ DEVICE CPD_OFF
@ DEVICE PROTECT_OFF
@ DEVICE MCLR_OFF
@ DEVICE PWRT_OFF
@ DEVICE WDT_OFF
@ DEVICE XT_OSC

</font><font color="#000080"><i>' Registers 76543210
</i></font>OPTION_REG = %10000000 <font color="#000080"><i>'PORT A&amp;B Pull-Ups disabled (look WPUA &amp; WPUB)
</i></font>ANSEL = %00000000 <font color="#000080"><i>'Disable analog inputs Channels 0 to 7
</i></font>ANSELH = %00000000 <font color="#000080"><i>'Disable analog inputs Channels 8 to 11
</i></font>ADCON0 = %00000000 <font color="#000080"><i>'A/D Module is OFF
</i></font>CM1CON0 = %00000000 <font color="#000080"><i>'Comparator1 Module is OFF
</i></font>CM2CON0 = %00000000 <font color="#000080"><i>'Comparator2 Module is OFF
</i></font>INTCON = %00000000 <font color="#000080"><i>'INTerrupts CONtrol
</i></font>TRISA = %00000000 <font color="#000080"><i>'Set Input/Output (0 to 5)
</i></font>PORTA = %00000000 <font color="#000080"><i>'Ports High/Low (0 to 5)
</i></font>TRISB = %01000000 <font color="#000080"><i>'Set Input/Output (4 to 7)
</i></font>PORTB = %00000000 <font color="#000080"><i>'Ports High/Low (4 to 7)
</i></font>TRISC = %01000000 <font color="#000080"><i>'Set Input/Output (0 to 7)
</i></font>PORTC = %01000000 <font color="#000080"><i>'Ports High/Low (0 to 7)

'set up SPI master mode
</i></font>SSPSTAT = %00000000
SSPCON = %00100000


<font color="#000080"><i>'-------------------------------------------------------------------------------
' EA DOGMxxx-A SPI mode LCD circuitry (see datasheet)
' &quot;RS&quot; is pulled LOW = Instruction register (for write)

'-------------------------------------------------------------------------------
</i></font>INIT:
SCK <b>VAR </b>PORTB.6 <font color="#000080"><i>'Clock pin
</i></font>CSB <b>VAR </b>PORTC.6 <font color="#000080"><i>'LOW active pin
</i></font>SDO <b>VAR </b>PORTB.7 <font color="#000080"><i>'Data Out pin

' &quot;EA-DOGM162L-A&quot; LCD display Mandatory settings
'$39 'Function Set: 8 bits bus mode
'$1C 'Bias set
'$52 'Power control + Contrast (HiByte)
'$69 'Follower control
'$75 'Contrast (LowByte)

</i></font><b>PAUSE </b>1000 <font color="#000080"><i>'Time to settle Vdd (THIS IS VERY IMPORTANT for this display!!!)

</i></font><b>LOW </b>CSB <font color="#000080"><i>'set LCD active
</i></font><b>SHIFTOUT </b>SDO,SCK,1,[$39,$1C,$52,$69,$75] <font color="#000080"><i>'MSBFIRST
</i></font><b>HIGH </b>CSB <font color="#000080"><i>'set LCD inactive

'-------------------------------------------------------------------------------
</i></font>MAIN:

<font color="#000080"><i>' Clear display
</i></font><b>LOW </b>CSB
<b>SHIFTOUT </b>SDO,SCK,1,[$1]
<b>HIGH </b>CSB

<font color="#000080"><i>' Sent character &quot;A&quot; to display
</i></font><b>LOW </b>CSB
<b>SHIFTOUT </b>SDO,SCK,1,[$41]
<b>HIGH </b>CSB
<b>
END
</b></code></pre><!--EndFragment--></body>
</html>

NB: thanks Jerson, your explanation made the SPI principle get out my head's myst

rsocor01
- 27th July 2010, 06:19
There is that "RS" line I don't really understand how I need to handle it but from the datasheet, I think I can tie it LOW (detail attached).

The RS line is the command/data line. High being equal to data and low being equal to command. If you tie it to low, it would never work. Take a look at the examples for LCD iniatilization in the LCD datasheet.

http://www.lcd-module.de/eng/pdf/doma/dog-me.pdf

I would recommend that you try the 8-bit mode first and then after you make it work move on to the SPI mode.

Robert

flotulopex
- 27th July 2010, 08:13
Thanks Robert,

This display works like a charm in 4/8bits mode and this is why I now want to see how I can control it in SPI mode.

Humbly, I think don't even understand what I need to do to make it display something in SPI mode.

But you just gave me one more clue for a step forward:

The RS line is the command/data line. High being equal to data and low being equal to command
I read this before; the problem is, I don't clearly understand the st7036 controller's datasheet. This might be because I'm a hobbyist, not an well educated electronician :o

So, if I get it right, I should program something like this:
1.- set CS low = select the display as SPI target
2.- set RS low = select the "instruction" register
3.- send instructions = send "instructions" to the display (cursor position, clear, etc.)
4.- set RS high = select the "data" register
5.- send data = "HELLO WORLD"
6.- set CS high = unselect the target

Unfortunately, I'm in the office now and will have to be patient until tonight to try this http://www.websmileys.com/sm/sad/1346.gif

Meanwhile, if this process is somehow correct, how do I send a bunch of "instructions" or "datas" to the display? Is it a single "instr./data" @ the time? If "no", how do I send more than one info? Do I need to repeat all the steps?

What about the timings? In some examples I could find, one can see 25µs fudge factor? What is this for?

Last but not least: are my PIC settings correct in order to make the SSP work?

rsocor01
- 28th July 2010, 03:58
http://www.websmileys.com/sm/sad/1346.gif[/img]

Meanwhile, if this process is somehow correct, how do I send a bunch of "instructions" or "datas" to the display? Is it a single "instr./data" @ the time? If "no", how do I send more than one info? Do I need to repeat all the steps?

What about the timings? In some examples I could find, one can see 25µs fudge factor? What is this for?

Last but not least: are my PIC settings correct in order to make the SSP work?

Yes, you need to pull RS low to send commands and high to send data.

About the timming you should be fine. According to the ST7036 datasheet page 55, the data bit set up time, Tsds, is around 10 nsecs. So, you should be ok. A "fudge factor" is a mathematical tool to force a result to be what we want it to be. So, I don't really know what they mean by this 25 us fudge factor. Maybe they are making the bit timming to be 25 usecs long.

I would try sending any data by using a combination of HIGH and LOW for the SCL and SI lines. Go by the example of timming sequence for a 4-wire SPI in page 47 of the datasheet.

Robert

flotulopex
- 3rd August 2010, 22:00
I've been working on this for hours now, unsuccesfully :(

Finally, I reduced my code to a minimum and started some readings on the scope. In fact, the current aim is now to make sure the PIC is working as it should - not matter what data/command is sent. I'm trying to get something like this (from the display's datasheet):

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4659&d=1280867268

..but this is what I see on my scope (where SDO=SI and SCK=SCL):
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4660&d=1280867751

At a very first glance, one can see that the SCK (SCL) doesn't "tick" as it should. I even tried another PIC but no change.

I have checked and re-checked the hardware (connections and wiring) many times and I think I haven't missed something there. I also put 10k pull-down resistors on all four wires but this didn't make any difference.

Here's my "non-efficient" but as simple and readable as possible code.

<html><head></head><body><!--StartFragment--><pre><code><font color="#000080"><i>' PIC 16F690 Fuses
</i></font><font color="#008000">@ DEVICE FCMEN_OFF
@ DEVICE IESO_OFF
@ DEVICE BOD_OFF
@ DEVICE CPD_OFF
@ DEVICE PROTECT_OFF
@ DEVICE MCLR_OFF
@ DEVICE PWRT_OFF
@ DEVICE WDT_OFF
@ DEVICE INTRC_OSC_NOCLKOUT

</font><font color="#000080"><i>' Registers 76543210
</i></font>OPTION_REG = %10000000 <font color="#000080"><i>'PORT A&amp;B Pull-Ups disabled (look WPUA &amp; WPUB)
</i></font>OSCCON = %01100000 <font color="#000080"><i>'Internal RC set to 4Mhz
</i></font>ANSEL = %00000000 <font color="#000080"><i>'Disable analog inputs Channels 0 to 7
</i></font>ANSELH = %00000000 <font color="#000080"><i>'Disable analog inputs Channels 8 to 11
</i></font>WPUB = %00000000 <font color="#000080"><i>'Disable weak pull-ups
</i></font>ADCON0 = %00000000 <font color="#000080"><i>'A/D Module is OFF
</i></font>CM1CON0 = %00000000 <font color="#000080"><i>'Comparator1 Module is OFF
</i></font>CM2CON0 = %00000000 <font color="#000080"><i>'Comparator2 Module is OFF
</i></font>INTCON = %00000000 <font color="#000080"><i>'INTerrupts CONtrol
</i></font>TRISA = %00000000 <font color="#000080"><i>'Set Input/Output (0 to 5)
</i></font>PORTA = %00000000 <font color="#000080"><i>'Ports High/Low (0 to 5)
</i></font>TRISB = %00000000 <font color="#000080"><i>'Set Input/Output (4 to 7)
</i></font>PORTB = %00000000 <font color="#000080"><i>'Ports High/Low (4 to 7)
</i></font>TRISC = %00000000 <font color="#000080"><i>'Set Input/Output (0 to 7)
</i></font>PORTC = %00000000 <font color="#000080"><i>'Ports High/Low (0 to 7)

'setup SPI master mode
</i></font>SSPSTAT.6 = 1 <font color="#000080"><i>'Data transmitted on rising edge of SCK
</i></font>SSPCON.5 = 1 <font color="#000080"><i>'SSP is enabled
</i></font>SSPCON.4 = 0 <font color="#000080"><i>'Idle state for clock is a low level
</i></font>SSPCON.1 = 1 <font color="#000080"><i>'SPI Master mode, clock = FOSC/64

'-------------------------------------------------------------------------------
</i></font>INIT:
RS <b>VAR </b>PORTB.5 <font color="#000080"><i>'instruction=0 / data=1
</i></font>SCK <b>VAR </b>PORTB.6 <font color="#000080"><i>'Clock pin
</i></font>CSB <b>VAR </b>PORTB.7 <font color="#000080"><i>'LOW active pin
</i></font>SDO <b>VAR </b>PORTC.7 <font color="#000080"><i>'Data Out pin
</i></font>Mode <b>CON </b>1 <font color="#000080"><i>'MSBFIRST - Clock idles low.

'-------------------------------------------------------------------------------
</i></font><b>PAUSE </b>1000 <font color="#000080"><i>'Time to settle display's Vdd

</i></font>MAIN:

<b>LOW </b>CSB <font color="#000080"><i>'set LCD active
</i></font><b>PAUSE </b>40
<b>LOW </b>RS <font color="#000080"><i>'set Register to &quot;instruction&quot;
</i></font><b>PAUSEUS </b>3

<b>SHIFTOUT </b>SDO,SCK,Mode,[$39]
<b>PAUSE </b>30

<b>HIGH </b>CSB
<b>PAUSE </b>30

<b>GOTO </b>MAIN:

<b>END</b></code></pre><!--EndFragment--></body></html>

It looks like something is missing in the SSP setup; what is it?

The error must be obvious, but I can't see where the fish is!

Darrel Taylor
- 3rd August 2010, 22:16
Roger,

The SHIFTOUT command is software bit-bang only.
It does not use the hardware MSSP module.

When you enable the MSSP, it takes control of those pins and you can no longer use SHIFTOUT.

Just comment out all the SSP stuff.

flotulopex
- 4th August 2010, 07:49
Don't even try using the MSSP module until it's working with SHIFTOUT.

Thanks Darrel, I understand only now what you meant in a previous post ;)

flotulopex
- 4th August 2010, 18:18
The display is working now.

I'll go for some tests and give a feedback later.

Thanks again, Darrel ;)

flotulopex
- 26th May 2011, 09:28
I've been working on some different projects for a while and just forgot to give some links to the projects I made with the help of this forum.

You can find two examples of simple (hopefully not too simple) software SPI (one-way) communication in BASIC language only:

http://home.citycable.ch/flotulopex/SPI_DOGM_LCD/SPI_DOGM_LCD_Frames_e.htm

http://home.citycable.ch/flotulopex/SPI_DOGL_GLCD/SPI_DOGL_GLCD_Frames_e.htm