• AVR Freaks

Hot!SPI SCK doesn't seem to outputting anything, problem with my setup?

Author
ThisCatOrThatOne
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/07/15 15:20:43
  • Location: 0
  • Status: offline
2019/07/17 08:37:49 (permalink)
0

SPI SCK doesn't seem to outputting anything, problem with my setup?

I am using PIC24FJ64GA002. Trying to setup SPI communication with an external ADC, MAX11202 (required that it be external for school project). My code compiles and flashes to PIC just fine, but using an oscilloscope I am unable to measure the SCK signal from the PIC. I have scoured various forums and example codes and I am not sure what is wrong with my code. Going through each of the registers, I'm pretty sure my bit setup is correct. I made sure to set the pins to digital, set pin functions in PPS, and set appropriate TRIS direction for the 2 SPI pins I'm using. In the same code I am also communicating serially with an I2C display, so I am wondering if they are interfering with each other somehow?? In any case, I think I should still be able to read SCK on oscilloscope, right?
 
Any help appreciated, thank you! 
 
EDIT: PLEASE SEE UPDATED POST BELOW
 
Code below, with some irrelevant functions removed:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xc.h"
#include "math.h"
//#include "lab5_headerFile_v001.h"
// CW1: FLASH CONFIGURATION WORD 1 (see PIC24 Family Reference Manual 24.1)
#pragma config ICS = PGx1 // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog Timer is disabled)
#pragma config GWRP = OFF // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG port is disabled)
// CW2: FLASH CONFIGURATION WORD 2 (see PIC24 Family Reference Manual 24.1)
#pragma config I2C1SEL = PRI // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = OFF // IOLOCK Protection (IOLOCK may be changed via unlocking seq)
#pragma config OSCIOFNC = ON // Primary Oscillator I/O Function (CLKO/RC15 functions as I/O pin)
#pragma config FCKSM = CSECME // Clock Switching and Monitor (Clock switching is enabled,
// Fail-Safe Clock Monitor is enabled)
#pragma config FNOSC = FRCPLL // Oscillator Select (Fast RC Oscillator with PLL module (FRCPLL))
/*
*
*/


void setup (void){
CLKDIVbits.RCDIV = 0; //16MHz
AD1PCFG = 0x9fff; //set all pins digital
//PIN direction setup
// Unlock Registers
__builtin_write_OSCCONL(OSCCON & 0xBF);
 
// Configure Input Functions (Table 10-2))
// Assign SDI1 To Pin RP5
RPINR20bits.SDI1R = 5;
 
// Configure Output Functions (Table 10-3)
// Assign Assign SCK 1 OUT To Pin RP4
RPOR2bits.RP4R = 8;
 
// Lock Registers
__builtin_write_OSCCONL(OSCCON | 0x40);
 
// SET TRIS BITS for inputs and outputs 
TRISBbits.TRISB4=0; //makes RP4/RB4 output pin (SCK1 for SPI)
TRISBbits.TRISB5=1; //makes RP5/RB5 input pin (SDI1 for SPI)
//Display Setup
//IFS3bits.MI2C2IF = 0; //What is this for?? Interrupt Flag??
I2C2BRG = 157;
//SPI Setup
SPI1CON1=0x00; //stops SPI1 and clears register
SPI1CON2=0x00; //stops SPI1 and clears register
_SDI1R=5; //set SDI1 to RP5
_SCK1R=4; //set SCK1 to RP4
SPI1STATbits.SPISIDL=0; //module operation continues during idle
SPI1CON1bits.DISSCK=0; //SPI 1 clock enabled
SPI1CON1bits.DISSDO=1; //SDO pin disabled
SPI1CON1bits.MODE16=1; //communication is word-byte
SPI1CON1bits.SMP=1; //input data sampled at end of data output time
SPI1CON1bits.CKE=1; //Serial output data changes on transition from active clock state to Idle clock state
SPI1CON1bits.SSEN=0; //SS 1 pin not used
SPI1CON1bits.CKP=0; //Idle state for clock is a low level; active state is a high level
SPI1CON1bits.MSTEN=1; //Master mode enabled
SPI1CON1bits.SPRE2=1;
SPI1CON1bits.SPRE1=0;
SPI1CON1bits.SPRE0=0;
//Above 3 bits set secondary prescalar to 4:1
SPI1CON1bits.PPRE1=1;
SPI1CON1bits.PPRE0=0;
//Above 2 bits set primary prescalar to 4:1
//Both prescalars set to 4:1 paired with 16MHz gives 1MHz on SCK 1 pin
SPI1CON2bits.FRMEN=0; //Framed support disabled
SPI1CON2bits.SPIFSD=0; //Framed support disabled
SPI1CON2bits.SPIFPOL=0; //Framed support disabled
SPI1CON2bits.SPIFE=0; //Framed support disabled
//TMR1 Setup
T1CON=0x00; //stop TMR1 and clear register
TMR1=0x00; //clear contents of TMR1
T1CONbits.TSIDL=0; //module operation continues during idle
T1CONbits.TGATE=0; //gated time accumulation disabled
T1CONbits.TCKPS1=1;
T1CONbits.TCKPS0=0; //above 2 bits set prescalar to 1:64
//1:64 will increment TMR1 every 4ms (62.5ns*64=4000ns=4ms)
T1CONbits.TCS=0; //TMR 1 sourced from internal clock
//ENABLE SPI and TMR and Display after SETUP
T1CONbits.TON=1; //enables TMR 1
SPI1STATbits.SPIEN=1; //enables SPI 1 Ports
I2C2CONbits.I2CEN = 1; //Enable
}


