|
|
View previous topic :: View next topic |
Author |
Message |
kagalou
Joined: 19 Jan 2012 Posts: 6
|
Problem with SPI |
Posted: Thu Jan 19, 2012 7:19 am |
|
|
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: 19512
|
|
Posted: Thu Jan 19, 2012 8:15 am |
|
|
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
|
|
Posted: Thu Jan 19, 2012 8:24 am |
|
|
I never worked without float. Can you help me for that ? |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Jan 19, 2012 7:07 pm |
|
|
HELP 4 that:
read the section called
DATA DEFINITIONS
in the CCS manual
its ALL there |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19512
|
|
Posted: Fri Jan 20, 2012 2:27 am |
|
|
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
|
|
Posted: Thu Feb 09, 2012 7:12 am |
|
|
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
|
|
Posted: Thu Feb 09, 2012 1:01 pm |
|
|
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 |
|
|
|
|
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
|