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 CCS Technical Support

pic16f spi communication -master communicate with four slave

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



Joined: 02 Aug 2016
Posts: 4

View user's profile Send private message

pic16f spi communication -master communicate with four slave
PostPosted: Tue Aug 02, 2016 7:24 am     Reply with quote

i have faced a problem in spi communication that master didnot read correct data from slave.
i used internal oscillator (32Mhz) both master and slave.
in slave side slave count external pulses by using timer0 and timer1 as a counter.
while using the spi interrupt the master didnot read correct data from slave,and slave also didnot count the external pulses.


any one please suggest to rectify this problem.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Aug 02, 2016 8:02 am     Reply with quote

you NEED to POST YOUR CODE ! A small, compilable example of what you're doing. Without knowing which PIC, which compiler and what code you're using , we have NO idea where the problem is. My XTAL ball is fuzzy.

Now your subject line says 4 slaves, so do you have FOUR slave select lines ? A schematic would be very.very helpful. Use a 3rd party site to post it.

Jay
suresh53



Joined: 02 Aug 2016
Posts: 4

View user's profile Send private message

here i have attached master and slave code
PostPosted: Wed Aug 03, 2016 5:10 am     Reply with quote

Master code:


#include<16F1936.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#FUSES NOWDT,HS
#FUSES NOBROWNOUT
#FUSES NOLVP
#use delay(internal=32000000)
#use rs232(baud=19200,parity=N,uart1,bits=8,STOP=1)

// SPI mode definitions.
#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)
#byte SSPBUF=0x211
#byte RCREG=0x199
#bit RCIF=0x11.5
#bit peie=0x0B.6
#bit SSPIF=0x11.3
#bit BF=0x214.0
#bit sw=0x0D.5
#bit SS_U1=0x0D.4
#bit SS_U39=0x0D.3
#bit SS_U2=0x0D.2
#bit SS_U38=0x0D.1
static unsigned char h[4],d[12],e[42]={0},y[42]={0},y1[42]={0},y3[42]={0};
unsigned int8 i,j,k,l,l1,l2;
unsigned char b[12]="AB678901234C";
#define length 6

//unsigned char j=0;
//unsigned char r[15];
void main()
{
//unsigned char d;
//unsigned char b='1';
unsigned char c='2';
unsigned char c1='3';
unsigned char c2='4';
set_tris_b(0x20);
set_tris_c(0x80);
// spi_speed (250000);
SS_U2=1;
SS_U1=1;
SS_U39=1;
SS_U38=1;
setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_16);
while(1)
{

SS_U2=1;
delay_ms(100);
SS_U2=0;
BF=0;
//delay_ms(300);
for(j=0;j<14;j++)
{
e[j]=spi_read(0);
printf("%c",e[j]);
}
printf("\n");
//delay_ms(300);
SS_U2=1;
delay_ms(100);


SS_U1=0;
BF=0;
//delay_ms(300);
for(k=0;k<14;k++)
{
y[k]=spi_read(0);
printf("%c",y[k]);
}
printf("\n");
//delay_ms(300);
SS_U1=1;
delay_ms(100);

SS_U38=0;
BF=0;
//delay_ms(300);
for(l1=0;l1<14;l1++)
{
y1[l1]=spi_read(0);
printf("%c",y1[l1]);
}
printf("\n");
//delay_ms(300);
SS_U38=1;
delay_ms(100);

SS_U39=0;
BF=0;
//delay_ms(300);
for(l2=0;l2<14;l2++)
{
y3[l2]=spi_read(0);
printf("%c",y3[l2]);
}
printf("\n");
//delay_ms(300);
SS_U39=1;
delay_ms(100);
}
}







SLAVE code:



#include<16F1936.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#FUSES NOWDT,HS
#FUSES NOBROWNOUT
#FUSES NOLVP
#use delay(internal=32000000)

// SPI mode definitions.
#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)
#byte SSPBUF=0x211
#byte RCREG=0x199
#bit BF=0x214.0
#bit RCIF=0x11.5
#bit peie=0x0B.6
#bit SSPIF=0x11.3
#define ERR_cmd "B"

#INT_TIMER2
void TIMER2_isr(void)
{
c2=get_timer0();
c3+=c2;
set_timer0(0);
}