int main(void) {
setup();
while (1){
if (SPI1STATbits.SPIRBF==1)
CurrentValue=SPI1BUF;
}
return (1);
}
 

post edited by ThisCatOrThatOne - 2019/07/19 07:56:10
#1
ric
Super Member
  • Total Posts : 23859
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/18 21:10:45 (permalink)
0
SCLK only toggles while a transfer is taking place.
SPI is an exchange protocol,where you write and read simultaneously.
The only way for the Master to trigger a transfer is by writing data to SSPBUF.
You never do, so no transfer ever takes place. You MUST write dummy data to trigger transfers.
Have another read of the SPI chapter in your PIC's datasheet.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
BobAGI
Super Member
  • Total Posts : 1724
  • Reward points : 0
  • Joined: 2011/03/09 00:04:35
  • Location: Texas and Sweden
  • Status: offline
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/19 07:02:54 (permalink)
0
When you post with code included, please make it readable by adding code tags around the code.
A code tag is a square bracket followed by the word code and the opposite square bracket. At the end you place the same except with a / before the word code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xc.h"
#include "math.h"
//#include "lab5_headerFile_v001.h"
// CW1: FLASH CONFIGURATION WORD 1 (see PIC24 Family Reference Manual 24.1)
#pragma config ICS = PGx1 // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog Timer is disabled)
#pragma config GWRP = OFF // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG port is disabled)
// CW2: FLASH CONFIGURATION WORD 2 (see PIC24 Family Reference Manual 24.1)
#pragma config I2C1SEL = PRI // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = OFF // IOLOCK Protection (IOLOCK may be changed via unlocking seq)
#pragma config OSCIOFNC = ON // Primary Oscillator I/O Function (CLKO/RC15 functions as I/O pin)
#pragma config FCKSM = CSECME // Clock Switching and Monitor (Clock switching is enabled,
// Fail-Safe Clock Monitor is enabled)
#pragma config FNOSC = FRCPLL // Oscillator Select (Fast RC Oscillator with PLL module (FRCPLL))
/*
*
*/


