Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

SPI Serial Clock Problem with PIC18F4550

Status
Not open for further replies.

Cekobidonq

Newbie level 3
Joined
Nov 20, 2012
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,302
SPI read Problem with PIC18F4550

Hello all,

I'm having a problem with the SPI interface on a PIC18F4550. I am trying to read data from a 24-bit A/D converter (ADS1271IPWG4). I have set up the SSPCON1 and SSPSTAT registers and I am sending a byte through the SDO pin to the ADC to produce the clock signal on pin SCK that will synchronize the data transfer. When I measure the waveform on pin SDI of the PIC, I get well synched serial data, but when I try to read the SSPBUF register I get nothing. My code is the following:

Code:
void main() {
short sample, buffer;
TRISA=0x00;
TRISB=0x01;
TRISC=0x00;
while(1)
{
 SSPCON1=0b00100010;
 PORTA.B5=0;
 SSPCON1.WCOL=0;
 SSPSTAT.BF=0;
 delay_us(10);
 SSPBUF=0xff;
 if(SSPSTAT.BF)
 {
  sample=SSPBUF;
  SSPSTAT.BF=0;
  SSPCON1.WCOL=0;
 }
  delay_us(500);
  PORTC=sample;

}
}
I am using MikroC Pro compiler. I also tried using the SPI1_Read function from the compiler's library, but with the same result.
If you have any idea what I'm doing wrong, please reply.

Best regards,
Tsvetan
 
Last edited:

Cekobidonq

Newbie level 3
Joined
Nov 20, 2012
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,302
Never mind... I fixed it. Apparently I needed to actually send data to the SSPBUF in order to generate the serial clock signal. And then for the correct synchronization I just used the READY signal from my ADC. I'm posting my working code so if anyone is having the same problems they can find a solution.

Code:
void main() {
short sample[3];  //sample is the matrix where I save the 3 bytes of data.
TRISA=0x00;       //Make sure to initialize the pins you use for the SPI as inputs or
TRISB=0b00000101; //outputs according to the datasheet instructions. (In my case only
TRISC=0x00;       //pin SDI(pin 33 of DIP40 package) is an input).
ADCON1=0x0F;      //Set the A/D control register so that your SDI input is a digital input.
SSPCON1=0b00100010;  //Initialize SPI with clock=Fosc/64, idle state low, no collision, no overflow.
UCON=0x00;           //Disable USB. This is just for my experimentation.
 PORTB.B3=0;         //Provide a low synch pulse to the SYNCH pin of the ADC.
 delay_us(10);       //Synch pulse width must be at least 1 clock period (10 in this case).
 PORTB.B3=1;         //Keep the SYNCH pin high when not pulsing. If it is low for 2^19 clock periods the ADC will enter Power-Down mode.
 while(1)            //Endless loop.
 {
 PORTA.B5=0;
 SSPCON1.WCOL=0;     //Clear the collision
 SSPSTAT.BF=0;       //and Buffer Full control bits.
 delay_us(10);
 while(PORTB.B2!=0);  //Wait until conversion is complete and ADC gives the READY signal (active low).
 SSPBUF=0xff;         //Write any random data to SSPBUF. This will generate the Serial Clock (SCK) signal and shift the registers of the ADC. Then data will be sent from the ADC to the SSPBUF register.
 while(!SSPSTAT.BF);  //Wait until the ADC responds and fills the SSPBUF with data. When SSPBUF is full the Buffer Full flag (SSPSTAT.BF) will be set.
 sample[0]=SSPBUF;    //Save the byte to the first matrix variable. MSB is transfered first.
 SSPSTAT.BF=0;        //Clear the Buffer Full flag.
 SSPBUF=0xff;         //Send the second byte of dummy data.
 while(!SSPSTAT.BF);  //Wait again for the flag.
 sample[1]=SSPBUF;    //Save second byte.
 SSPSTAT.BF=0;        //Clear flag.
 SSPBUF=0xff;         //Do the
 while(!SSPSTAT.BF);  //same
 sample[2]=SSPBUF;    //for
 SSPSTAT.BF=0;        //the third one.
 SSPCON1.WCOL=0;      //Clear the collision flag.
 //delay_us(500);
 PORTC=(sample[0])>>1;  //I used this to output the MSB on the 6th pin of PORTC. Using a pot I changed the analog input to the ADC.
 }                      //The MSB goes from low to high at 2.5V, which is half of the 5V span. This indicates that the PIC is reading the samples correctly.
}
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top