|
|
View previous topic :: View next topic |
Author |
Message |
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Mar 08, 2011 2:27 am |
|
|
How much time this loop will take if I am running processor at 20Mhz? My controller is 18f252.
Code: |
b0=GetByte(value1,0);
b1=GetByte(value1,1);
b2=GetByte(value1,2);
b3=GetByte(value1,3);
spi_write(b0);
spi_write(b1);
spi_write(b2);
spi_write(b3);
|
At the receiver side if I use interrupt then the data received in SSPBUF buffer. I have to save that data in a variable which takes some time, so how much delay is required between two spi_write commands in order that I can transfer data from SSPBUF to variable? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Mar 08, 2011 2:51 am |
|
|
Impossible to answer. Speed depends on how fast you are clocking the SPI.
However, the 'GetByte' routine is horribly inefficient. Use 'make8', or a union instead. Using a pointer, and adding an offset to get a byte, takes perhaps about a dozen machine cycles. Make8, or the union, take just a couple....
Again impossible to answer about the receiver. Depends how fast it is clocking. Typically takes 30 instructions to get into the interrupt, and perhaps a handful (if the code is well written), to get the byte from the SSP register. Say 40 instructions. At 4MHz, 40uSec, but at 40Mhz, just 4.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Mar 08, 2011 6:09 am |
|
|
make8 function works for int16 and int32 bits.how i can set it to work with floating numbers? |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Mar 08, 2011 6:19 am |
|
|
union function is like that
Code: |
union convert
{
int8 b[4];
float fval;
}
val;
val.fval=value1;
b0=val.b[3];
b1=val.b[2];
b2=val.b[1];
b3=val.b[0];
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Mar 08, 2011 9:10 am |
|
|
Yes, I personally use, and prefer unions, since they are supported in other C's. However you can also get the same effect, and use 'make8', using the #byte directive.
Code: |
float val;
int32 int_valversion;
#byte int_valversion=val;
val=1.2345;
make8(int_valversion,0);
|
This tells the compiler to put the int32 variable 'int_valversion', at the same location in memory, as 'val' - exactly the same thing that the union does, and then 'make8', returns the first byte of this. make32, can be used to go the other way.
If you check the .sym file, you will find the two variables are in the same memory location.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 09, 2011 2:57 am |
|
|
I tried to make a spi routine but unfortunately it is not working
Interrupt is not generating
here is my code
Master
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
#define SSP_SS PIN_B5
#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)
float value1;
int b0,b1,b2,b3;
void main()
{
output_high(SSP_SS);
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
while(1)
{
value1=12.34;//value which has to be sent
//break the floating value to seperate bytes and then send through SPI.
{
union convert
{
int data[4];
float number;
}
val;
val.number=value1;
b0=val.data[3];
b1=val.data[2];
b2=val.data[1];
b3=val.data[0];
}
output_low(SSP_SS);
spi_write(b0);//sending first byte
output_high(SSP_SS);
delay_ms(1);//some delay
output_low(SSP_SS);
spi_write(b1);//sending 2nd byte
output_high(SSP_SS);
delay_ms(1);//some delay
output_low(SSP_SS);
spi_write(b2);//sending 3rd byte
output_high(SSP_SS);
delay_ms(1);//some delay
output_low(SSP_SS);
spi_write(b3);//sending 4th byte
output_high(SSP_SS);
delay_ms(1);//some delay
delay_ms(500);//after 0.5 sec repeat the process again.
}
}
|
Slave
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
#byte SSPBUF = 0xFC9//register value for 18f252
#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)
int data[4],x=0,flag=0;
float recive;
int32 data32;
#int_ssp
void ssp_isr(void)
{
data[x]=SSPBUF;
x++;
if(x>=4)
{
x=0;
flag=1;
}
}
void main()
{
setup_spi(SPI_MASTER | SPI_MODE_0);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
if(flag==1)
{
data32=make32(data[0],data[1],data[2],data[3]);
//function for making int32 to float
{
union convert
{
int32 y;
float fval;
}
val;
val.y=data32;
recive=val.fval;
}
printf("%f\r\n",recive);//display the result.
flag=0;
}
}
}
|
Give me some suggestions how it will work. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Mar 09, 2011 3:15 am |
|
|
First, shift your union declarations to the start of the function. C traditionally only allows declarations at the start of the functions. Latter versions allow them at the start of any code block. CCS, 'tries' to allow them inline to some extent, but they are much more reliable if you use the traditional declarations. The inline versions have a 'habit' of resulting in variables overlapping one another. So _keep to standard C syntax_.
Second, your slave SPI port, needs to be a slave, not a master. Something like:
setup_spi(SPI_MODE_0 | SPI_SS_ENABLED);
Since you are sending a slave select in the master.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 09, 2011 3:32 am |
|
|
Thanks Ttelmah
I compiled after your given suggestions but it gives me error at this line
Code: |
setup_spi(SPI_MODE_0 | SPI_SS_ENABLED); |
Quote: | Undefined identifier SPI_SS_ENABLED |
Slave
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
#byte SSPBUF = 0xFC9//register value for 18f252
#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)
int data[4],x=0,flag=0;
float recive;
int32 data32;
union convert
{
int32 y;
float fval;
}
val;
#int_ssp
void ssp_isr(void)
{
data[x]=SSPBUF;
x++;
if(x>=4)
{
x=0;
flag=1;
}
}
void main()
{
setup_spi(SPI_MODE_0 | SPI_SS_ENABLED);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
if(flag==1)
{
data32=make32(data[0],data[1],data[2],data[3]);
//function for making int32 to float
val.y=data32;
recive=val.fval;
printf("%f\r\n",recive);//display the result.
flag=0;
}
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Mar 09, 2011 3:59 am |
|
|
Look in the 18F252.h, for the legal syntax. Unfortunately, CCS has the habit of changing their defines between compiler versions and chips. The default is for slave select to be enabled, so just using:
setup_spi(SPI_MODE_0 | SPI_SLAVE);
Should give slave operation with slave select, but some chips have the select as a separate option...
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 09, 2011 6:18 am |
|
|
My code is not working. Whats wrong with this?
Master
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
#define SSP_SS PIN_B5
#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)
float value1;
int b0,b1,b2,b3;
union convert
{
int data[4];
float number;
}
val;
void main()
{
output_high(SSP_SS);
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
while(1)
{
value1=12.34;//value which has to be sent
//break the floating value to seperate bytes and then send through SPI.
{
val.number=value1;
b0=val.data[3];
b1=val.data[2];
b2=val.data[1];
b3=val.data[0];
}
output_low(SSP_SS);
spi_write(b0);//sending first byte
output_high(SSP_SS);
delay_ms(1);//some delay
output_low(SSP_SS);
spi_write(b1);//sending 2nd byte
output_high(SSP_SS);
delay_ms(1);//some delay
output_low(SSP_SS);
spi_write(b2);//sending 3rd byte
output_high(SSP_SS);
delay_ms(1);//some delay
output_low(SSP_SS);
spi_write(b3);//sending 4th byte
output_high(SSP_SS);
delay_ms(1);//some delay
delay_ms(500);//after 0.5 sec repeat the process again.
}
}
|
Slave
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
#byte SSPBUF = 0xFC9//register value for 18f252
#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)
int data[4],x=0,flag=0;
float recive;
int32 data32;
union convert
{
int32 y;
float fval;
}
val;
#int_ssp
void ssp_isr(void)
{
data[x]=SSPBUF;
x++;
if(x>=4)
{
x=0;
flag=1;
}
}
void main()
{
setup_spi(SPI_SLAVE | SPI_MODE_0);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
if(flag==1)
{
data32=make32(data[0],data[1],data[2],data[3]);
//function for making int32 to float
val.y=data32;
recive=val.fval;
printf("%f\r\n",recive);//display the result.
flag=0;
}
}
}
|
|
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Sun Mar 13, 2011 10:54 pm |
|
|
I have modified the PCM programmer code for sending and receiving the data using spi but it is not working as well,
Master
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
#define SPI_SS PIN_B5
#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)
char c;
int result,counter;
void main()
{
output_high(SPI_SS);
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
while(1)
{
c=getc();
c=toupper(c);
switch(c)
{
case 'A':
output_low(SPI_SS);
spi_write(1);
output_high(SPI_SS);
delay_us(100);
output_low(SPI_SS);
result=spi_read(0);
output_high(SPI_SS);
printf("value =%u\r\n",result);
break;
case 'B':
output_low(SPI_SS);
spi_write(2);
output_high(SPI_SS);
delay_us(100);
output_low(SPI_SS);
result=spi_read(0);
output_high(SPI_SS);
printf("value =%u\r\n",result);
break;
case 'C':
output_low(SPI_SS);
spi_write(3);
output_high(SPI_SS);
delay_us(100);
output_low(SPI_SS);
result=spi_read(0);
output_high(SPI_SS);
printf("value =%u\r\n",result);
break;
}
}
}
|
Slave
Code: |
#include <18f252.h>
#fuses HS,NOWDT,NOLVP,PUT,NOBROWNOUT,protect
#use delay(clock=20000000)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=9600)
//#byte SSPBUF = 0xFC9//register value for 18f252
#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)
int counter;
int buffer;
#int_ssp
void ssp_isr(void)
{
buffer=spi_read();
int command;
command=SSPBUF;
switch(command)
{
case 1:
SSPBUF=5;
break;
case 2:
SSPBUF=46;
break;
case 3:
SSPBUF=12;
break;
}
counter++;
}
void main()
{
setup_spi(SPI_SLAVE | SPI_MODE_0);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
}
}
|
Where i am wrong. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 14, 2011 11:43 am |
|
|
I didn't really look at the code closely. Post a list of the connections
between the two PICs. There should be 4 wires for the SPI signals,
and a ground connection. Post the pin numbers on each PIC that
are connected to each other for the SPI. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Mon Mar 14, 2011 11:33 pm |
|
|
Quote: |
I didn't really look at the code closely. Post a list of the connections
between the two PICs. There should be 4 wires for the SPI signals,
and a ground connection. Post the pin numbers on each PIC that
are connected to each other for the SPI. |
I am using two 18f252 pic for spi communication
my connections are
SDI--->SDO
SDO--->SDI
SCK--->SCK
GND--->GND
For SS I am using PIN_A0 on both controller. Before I was using PIN_B5.
my compiler version is 4.093 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 15, 2011 12:26 am |
|
|
Quote: | For SS I am using PIN_A0 on both controller.
|
Download the 18F252 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/39564c.pdf
Look at the pin diagram for the 18F252. What pin is used for \SS
on a SPI Slave PIC ? Hint: It's not Pin A0.
On the SPI Master PIC, you can use pin A0 to drive the Slave Select
signal, because it's done by software, with output_low() and output_high()
functions. But for an SPI slave you must use the correct hardware \SS
pin on the Slave PIC. Read the data sheet to find the correct pin. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Mar 15, 2011 12:50 am |
|
|
PCM Programmer
Its pin #7 of 18f252. /SS
I have change the hardware from A0 to A5 on slave side, but I am not using that pin in the slave software, so will it work without declaring that pin? Is it necessary to change the pin of master from A0 to A5? |
|
|
|
|
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
|