void setup (void){
CLKDIVbits.RCDIV = 0; //16MHz
AD1PCFG = 0x9fff; //set all pins digital
//PIN direction setup
// Unlock Registers
__builtin_write_OSCCONL(OSCCON & 0xBF);
 
// Configure Input Functions (Table 10-2))
// Assign SDI1 To Pin RP5
RPINR20bits.SDI1R = 5;
 
// Configure Output Functions (Table 10-3)
// Assign Assign SCK 1 OUT To Pin RP4
RPOR2bits.RP4R = 8;
 
// Lock Registers
__builtin_write_OSCCONL(OSCCON | 0x40);
 
// SET TRIS BITS for inputs and outputs 
TRISBbits.TRISB4=0; //makes RP4/RB4 output pin (SCK1 for SPI)
TRISBbits.TRISB5=1; //makes RP5/RB5 input pin (SDI1 for SPI)
//Display Setup
//IFS3bits.MI2C2IF = 0; //What is this for?? Interrupt Flag??
I2C2BRG = 157;
//SPI Setup
SPI1CON1=0x00; //stops SPI1 and clears register
SPI1CON2=0x00; //stops SPI1 and clears register
_SDI1R=5; //set SDI1 to RP5
_SCK1R=4; //set SCK1 to RP4
SPI1STATbits.SPISIDL=0; //module operation continues during idle
SPI1CON1bits.DISSCK=0; //SPI 1 clock enabled
SPI1CON1bits.DISSDO=1; //SDO pin disabled
SPI1CON1bits.MODE16=1; //communication is word-byte
SPI1CON1bits.SMP=1; //input data sampled at end of data output time
SPI1CON1bits.CKE=1; //Serial output data changes on transition from active clock state to Idle clock state
SPI1CON1bits.SSEN=0; //SS 1 pin not used
SPI1CON1bits.CKP=0; //Idle state for clock is a low level; active state is a high level
SPI1CON1bits.MSTEN=1; //Master mode enabled
SPI1CON1bits.SPRE2=1;
SPI1CON1bits.SPRE1=0;
SPI1CON1bits.SPRE0=0;
//Above 3 bits set secondary prescalar to 4:1
SPI1CON1bits.PPRE1=1;
SPI1CON1bits.PPRE0=0;
//Above 2 bits set primary prescalar to 4:1
//Both prescalars set to 4:1 paired with 16MHz gives 1MHz on SCK 1 pin
SPI1CON2bits.FRMEN=0; //Framed support disabled
SPI1CON2bits.SPIFSD=0; //Framed support disabled
SPI1CON2bits.SPIFPOL=0; //Framed support disabled
SPI1CON2bits.SPIFE=0; //Framed support disabled
//TMR1 Setup
T1CON=0x00; //stop TMR1 and clear register
TMR1=0x00; //clear contents of TMR1
T1CONbits.TSIDL=0; //module operation continues during idle
T1CONbits.TGATE=0; //gated time accumulation disabled
T1CONbits.TCKPS1=1;
T1CONbits.TCKPS0=0; //above 2 bits set prescalar to 1:64
//1:64 will increment TMR1 every 4ms (62.5ns*64=4000ns=4ms)
T1CONbits.TCS=0; //TMR 1 sourced from internal clock
//ENABLE SPI and TMR and Display after SETUP
T1CONbits.TON=1; //enables TMR 1
SPI1STATbits.SPIEN=1; //enables SPI 1 Ports
I2C2CONbits.I2CEN = 1; //Enable
}


int main(void) {
setup();
while (1){
if (SPI1STATbits.SPIRBF==1)
CurrentValue=SPI1BUF;
}
return (1);
}


--
Bo B
Sweden & Texas
 
#3
ThisCatOrThatOne
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/07/15 15:20:43
  • Location: 0
  • Status: offline
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/19 07:51:03 (permalink)
0
Thanks, Bo! I will do that next time. 
 
