![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
jvieira88
Joined: 10 Sep 2012 Posts: 3
|
PIC18F45K20 SPI problem |
Posted: Tue Sep 18, 2012 9:48 am |
|
|
Hi guys!
I am currently trying to get a serial flash (SST25VF016B) to work with a PIC18F45K20 but I've not been lucky :/
I used the scope and checked that the pic is sending correct data from SDO and that I have clock signal too. However, I am not receiving anything on SDI.
Here is some code. It was supposed to receive 0x41, but I get 0x00. I've tried it with PIC16F690 and it works...
Code: |
#if defined(__PCH__)
#include <18F45K20.h>
#device *=16
#fuses INTRC_IO,NOPROTECT,NOBROWNOUT,MCLR,NOCPD,NOWDT,NOPUT,NOIESO,NOFCMEN,BROWNOUT_NOSL
#use delay(clock=4000000)
#use spi(master, mode=0,DI=PIN_C4,DO=PIN_C5 ,CLK=PIN_C3 )
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#endif
#define SPI_CLK PIN_C3
#define SPI_DOUT PIN_C5
#define SPI_DIN PIN_C4
#define SPI_CE PIN_A5
#define Hold PIN_A0
#define WP PIN_A1
/********************************************************************/
/* Functions for SST25VF016B Serial Flash */
/********************************************************************/
void CE_High()
{
output_high(SPI_CE); /* set CE high */
}
void CE_Low()
{
output_low(SPI_CE); /* clear CE low */
}
void EWSR()
{
CE_Low(); /* enable device */
spi_xfer(0x50); /* enable writing to the status register */
CE_High(); /* disable device */
}
void WRSR(unsigned char b)
{
EWSR();
delay_ms(10);
CE_Low(); /* enable device */
spi_xfer(0x01); /* select write to status register */
spi_xfer(b); /* data that will change the status of BPx
or BPL (only bits 2,3,4,5,7 can be written) */
CE_High(); /* disable the device */
}
void WREN()
{
CE_Low(); /* enable device */
spi_xfer(0x06); /* send WREN command */
CE_High(); /* disable device */
}
void init_spi()
{
output_high(SPI_CE);
output_low(SPI_CLK); /* set clock to low initial state */
output_high(SPI_DOUT);
}
void Unhold()
{
output_high(Hold); /* set Hold pin */
}
void UnWP()
{
output_high(WP); /* set WP pin */
}
unsigned char R_ID(ID_addr)
{
unsigned char b;
EWSR();
CE_Low();
spi_xfer(0x90); /* send read ID command (90h or ABh) */
spi_xfer(0x00); /* send address */
spi_xfer(0x00); /* send address */
b=spi_xfer(ID_addr);
b=spi_xfer(0);
b=spi_xfer(0);
CE_High();
return b;
}
// MAIN
void main ()
{
setup_oscillator(OSC_4MHZ);
delay_ms(10);
SETUP_ADC(ADC_OFF);
SETUP_ADC_PORTS(NO_ANALOGS);
SET_TRIS_A(0x00);
SET_TRIS_C(0x10);
init_spi();
delay_ms(100);
int ID;
Unhold();
UnWP();
WRSR(0x42);
while(1)
{
ID=R_ID(0x00);
printf("- %X \r\n",ID);
}
}
|
Does someone have any idea of what's going on? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 18, 2012 12:19 pm |
|
|
Quote: | #if defined(__PCH__)
#include <18F45K20.h>
#device *=16
|
The line in bold above is not necessary with the PCH compiler. It always
uses 16-bit RAM pointers. Delete that line.
Quote: | #fuses INTRC_IO,NOPROTECT,NOBROWNOUT,MCLR,NOCPD,NOWDT,NOPUT,NOIESO,NOFCMEN,BROWNOUT_NOSL
#use delay(clock=4000000)
#use spi(master, mode=0,DI=PIN_C4,DO=PIN_C5 ,CLK=PIN_C3 ) |
The #use spi() library defaults to 32-bit transfers. You don't want that.
You want 8-bit transfers. Add a "BITS=8" parameter to it. Also, the
library defaults to software SPI. I suspect that, based on your choice of
pins, you probably want hardware SPI. You need to add the FORCE_HW
parameter to the line above.
Quote: |
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#endif |
Always add the ERRORS statement to the line above, at least when you're
using the hardware UART (which you are doing). Adding ERRORS will
prevent the UART from locking up if you don't read the incoming bytes in
your main program.
Quote: | void main ()
{
setup_oscillator(OSC_4MHZ);
delay_ms(10);
SETUP_ADC(ADC_OFF);
SETUP_ADC_PORTS(NO_ANALOGS);
SET_TRIS_A(0x00);
SET_TRIS_C(0x10);
init_spi();
delay_ms(100);
int ID;
Unhold();
UnWP();
WRSR(0x42); |
Don't declare variables in the middle of code. It's not supported by CCS.
It may work this time, or it may not. Put all local variable declarations
at the start of the function. |
|
![](templates/subSilver/images/spacer.gif) |
jvieira88
Joined: 10 Sep 2012 Posts: 3
|
|
Posted: Wed Sep 19, 2012 2:35 am |
|
|
Hi PCM programmer! Thanks for the reply!
Well, I followed your advice's but still didn't get anything :/ |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 20, 2012 3:04 pm |
|
|
1. Post a list of connections between the PIC and the SST25VF016B. Trace
the connections on your board with a meter, or if you bought the board,
then look at the schematic. Post the pin numbers for the connections
between the PIC and the SST25VF016B.
2. Post your CCS compiler version.
3. Post the Vdd voltage for the PIC and for the SST25VF016B.
4. Is this a Proteus project ? |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 21, 2012 4:01 am |
|
|
Funny, but you specify value 0 and are returning address 1?
Would make more sense to specify the same value as the address you want to read (saves one spi_xfer as well). |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|