CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problem with SPI

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kagalou



Joined: 19 Jan 2012
Posts: 6

View user's profile Send private message

Problem with SPI
PostPosted: Thu Jan 19, 2012 7:19 am     Reply with quote

Hi everybody,

Please can anybody help me because I have some problems with my project.
I'm working on SPI tranfer-system and I need to send an information in 10 bits size but I have only a 8 bits information who comes out of a sensor. That's because I need to get up on 10 bits to make it work.

I waiting for your response.

Master Program:

Code:

#include "18F4580.h"
#device ADC=10   //permet de renvoyer que les 8bits de poids fort de la conversion

#use delay(clock=4000000)
//#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3)
#include "MonLCD.c"

float valeur;
float conv;
float MOY;
float MOY1;
int a=1;
int MOY2;

void main ()
{
SET_TRIS_A(0b00000001);
setup_adc(ADC_CLOCK_INTERNAL);            // l'horloge interne est utilisée pour le CAN
setup_adc_ports(AN0);            //seul la broche RA0 est analogique
set_adc_channel(0);
setup_spi(spi_master |spi_l_to_h | SPI_CLK_DIV_64);

while(1)
{
output_high(PIN_A5);
MOY1 =0;
//output_low(PIN_A5);

for (a=1;a<30;a++)
{
valeur= read_ADC();
MOY= valeur;
MOY1= MOY1+MOY;
delay_ms(10);
}
conv= MOY1/30;
MOY2= conv;

lcd_init();  // on se contente d'afficher quelque chose du genre "Freq : XXX Hz" l'affichage s'adaptera même si on a plus que 50 Hz par exemple.
lcd_gotoxy(1,1);
printf (LCD_PUTC,"\%1.2f",conv);
LCD_PUTC(" Envoi Maitre");
output_low(PIN_A5);
spi_write(MOY2);
delay_ms(100);
}
}


Slave Program:
Code:

#include "18F4580.h"
#device ADC=10
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3)
#include "MonLCD.c"

unsigned int MOY1;
float MOY;

void main ()
{
setup_spi(spi_slave |spi_l_to_h );
while(1)
{
if( spi_data_is_in() )
{
MOY1 = spi_read();

}
MOY = MOY1;

lcd_init();  // on se contente d'afficher quelque chose du genre "Freq : XXX Hz" l'affichage s'adaptera même si on a plus que 50 Hz par exemple.
lcd_gotoxy(1,1);
printf (LCD_PUTC,"\%f",MOY);
LCD_PUTC(" Recep Esclave");
lcd_gotoxy(1,2);

delay_ms(1000);
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Thu Jan 19, 2012 8:15 am     Reply with quote

You just need to do two SPI transfers. Sending a total of 16 bits, containing the 10 bits you require. and read two bytes at the slave.
Look at make8, and make16.
Get rid of the floats. Seriously, you are reading a 10bit integer from the ADC, so need to use an int16 for this, but the value you are sending is stored in an int, which can only hold 8bits. Nothing you are doing needs float, and will be much simpler if you just keep to integers....

Best Wishes
kagalou



Joined: 19 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Thu Jan 19, 2012 8:24 am     Reply with quote

I never worked without float. Can you help me for that ?
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Jan 19, 2012 7:07 pm     Reply with quote

HELP 4 that:

read the section called

DATA DEFINITIONS

in the CCS manual

its ALL there Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Fri Jan 20, 2012 2:27 am     Reply with quote

Also, as a comment, you 'work without float' all the time....

When you are adding up your bank balances, you don't start using exponential notation (unless you are somebody like Bill Gates....). You add up effectively _integer_ 'cents', and just put a decimal point after two columns of these.

The problem is that 'float', wastes an enormous amount of space, and time on a little chip like the PIC. For instance, adding two 32bit integers, takes 15 instructions, whilst adding two 'float' numbers takes over 550 instructions!. Also a 32bit integer, potentially has greater accuracy than a 'float', giving over 9digits or resolution, against a 'float' giving just over 6 digits!.

The 'good thing' about float, is it's flexibility when you don't 'know' where a number is going to be in the range of possible numbers. However when you are dealing with a number with a fixed 'range' (ADC value, 0...1023), this is not needed.

Best Wishes
kagalou



Joined: 19 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 7:12 am     Reply with quote

Hi everyone.

I come back because I have a new question ! :D
I have progress. I think.

Master program:
Code:

#include <18F4580.h>

#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

#use delay (clock=4000000)
#include "EtudiantLCD.C"

#define SS PIN_B0

void main(void)
{
set_tris_b (0b111110);
set_tris_c (0b111110);

int a;
int hi,lo;
int16 toto;


lcd_init();
setup_spi (spi_master|SPI_L_TO_H|SPI_CLK_DIV_16);
 // output_high(SS);
a=200;
hi=0;
lo=0;

output_low(SS);
delay_ms(20);
//spi_write(a);
output_high (SS);

delay_ms(100);
output_low(SS);

spi_read(hi);
hi=spi_read();

delay_ms(1000);
spi_read(lo);
lo=spi_read();

delay_ms(100);

/*/BOUCLE/*/

while(1)
   {
output_low (SS);

toto = make16(lo , hi);

/*/ Partie LCD/*/

LCD_PUTC ("\f");
lcd_gotoxy(1,1);

PRINTF(LCD_PUTC,"VL %u",lo);
PRINTF(LCD_PUTC,"VH %u",hi);

lcd_gotoxy(1,2);
PRINTF(LCD_PUTC,"ret %u" a);

PRINTF(LCD_PUTC,"test %lu",toto);
delay_ms(100);
   }
}


Slave program :

Code:
#include <18F4580.h>

#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)

#use delay (clock=4000000)
#include "EtudiantLCD.C"

#int_SSP

int a;
int lo,hi;

 //void SSP(void);
void SSP_isr(void)
{
while (!spi_data_is_in());

delay_ms(10);
spi_write(lo);
delay_ms(10);
spi_write(hi);
}

/*/ Partie LCD/*/

void main ()
{
set_tris_b (0b11111100);

int a;
int lo;
int hi;

int16 b=0x8540;
hi=make8(b,1);
lo=make8(b,0);

enable_interrupts(INT_SSP); 
enable_interrupts(GLOBAL);
lcd_init();
setup_spi (spi_slave| SPI_L_TO_H  );

spi_write(hi);
spi_write(lo);

while(1)
   {
   lcd_gotoxy(1,1);

PRINTF(LCD_PUTC,"VL %u",lo);
PRINTF(LCD_PUTC,"VH %u",hi);
lcd_gotoxy(1,2);
a=spi_read();
 PRINTF(LCD_PUTC,"retour %u",a);
   }
}

The problem is the next. I want the slave only send information when the master is asking. How can I make that ? How can I do this ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 1:01 pm     Reply with quote

There's no way your posted code above can be working. The #int_ssp
routine won't be compiled because the directive is not immediately above
the routine. Your code has large number of bugs. You are missing the
#fuses. I wonder if this is a Proteus project ?

This thread has links to spi slave examples.
http://www.ccsinfo.com/forum/viewtopic.php?t=47409&start=1
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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