In the time it took to approve this post (which was kind of a long time I felt?) I figured it out. My working code is shown below. With this code, I can verify that SCK is working at 1MHz via oscilloscope and I can read the values of CurrentValue (where I'm storing the ADC data). 
 
My new issue is that CurrentValue seems to be changing all the time, even when the voltage to the ADC is constant. I suspect that there is a buffer size mismatch in that the ADC's buffer is 24bits and the PIC's SPI1BUF is less than that, probably 8 or 16bits (I think 16 but not sure). So, when the PIC is reading in data to SPI1BUF, it is only reading in part of the ADC's value and then stopping. I think then, on the next read cycle, the PIC is reading in the rest of the bits that were left over from the previous read cycle. This would make it appear like the values are random, when really they are just random parts of the same number spliced together. Does that make sense? Can anyone confirm or disprove this? If that's true, how would I go about making the 2 compatible? If it helps, I really only care about the most significant 16 bits from the ADC, so if the least significant ones get trashed that would be ok with me. Thanks!
 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xc.h"
#include "math.h"
//#include "lab5_headerFile_v001.h"
// CW1: FLASH CONFIGURATION WORD 1 (see PIC24 Family Reference Manual 24.1)
#pragma config ICS = PGx1 // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog Timer is disabled)
#pragma config GWRP = OFF // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG port is disabled)
// CW2: FLASH CONFIGURATION WORD 2 (see PIC24 Family Reference Manual 24.1)
#pragma config I2C1SEL = PRI // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = OFF // IOLOCK Protection (IOLOCK may be changed via unlocking seq)
#pragma config OSCIOFNC = ON // Primary Oscillator I/O Function (CLKO/RC15 functions as I/O pin)
#pragma config FCKSM = CSECME // Clock Switching and Monitor (Clock switching is enabled,
// Fail-Safe Clock Monitor is enabled)
#pragma config FNOSC = FRCPLL // Oscillator Select (Fast RC Oscillator with PLL module (FRCPLL))
/*
*
*/
/*
void setup (void){
SPI1STAT=0;//clears/disables SPI
SPI1CON1=0; //stops SPI1 and clears register
SPI1CON2=0; //stops SPI1 and clears register
CLKDIVbits.RCDIV = 0; //16MHz
AD1PCFG = 0x9fff; //set all pins digital

//PIN direction setup
TRISBbits.TRISB4=0; //makes RP4/RB4 output pin (SCK1 for SPI)
TRISBbits.TRISB5=1; //makes RP5/RB5 input pin (SDI1 for SPI)
TRISBbits.TRISB2=0; //makes RP2 output
__builtin_write_OSCCONL(OSCCON & 0xBF); //Unlock PPS
RPINR20bits.SDI1R = 5; //SDI1 RB5 (SPI input)
RPOR2bits.RP4R = 8; //SCK1 RB4 (SPI Clock output)
RPOR1bits.RP2R = 7;//SDO on RP2
__builtin_write_OSCCONL(OSCCON | 0x40); //Lock PPS

//SPI Setup
SPI1CON1=0x00; //stops SPI1 and clears register
SPI1CON2=0x00; //stops SPI1 and clears register
SPI1CON1bits.DISSCK=0; //SPI 1 clock enabled
SPI1CON1bits.DISSDO=0;//SDO pin enabled
SPI1CON1bits.MODE16=1; //communication is word (16 bits)
SPI1CON1bits.SMP=1; //input data sampled at end of data output time
SPI1CON1bits.CKE=1; //Serial output data changes on transition from active clock state to Idle clock state
SPI1CON1bits.SSEN=0; //SS 1 pin not used
SPI1CON1bits.CKP=0; //Idle state for clock is a low level; active state is a high level
SPI1CON1bits.MSTEN=1; //Master mode enabled
SPI1CON1bits.SPRE2=1;
SPI1CON1bits.SPRE1=0;
SPI1CON1bits.SPRE0=0;
//Above 3 bits set secondary prescalar to 4:1
SPI1CON1bits.PPRE1=1;
SPI1CON1bits.PPRE0=0;
//Above 2 bits set primary prescalar to 4:1
//Both prescalars set to 4:1 paired with 16MHz gives 1MHz on SCK 1 pin
SPI1CON2bits.FRMEN=0; //Framed support disabled
SPI1CON2bits.SPIFSD=0; //Framed support disabled
SPI1CON2bits.SPIFPOL=0; //Framed support disabled
SPI1CON2bits.SPIFE=0; //Framed support disabled
SPI1STAT=0; //clear status register
SPI1STATbits.SPISIDL=0; //continues in idle mode
//Enable SPI 1
SPI1STATbits.SPIEN=1;
_SPI1IF = 0;
}
void delay(int ms)
{
//TMR2 Setup
T2CON=0; //Clear TMR2 and stop
PR2=15999; //PRE setup
TMR2=0; //clear TMR2 value
IFS0bits.T2IF=0; //Clear T2 interrupt flag
T2CON=0x8000; //T2 on w/PRE 1:1
//actual delay code
while (ms>0) {
while (!_T2IF);
_T2IF=0;
ms--;
}
return;
}
int spi1_xfer(int data)
{
SPI1BUF = data;//write dummy value of 0
while (SPI1STATbits.SPIRBF==0);//wait for "read buffer full" bit to set
return SPI1BUF;//ADC data
}

int main (void){
setup();
int CurrentValue=1;
while (1){
CurrentValue=spi1_xfer(0);//get ADC value
delay(100);//ADC data conversion time is 73ms
}
return 1;
}

post edited by ThisCatOrThatOne - 2019/07/19 07:53:19
#4
LdB_ECM
Senior Member
  • Total Posts : 148
  • Reward points : 0
  • Joined: 2019/04/16 22:01:25
  • Location: 0
  • Status: offline
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/19 07:52:14 (permalink)
0
Say what ... make up your mind which way the clock is going :-)
 
// Assign Assign SCK 1 OUT To Pin RP4
RPOR2bits.RP4R = 8;
 _SCK1R=4; //set SCK1 to RP4 as INPUT!!!!

 
I am guessing the last becomes true so you have SCK1 set as input clock hence no data
post edited by LdB_ECM - 2019/07/19 07:54:16
#5
ThisCatOrThatOne
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/07/15 15:20:43
  • Location: 0
  • Status: offline
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/19 07:55:01 (permalink)
0
@LdB_ECM, thanks, please see my updated code. 
post edited by ThisCatOrThatOne - 2019/07/19 07:56:52
#6
LdB_ECM
Senior Member
  • Total Posts : 148
  • Reward points : 0
  • Joined: 2019/04/16 22:01:25
  • Location: 0
  • Status: offline
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/19 19:01:09 (permalink)
0
Generally you will have that issue if you have the SPI clocking on the wrong edge to the device
 
So check you device datasheet and check your CKP and CKE setting
// CKP .. 1 = clock high at idle, 0 = clock low at idle
// CKE .. 1 = data on active to idle 0 = data on idle to active
#7
Aussie Susan
Super Member
  • Total Posts : 3618
  • Reward points : 0
  • Joined: 2008/08/18 22:20:40
  • Location: Melbourne, Australia
  • Status: offline
Re: SPI SCK doesn't seem to outputting anything, problem with my setup? 2019/07/21 19:10:12 (permalink)
4 (1)
LdB_ECM
Say what ... make up your mind which way the clock is going :-)
 

// Assign Assign SCK 1 OUT To Pin RP4
RPOR2bits.RP4R = 8;
 _SCK1R=4; //set SCK1 to RP4 as INPUT!!!!


Actually that is probably correct.
When an SPI module uses PPS, you often need to connect the SCK as both input and output to the pin.
If you don't then the Rx side does not get the SCK signal.
This was an undocumented issue with some of the early MCUs (and not all of them) but the more recent documents now mention this.
Susan
#8
Jump to:
© 2019 APG vNext Commercial Version 4.5