|
|
View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
First time SPI questions |
Posted: Fri Aug 20, 2004 9:53 am |
|
|
Hi all,
OK I'm new to SPI and I'm interfacing a MAX1229 A/D with a 18F252 (28pin DIP) using hardware SPI and software I2C
I have the following pins connected for comms
PIC MAX1229
SDI (15) DOUT (23)
SDO (16) DIN (22)
SCK (14) SLCK (20)
RB7 (28) CS (21)
I am about to start coding but am getting a little bogged down with bus speeds and general setup and read / write, does anyone have examples of SPI with a device with a similar spec? or even better examples |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 20, 2004 3:09 pm |
|
|
The only example file that CCS has for the hardware spi_write()
function is 9356SPI.C. It's in this folder:
c:\Program Files\Picc\Drivers
It's for an EEPROM, but it shows how to use the setup_spi() function,
and do other initialization of i/o pins.
If you have an oscilloscope, I suggest that you write a small test
program that initializes the SPI pins and calls the setup_spi() function,
and then just repeatedly calls spi_write() in a continuous while(1)
loop. Maybe put a short delay between calls to spi_write() so you
can see distinct packets of 8 pulses on your scope.
Now, once you've got that program running, you can check the
relationship between the edges of the SPI clock and the data.
You can compare the output of the PIC to the Maxim data sheet and
make sure that you have setup the SPI module in the proper mode.
Also check the frequency of the SPI clock to make sure it meets spec,
and make sure you've got Chip Select going low at the appropriate time.
Once you've got the SPI bus working OK, then you can consult the
data sheet and do some testing by sending commands, and then
check the response of the chip. In other words, you can then write
the rest of the driver.
Here is a sample SPI test program, that I mentioned above.
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud = 9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main()
{
printf("Start\n\r");
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);
while(1)
{
spi_write(0x55);
delay_us(100);
}
} |
|
|
|
ANother guest Guest
|
SPI questions |
Posted: Sat Aug 21, 2004 4:55 pm |
|
|
And don't forget to check the device header file for the latest "setup_spi()" options. I spent a long time once looking at a scope and trying to figure out why the SPI didn't work. According to the CCS manual and my scope, there was no way to get the correct phase of the clock and the data using the built-in SPI functions. So I wrote my own "bit banging" routine and punted the built-in SPI stuff. But it bugged me so much, I didn't give up on using the built-in SPI. Turns out there were more options in the header file that made it work just fine. |
|
|
Kieran
Joined: 28 Nov 2003 Posts: 39 Location: Essex UK
|
|
Posted: Sun Aug 22, 2004 3:26 am |
|
|
About time CCS updated thier manual and help files! |
|
|
Guest Guest
|
Hmm, I only have v3.148 of the compiler |
Posted: Sun Aug 22, 2004 6:39 am |
|
|
Hmm, I only have v3.148 of the compiler, will this work OK as in extra setup_spi() options?
also can anyone comment if 3.148 works fine with SPI?
The reason I have not updated is it that appears to me that CCS have found a cash fountain, why do they want to get the compiler working 98% OK. If they do people won't buy maintenece. Also I got sick of updating and finding more problems.
I'd rather they got the compiler working solid and then pay for features, but lets not go down this line.......... |
|
|
Guest Guest
|
Any Ideas? |
Posted: Sun Aug 22, 2004 11:15 am |
|
|
I have got things sort of working (I can see data going both ways with scope)
But I can't see anything in Hyperterminal, set for 9600,8,N,1 does SPI affect RS232 in any way, I can see data on TX Pin but nothing in hyperterminal.
#include <16F876.H>
#fuses HS, NOWDT, NOPROTECT
#use delay(clock = 2000000)
#use rs232(baud = 9600, xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8,ERRORS)
void main()
{
printf("Start\n\r");
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);
output_low(PIN_B7);
spi_write(0b01101011);
spi_write(0b11111100);
output_high(PIN_B7);
while(1)
{
output_low(PIN_B7);
spi_write(0b10000110);
while(!input(PIN_B6)){
delay_us(10);
}
output_high(PIN_B7);
if( spi_data_is_in()){
printf("%X\n\r",spi_read());
}
}
} |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 22, 2004 1:48 pm |
|
|
SPI is a bidirectional bus, you can read and write data with the same clockpulses. You have selected SPI_MASTER, so your application is responsible for creating the clock pulses. Pass a value to the spi_read() function which will be output and so generating the clock pulses, simultaneously the read-value will be clocked in. Check the datasheet for which value to output, in the example below I've chosen a zero.
Also note that I've changed the position of your chip deselect, spi_read() won't work on a disabled device.
Code: | while(1)
{
output_low(PIN_B7);
spi_write(0b10000110);
while(!input(PIN_B6)){
delay_us(10);
}
printf("%X\n\r",spi_read(0));
output_high(PIN_B7);
} |
|
|
|
Guest Guest
|
SPI appears OK, Problem with printf. |
Posted: Sun Aug 22, 2004 3:36 pm |
|
|
Hi ckielstra,
I have checked the data sheet for this device
http://pdfserv.maxim-ic.com/en/ds/MAX1227-MAX1231.pdf
and whilst normally a CS line is "chip select" and does disable the chip, it appears that in this device it is used more like a mode select pin, and data still flows to the PIC even when high. (see page 18, fig 6, clock mode 10)
As for ths bi-directional side of things, again because of the nature of the IC, i.e. you send two bytes to gets things going, then read a byte. in this instance bi-direction does not happen.
My SPI code appears to work OK, it's my RS232 / printf that does not, do you have any idea about this? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 22, 2004 4:29 pm |
|
|
Quote: | Also can anyone comment if 3.148 works fine with SPI ?
My SPI code appears to work OK, it's my RS232 / printf that does not. |
I installed PCM 3.148, and compiled the test program below and it
worked OK. It displayed this:
Quote: | Start
After SPI init |
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main()
{
printf("Start\n\r");
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);
spi_write(0x55);
printf("After SPI init\n\r");
while(1);
} |
Quote: | Does SPI affect RS232 in any way, I can see data on TX Pin but nothing in hyperterminal. |
This sounds strange. Do you have a cable from your PIC to your PC ?
Is Hyperterminal setup at the same baudrate as the PIC ?
Also, when you say RS232 doesn't work, do you just mean the 2nd
printf() statement in your code, or do you mean both of them ?
Because the 2nd statement is inside a conditional (an 'if' statment),
and if that conditional is not executed, they you'll never see the output
from the printf(). I just wonder if you're trying to test two things here.
That's why I made a test program that was ultra-simple and would test
the basic question of: Does SPI affect RS-232 for PCM vs. 3.148 ?
The answer is no, it doesn't affect it. I think you should modify your
test program that so you're only testing one thing at a time, and prove
that each section works, before moving on to test a 2nd idea. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Aug 22, 2004 4:36 pm |
|
|
In your last post you use this #fuses directive
Quote: |
#fuses HS, NOWDT, NOPROTECT
|
As PCM programer stated, use this:
Quote: |
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
|
Humberto |
|
|
Guest Guest
|
OK, I'll try a test prog. |
Posted: Sun Aug 22, 2004 4:55 pm |
|
|
Neither printf works, I even placed a loop around the first printf and tested that without joy.
Yes I have a cable to the PC via MAX233 (I can see some data but it looks like the protocol is set wrong) I get occasional gibbirish like "000----0000gg"
I also have a seperate RS232 probe type device that I use for testing, I can probe TX pin direct, and this still fails.
Yes hyperterminal is set 9600,8,n,1
As for fuses, I don't think thats the problem, I can see B7 changing so basic IC is working OK, I am using a 20mhz crystal so it should be HS shouldn't it?
It is going to be something really stupid!! I will prog below and let you know
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT
#use delay(clock = 2000000)
#use rs232(baud = 9600, xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8,ERRORS)
void main()
{
while(1){
printf("Test\n\r");
}
}
Thx for your help..... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 22, 2004 5:00 pm |
|
|
You need to add (or change) the items shown in bold, below.
#include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, NOLVP
#use delay(clock = 2000000) // Should be 20000000 (7 zeros)
#use rs232(baud = 9600, xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8,ERRORS)
void main()
{
while(1){
printf("Test\n\r");
}
}
And it doesn't hurt to have BROWNOUT and PUT in there, either.
The brownout fuse can help to give you reliable power-ups when
you're using a "wall-wart" to power your board. The PUT fuse
helps to give enough time for the power to come up, and the
oscillator to be running nicely before program execution begins.
---------
Edited per ckielstra's post to change XT to HS, as well.
Last edited by PCM programmer on Sun Aug 22, 2004 5:43 pm; edited 2 times in total |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 22, 2004 5:09 pm |
|
|
So now we now it is the RS-232 that is not working correctly. Very likely the missing zero in the crystal speed declaration is the cause of this error.
One thing I noted in my quick browsing of the MAX1229 datasheet:
Quote: | For SPI/QSPI, ensure the CPU serial interface runs in master mode so it generates the serial clock signal. | It wouldn't hurt to change the spi_read() to a spi_read(0)....
B.T.W.: What does your function spi_data_is_in() look like?
-----
Edit: Removed a now obsolete correction to a previous posting.
Last edited by ckielstra on Mon Aug 23, 2004 1:06 am; edited 1 time in total |
|
|
Guest Guest
|
RS-232 to MAX233 -> Invert needed? |
Posted: Sun Aug 22, 2004 5:31 pm |
|
|
I think you'll need the INVERT option in the "#use rs232" command to send data from the PIC to the MAX233.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 22, 2004 5:42 pm |
|
|
Quote: | I think you'll need the INVERT option in the "#use rs232" command to send data from the PIC to the MAX233.... |
No, he doesn't need that.
First, the INVERT option doesn't work with the hardware USART in a PIC.
It can only work wth a software USART.
Secondly, you only use INVERT if you don't have a RS232 level
converter chip between the PIC and your PC, and he does: the MAX233. |
|
|
|
|
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
|