View previous topic :: View next topic |
Author |
Message |
steve_smith94
Joined: 21 Mar 2011 Posts: 7 Location: London
|
How do I use spi |
Posted: Tue Mar 29, 2011 5:34 am |
|
|
Guys,
I have never used the spi interface and am in need of some advice/help!
I need to communicate with a synthesizer module via spi. I am using a PIC16F917.
I only need to write to the device (issue tuning frequencies). The code relevant to this is as follows:
Code: | setup_adc_ports ( NO_ANALOGS|VSS_VDD );
setup_adc ( ADC_CLOCK_DIV_2 ) ;
setup_spi ( SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4 );
setup_lcd ( LCD_DISABLED ) ;
setup_timer_0 ( RTCC_INTERNAL|RTCC_DIV_256 );
setup_comparator ( NC_NC_NC_NC ) ;
setup_vref ( FALSE ) ;
|
and the tuning function:
Code: | /***************************Frequency Tuning Function**************************/
// Tunes the module to the correct frequency
void Tune_Module( long freq )
{
long byte2 = 0x00 ;
long byte1 = freq / 256 ;
long byte0 = freq - ( 256 * ( byte1 ) ) ;
const int NBS = 20 ; // Next Byte Setup time
spi_write( byte2 ) ;
delay_us( NBS ) ;
spi_write( printf ( "0x%02x", byte1 )) ;
delay_us( NBS ) ;
spi_write( printf( "0x%02x", byte0 )) ;
}
|
The frequency passed as a parameter is a long int and is split into 3 bytes, seperated by a 20us delay.
The code I have witten above gets stuck in the first spi_write line. I'm not sure if there is a setup part missing or if it is set up correctly or wether my code is flawed elsewhere. I do know that the function is being called on correctly.
Thanks in advance
Steve S |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Tue Mar 29, 2011 7:06 am |
|
|
Your first SPI_WRITE is OK. Your second though is insane. It is attempting to write the returned value from a printf function, which does not return anything.This could well cause completely indeterminate operation. How long the printf function will take, will depend on how your RS232 is setup. This code is simply 'wrong'....
Best Wishes |
|
|
steve_smith94
Joined: 21 Mar 2011 Posts: 7 Location: London
|
|
Posted: Tue Mar 29, 2011 7:29 am |
|
|
OK. So how do I take frequency, expressed as a long int, for example 4000. The convert this value to 3 bytes in a hex format that i can send via the spi.
do I have to set up the spi interface using the #use spi (options) ?
do I have to set up rs232 seperatly ie #use rs232 ? Why do i need this?
I'm quite confussed and the manual doesn't give out much info on spi. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Mar 29, 2011 7:42 am |
|
|
Your code has many issues.
It is important to keep a clear idea of numbers ( values ) when writing code.
Program variables are notational. Often int8 int16 ( long) storage contain numbers in binary notation that can be directly manipulated by the PIC. At times they can contain other notation like ASCII numbers to encode characters. Variables bytes int8 etc are storage but when they contain binary notation of numbers the PIC can usually use them without further translation.
Printf is a translation type interface that often changes internal notation like binary to ascii characters. Now with
spi_write( printf( "0x%02x", byte0 )) ; probably you wish to translate from binary notation of byte0 to a formatted ascii character notation of byte0 ( internal binary notation to ascii hex notation).
CCS provides a way to do this via (printf(myfunc,"0x%02x", byte0 )
Myfunc or any name you choose is a function you will write. Printf will call it for each and every acscii char it creates when performing the translation
Your function when called will take this byte that contains ascii notation for a char and in turn write it to the SPI interface as a byte since no further notational translation is needed.
The above is an assumption of what you may be wanting to do your code has issues and is unclear. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Mar 29, 2011 7:49 am |
|
|
Printf most often is linked to a serial RS232 (ttl level) interface.
You don't need this so you don't need the uses rs232 statement.
However you are now required to develop the interface. It could be to an LCD or in your case spi. That's where your own bridge ( function ( printf(myfunction," ",var) to your interface comes in. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Tue Mar 29, 2011 8:47 am |
|
|
Add that you don't need to separate the bytes. A long int (16 bits), could use up to 4 hex bytes. You imply the chip needs 3, then try to send binary '0' as the first byte (which is not hex.....). You can print all three bytes of your 'long', to SPI, with:
Code: |
if (freq)>0xFFF) {
//Value here is too big to send in 3 bytes - you may need to do something
}
else {
printf ( spi_write,"%03Lx", freq );
}
|
However this will send the MSNibble first. Is this what the chip wants?.
If not, then consider using sprintf, too a text buffer, and sending the contents of this. So:
Code: |
char buff[4];
if (freq)>0xFFF) {
//Value here is too big to send in 3 bytes - you may need to do something
}
else {
sprintf ( buff,"%03Lx", freq );
spi_write(buff[2]);
spi_write(buff[1]);
spi_write(buff[0]);
}
|
Which will send the three hex characters in reverse order.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 29, 2011 1:12 pm |
|
|
Quote: | I need to communicate with a synthesizer module via spi. |
If you help writing a driver, you should always post the manufacturer
and part number, and a link to the website and/or data sheet.
We might know of a driver that's already written for the chip. |
|
|
|