View previous topic :: View next topic |
Author |
Message |
asadi.siyavash
Joined: 01 Aug 2013 Posts: 3
|
Simple SPI doesn't WORK [SOLVED] |
Posted: Tue May 27, 2014 11:07 am |
|
|
Code: |
#include <18F26K20.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES LP //Low power osc < 200 khz
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES HS
#use delay(clock=20000000)
#use FIXED_IO( B_outputs=PIN_B0 )
#define CS PIN_B0
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
///spi modes
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
///
void main()
{
port_b_pullups(TRUE);
//adc
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
//end of adc
//watchdog
setup_wdt(WDT_OFF);
//
//SPI
setup_spi(SPI_MASTER|SPI_MODE_1|SPI_CLK_DIV_4);
//end of SPI
int8 value[1];
while(true)
{
output_low(CS);
delay_ms(10);
value[0]=spi_read();
value[1]=spi_read();
output_high(CS);
delay_ms(100);
printf("value[0]=%C\r\n",value[0]);
delay_ms(10);
printf("value[1]=%C\r\n",value[1]);
}
} |
_________________ every thing is possible if you want...
Last edited by asadi.siyavash on Tue May 27, 2014 2:18 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 27, 2014 11:39 am |
|
|
Quote: | while(true)
{
output_low(CS);
delay_ms(10);
value[0]=spi_read();
value[1]=spi_read();
output_high(CS);
|
Read my post in this thread about the correct way to do spi_read():
http://www.ccsinfo.com/forum/viewtopic.php?t=46494
Quote: | #FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES LP //Low power osc < 200 khz #FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES HS
#use delay(clock=20000000) |
You are running at 20 MHz. The LP says it's for less than 200 KHz (ie
it's for a watch crystal). Get rid of the LP fuse. You already have the
HS fuse, which is the correct one for 20 MHz.
Quote: | #use FIXED_IO( B_outputs=PIN_B0 ) |
I strongly suggest that you do not use this as a newbie. It's not
necessary. Let the compiler automatically handle setting the TRIS.
Quote: |
int8 value[1];
value[0]=spi_read();
value[1]=spi_read();
|
Your code uses an array of two bytes, but you only declare 'value'
to be an array of 1 byte. You need to fix your array declaration size.
Also, don't declare variables in the middle of code. CCS doesn't support
it. Put local variable declarations at the start of the function. Example:
Code: |
void main()
{
// Declare your local variables for main() here.
// Then put code after the variable declarations. |
Quote: | printf("value[0]=%C\r\n",value[0]);
delay_ms(10);
printf("value[1]=%C\r\n",value[1]);
|
Can you guarantee that you will only be reading printable ASCII
characters ? If not, I would use %x as the format string. Then you can
see the hex value that is received by the spi_read(). |
|
![](templates/subSilver/images/spacer.gif) |
asadi.siyavash
Joined: 01 Aug 2013 Posts: 3
|
|
Posted: Tue May 27, 2014 2:17 pm |
|
|
PCM PROGRAMMER,
thank you alot my problem solved, my major problem was SPI_READ();
as you said I should use SPI_READ(0 );
but I did it as I saw in the page "63" SPI title of "PIC MCU C COMPILER" June 2013. if it is incorrect it should be better to change it in the manual.
Really thanks for very good support,
all the best,
Siyavash _________________ every thing is possible if you want... |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Tue May 27, 2014 2:39 pm |
|
|
asadi.siyavash wrote: |
but I did it as I saw in the page "63" SPI title of "PIC MCU C COMPILER" June 2013. if it is incorrect it should be better to change it in the manual.
|
Both ways are correct depending on your needs. Not supplying an argument is for reading values obtained just from transmitting the last value (usually a full duplex style communications). It simply reads the current value in the SPI receive buffer without generating clocks. Your communications are different here. Yours need to generate the clocks and read a new value rather than the current. The most recent version of the manual (May 2014) shows both ways on that page.
You might take some time to really read up on SPI and how it works if you want to understand how spi_read() and spi_read(value) differ in operation. spi_read(value) is the most common, but I have worked with devices that would leverage spi_read() as well. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue May 27, 2014 2:41 pm |
|
|
No.
It depends on how you are using SPI_READ.
If you _write_ a byte to the SPI port, then this clocks the bus, and the data returned is available when the write has finished, for an immediate read without a byte to clock out being needed. |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Tue May 27, 2014 2:50 pm |
|
|
That's what I was saying. EDIT: though not as eloquently. |
|
![](templates/subSilver/images/spacer.gif) |
|