void main()
{

set_tris_A(0x10);
set_tris_C(0x01);
setup_lcd(LCD_DISABLED);
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1|RTCC_8_bit); //32.0 us overflow
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_16,35,1);
set_timer0(0);
set_timer1(0);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
setup_spi(SPI_SLAVE | SPI_MODE_1);
while(TRUE)
{
count1=get_timer1();
delay_ms(50);
c1=count1;
sprintf(d2data,"s%s%06lues%s%06lue",cmd,c1,cmd1,c3);
printf("%s",d2data);
for(int8 j=0;j<18;j++)
{
spi_write(d2data[j]);
BF=0;
//delay_ms(10);
}
}
}
suresh53



Joined: 02 Aug 2016
Posts: 4

View user's profile Send private message

about master and slave code
PostPosted: Wed Aug 03, 2016 5:18 am     Reply with quote

please suggest how do read the master write data in slave side by using interrupt method.

and also pls suggest to transfer the data from slave to master in interrupt method.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Aug 03, 2016 5:56 am     Reply with quote

couple of points...

1) use the 'code' button just before and after pasting your code. That way the code will look like code!

2) in CCS C 'char' IS an unsigned 8 bit variable ( 0-255) so you can delete the unsigned char to char.

3) CCS may have examples in the examples folder, though I haven't checked.

4) probably the most important. COMMENT your code! While you know what is supposed to happen, what variables are for, etc. others don't. By adding comments at the end of important lines anyone can follow what you're doing(or trying to do). Also INDENT your code,ie. in for-next operations, makes it easier to read.

the easier it is for others to read, the quicker the replies !!


Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19545

View user's profile Send private message

PostPosted: Wed Aug 03, 2016 6:40 am     Reply with quote

Also you need to understand SPI.

In SPI, the master always writes. To read a byte, it writes a dummy byte 'out' and gets the byte back from the slave as a reply. You can't use INT_SPI in the master, since it is always what is triggering the transfer.

Then you were asked about 'slave select', but I see no sign of this being used.
You set select bits from the master, but the slave code does not have the slave select enabled in the SPI setup....
It is needed. If this is not used, all the SDO lines from the four devices will be trying to drive at the same time, and shorting each other out....
The point about the SS input is that it both synchronises the transfer (resets the incoming shift register in the slave), and controls the output enable on the SDO line.

Then there is a problem of 'time'. The slave has to load a byte _before_ the master requests it.

You need to actually design a protocol.
I did one years ago using SPI, and based it on the 25AA040 EEPROM. On this you send the first instruction to the slave, specifying whether the following transfer is going to be a 'read' or a 'write'. Then the 'address' byte saying where you want to transfer to/from. Then if you have specified 'read', you pause for long enough for the slave to load the first byte into it's buffer, and start sending dummy bytes and reading the replies.

Repeat the comment about 'comments'.
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Wed Aug 03, 2016 5:39 pm     Reply with quote

Another bit of information. The FUSES can all be on the same line and they
must come right after the processor include line. Then USE RS232 then
your other includes like this.
Code:

#include<16F1936.h>
#FUSES NOWDT,HS, NOBROWNOUT, NOLVP
#use delay(internal=32000000)
#use rs232(baud=19200,parity=N,uart1,bits=8,STOP=1)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

To simplify things further, 8N1 is the RS232 default and you should always
add the errors keyword when you use hardware RS232 UARTs so that
line can be brought down to:
Code:
#use rs232(baud=19200, uart1, ERRORS)

_________________
Google and Forum Search are some of your best tools!!!!
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Aug 03, 2016 6:09 pm     Reply with quote

re: The FUSES can all be on the same line

hahaha,lol, that's rich....
well I suppose for the smaller PICs that's true but for the 'big boy PICs' like the 46k22, I've had to create an 'include file' just for the fuses. it's the only way I can be SURE the correct fuses are used. Sometimes the 'default' set by the 'coder of the day' sets the wrong ones for my applications.
I also have a 'base template' of all fuses that does the 1Hz LED/ 'hello world' programs, just to be SURE the PIC runs correctly.

Yeah, getting old...I like to see everything, just to be sure !!


Jay
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