1
\$\begingroup\$

I am doing Single master multiple slave implementation.
Master - PIC18F4550
Slave - PIC18F4520

A potentiometer is connected to the Slave. Slave will convert the Potentiometer value to digital and communicate with the master using SPI protocol.

I am getting 8bit data (ADRESH -- Left justified)correctly from slave. But I have to get 10bit data (ADRESH - 8bit, ADRESL - 2bit).

How can I get 10bit data?

Master code

OpenSPI(SPI_FOSC_64, MODE_01, SMPMID);   //SPI configuration

SSPCON1bits.WCOL = 0;    //Clearing SSPBUF
LATDbits.LATD0 = 0;  //Slave select
WriteSPI(0xFF);  //writing 0xFF to slave    
for(mdelay = 0; mdelay < 10; mdelay++); 
var1 = SSPBUF;
LATDbits.LATD0 = 1;
highbyte = var1;
highbyte = highbyte << 8;    //deselecting SS   
for(mdelay = 0; mdelay < 100; mdelay++);

SSPCON1bits.WCOL = 0;
LATDbits.LATD0 = 0;  //2nd time slave selct 
WriteSPI(0xAA);
for(mdelay = 0; mdelay < 10; mdelay++); 
var2 = SSPBUF;
LATDbits.LATD0 = 1;
lowbyte = var2;
for(mdelay = 0; mdelay < 100; mdelay++);

highbyte = highbyte | lowbyte;
result = highbyte;

Slave

int Count;
unsigned char ch1,ch2,data; 

ADCON0 = 0x01;   // AD Control Register 1: Enable (turn on ADC)
ADCON2 = 0x3C;   // AD Control Register 2: 20 TAD (accuracy), FOSC 4 (freq/4)
ADCON2bits.ADFM = 0;     // ADC result left justified (D10 - D2 --> ADRESH, D1 - D0 --> ADRESL) 

TRISCbits.TRISC3 = 1;    //SPI pins(PIC18F4520)
TRISCbits.TRISC4 = 1;   
TRISCbits.TRISC5 = 0;
TRISAbits.TRISA5 = 1;

TRISDbits.TRISD0 = 0;    //Configuring PORTD as output
TRISDbits.TRISD1 = 0;
TRISDbits.TRISD2 = 0;
TRISDbits.TRISD3 = 0;
TRISDbits.TRISD4 = 0;
TRISDbits.TRISD5 = 0;
TRISDbits.TRISD6 = 0;
TRISDbits.TRISD7 = 0;   

SSPSTATbits.SMP = 0;     //Configuration of SPI register
SSPSTATbits.CKE = 0;
SSPCON1bits.CKP = 0;
SSPCON1bits.SSPM3 = 0;
SSPCON1bits.SSPM2 = 1;
SSPCON1bits.SSPM1 = 0;
SSPCON1bits.SSPM0 = 0;  
SSPCON1bits.SSPEN = 1;

while(1)
{   

ADCON0bits.CHS0 = 1;     //Selecting AN0 as analog input
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS3 = 0;
ADCON0bits.GO = 1;   //Start analog to digital conversion   
while (ADCON0bits.NOT_DONE);    
ch1 = ADRESL;   
ch2 = ADRESH;


data = SSPBUF;   //loading the SSPBUF value to some dummy varible(Previous data in SSPBUF)

//First time slave select
SSPCON1bits.WCOL = 0;    //Clearing SSPBUF register
while(PORTAbits.RA5 == 1);  //wait for slave select
SSPBUF = ch1;    //Loading ADRESH value to SSPBUF
while(SSPSTATbits.BF == 0); //wait untill the buffer is full

for(Count=0;Count<10;Count++);  //delay

//Second time slave selct
SSPCON1bits.WCOL = 0;    //Clearing SSPBUF register
while(PORTAbits.RA5 == 1);  //wait for slave select
SSPBUF = ch2;    //Loading ADRESL value to SSPBUF
while(SSPSTATbits.BF == 0); //wait untill the buffer is full

for(Count=0;Count<10;Count++);  //delay
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There are a few things that look suspicious to me. On the master side, I would introduce a small delay between setting the slave select signal and sending the dummy data (to start the transfer), though this may not be a problem. The other things that's suspicious is that in your slave code you first have ...

ch1 = ADRESL;   
ch2 = ADRESH;

but then

SSPBUF = ch1;    //Loading ADRESH value to SSPBUF
...
SSPBUF = ch2;    //Loading ADRESL value to SSPBUF

So, according to your comments and to the code the master expects, you expect to get the high byte first, then the low byte, but the slave actually sends ADRESL first, then ADRESH.

Lastly, after the first byte transfer you introduce a long(er) delay (mdelay<100) before deselecting SS on the master. On the slave side, there is only a short delay, then you wait for the SS to be set again, which most likely is still set based on the long delay by the master. You then set the second data byte and wait for the BF bit to be set. I'm not familiar with the PIC18F4550, so I don't know if this is an issue, but since you never explicitly clear the BF bit, it might still be set from the first round, which would then cause your slave to restart the main loop (after another short delay).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.