|
|
View previous topic :: View next topic |
Author |
Message |
SeeCwriter
Joined: 18 Nov 2013 Posts: 160
|
SPI Enable pin |
Posted: Fri Feb 27, 2015 6:44 pm |
|
|
On a 18F8722 with PCWHD 5.042, I have the following spi statements:
Code: |
#use SPI (MASTER, SPI1, ENABLE=PIN_D0, BAUD=38400, MODE=1, BITS=8, STREAM=SPI_1)
...
spi_write( value );
|
But pin PIN_D0 doesn't do anything but lay there at 0V. I can toggle it myself using an output statement. Shouldn't the ENABLE option tell the compiler to toggle that pin when writing to the spi port? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 27, 2015 7:13 pm |
|
|
There are two methods of doing SPI with CCS.
1. With the setup_spi() method, you should use spi_write(), spi_read(), etc.
2. With the #use spi() method, you should use spi_xfer().
If you do this, you will see the Enable pin working. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Sat Feb 28, 2015 1:50 am |
|
|
PCM_programmer has covered it, but it is well worth looking at the manual.
If you look at 'setup_spi' (which does not have an option to toggle the pin), you will see it refers you to spi_read, and spi_write as the commands to do the I/O.
If you look at #USE SPI, you will find it only refers you to spi_xfer.
They are two completely separate methods of handling the SPI. There really ought to be a warning in the manual to not 'mix' the methods, but people tend not to actually read the manual.....
Setup/read/write, was the old method of handling SPI. Works for the hardware only, can only do 8bit operations, and cannot control the enable pin.
#USE is the newer method, now works very well indeed. Allows 'software' SPI masters, as well as the hardware, different length transfers, control of the enable pin, and definition of the polarities using 'mode' numbers.
As you have found, when using the hardware, you can slightly 'cross use' the two methods of working (since they both use the same hardware it makes sense), but you won't get the results you expect. |
|
|
SeeCwriter
Joined: 18 Nov 2013 Posts: 160
|
|
Posted: Mon Mar 02, 2015 10:00 am |
|
|
I read the manual, several times. As you say, there is nothing in the manual to tell the user he can't mix the two methods.
And even though I've read the manual and read the section on SPI in Mark Siegesmund's book, Embedded C Programming, I still don't understand how to use spi_xfer() when sending and receiving multi-byte data. For example, I want to read an ADC channel on a 12-bit ADC. I need to send an 8-bit control word and read back 16-bits of data. The book seems to say that for each bit sent out you get one bit back. But data coming back doesn't start until after the 8-bit control word is sent. So do I append 16 zeros to my 8-bit control word and expect spi_xfer() to return what? A 16-bit value, a 24-bit value? |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Mar 02, 2015 10:37 am |
|
|
SeeCwriter wrote: | As you say, there is nothing in the manual to tell the user he can't mix the two methods. |
And there's nothing to say he can either. It gives the two methods separately. Its therefore reasonable and prudent to assume the two don't mix perfectly, and empirical evidence proves that assumption to be right.
Quote: | I still don't understand how to use spi_xfer() when sending and receiving multi-byte data. ... I need to send an 8-bit control word and read back 16-bits of data. The book seems to say that for each bit sent out you get one bit back. But data coming back doesn't start until after the 8-bit control word is sent. So do I append 16 zeros to my 8-bit control word and expect spi_xfer() to return what? A 16-bit value, a 24-bit value? |
Its often not useful to think in bits with SPI. Bytes is often simpler. With the spi set up for 8 bit transfer, which is the default, you do three spi-xfers:
Code: |
spi_xfer(Control_Word) ; // Ignore anything sent by the ADC.
Data_A = spi_xfer(0) ; // send anything, just read what comes back. This is the one byte, low or high of the data
Data_B = spi_xfer(0) ; // send anything, just read what comes back. This is the other byte of the result.
// Now put the two data bytes together to reconstruct the ADC reading.
|
With SPI, data is indeed transferred in both directions at once under the control of the clock from the master device, in this case the PIC. Often in any one byte data is only needed to be transferred in one direction, though not always, but the master must send *something* in order to generate the right number of clocks to get the required data back. Here, you must send 3 bytes, i.e. 24 bits, of data to generate all the required clocks and transfer all data, first the command, then the returned data, The first byte is the command, and whatever comes back can be ignored. The second and third bytes are the data being sent back from the ADC and whatever is sent to it is ignored, often called "don't care".
Spi_ xfer will also allow twenty four bit transfers, for which it will do three eight bit transfers for you. The hardware, though, will only work in multiples of eight bits. One problem with that is that you'll still have to convert the 24 bit returned data into meaningful 16 bit data, and there is no 24 bit data type in CCS C. Most, if not all, SPI devices will not mind extra clocks, so doing it as a four byte, 32 bit, transfer will almost certainly also work. Personally I like consistency and therefore I always do eight bit transfers. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|