![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
suresh53
Joined: 02 Aug 2016 Posts: 4
|
pic16f spi communication -master communicate with four slave |
Posted: Tue Aug 02, 2016 7:24 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Tue Aug 02, 2016 8:02 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
suresh53
Joined: 02 Aug 2016 Posts: 4
|
here i have attached master and slave code |
Posted: Wed Aug 03, 2016 5:10 am |
|
|
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);
}
}
} |
|
![](templates/subSilver/images/spacer.gif) |
suresh53
Joined: 02 Aug 2016 Posts: 4
|
about master and slave code |
Posted: Wed Aug 03, 2016 5:18 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Wed Aug 03, 2016 5:56 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Aug 03, 2016 6:40 am |
|
|
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'. |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Wed Aug 03, 2016 5:39 pm |
|
|
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!!!! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Wed Aug 03, 2016 6:09 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|