Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics 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.

[PIC] SPI communication problem between PIC18 & STM32F4 Discovery

Status
Not open for further replies.

flukeco

Junior Member level 1
Joined
Apr 25, 2014
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
180
Hi,

I've successfully implement SPI communication between STM32F4 Discovery (as master) and PIC18F2580 (as slave). Everything works fine, clock signal is sent from STM32F4, MOSI and MISO data are correct.

However, when I tried the opposite configuration (PIC18F2580 as master and STM32F4 as slave), no clock signal is sent from PIC's SCK pin (SCK always at high, I confirmed this using logic analyzer).

What do you guys think could be the source of this problem?
Does the CPU speed has effect on this (PIC has slower CPU speed than STM32F4 board)?

Any suggestions will be highly appreciated.

Best Regards,
Pat
 

I've successfully implement SPI communication between STM32F4 Discovery (as master) and PIC18F2580 (as slave). Everything works fine, clock signal is sent from STM32F4, MOSI and MISO data are correct.

However, when I tried the opposite configuration (PIC18F2580 as master and STM32F4 as slave), no clock signal is sent from PIC's SCK pin (SCK always at high, I confirmed this using logic analyzer).

Post or upload your code, particularly the segment configuring the PIC18F2580 SPI port as master.

Have you attempted to use the PIC18F2580's SPI port to communicate as the master with a standard peripheral device, serial EPROM, RTC, etc?

As the SPI port of the PIC18F2580 is typically configured to be the master, the lack of a clock is most likely a configuration or hardware connection issue.

BigDog
 

Re: SPI communication problem between PIC18 & STM32F4 Discovery

bigdogguru, Thank you very much for your response.

Here is the PIC18F2580 SPI configuration code. I call my SPI_init() function passing _MASTER_MODE as an argument:

Code:
/* SMP: Sample bit
 * SPI Master mode:
 *      1 = Input data sampled at end of data output time
 *      0 = Input data sampled at middle of data output time
 * SPI Slave mode:
 *      SMP must be cleared in slave mode
 */
#define _SMP            0

/* CKE: SPI Clock Select bit
 *      1 = Transmit occurs on transition from active to idle clock state
 *      0 = Transmit occurs on transition from idle to active clock state
 */
#define _CKE            0

/* CKP: Clock Polarity Select bit
 *      1 = Idle state for clock is a high level
 *      0 = Idle state for clock is a low level
 */
#define _CKP            1

/* Synchronous Serial Port Mode Select bits
 *      0101 = Slave mode, clock = SCK pin, SS pin disabled (can be used as I/O pin)
 *      0100 = Slave mode, clock = SCK pin, SS pin enabled
 *      0011 = Master mode, clock = TMR2 output/2
 *      0010 = Master mode, clock = Fosc/64
 *      0001 = Master mode, clock = Fosc/16
 *      0000 = Master mode, clock = Fosc/4
 */
#define _SSPM_MASTER    0b0000
#define _SSPM_SLAVE     0b0101

void SPI_init(unsigned char mode) {
    TRISA = 0x00;               /* set all port A pins as output pins */
    ADCON1 = 0x0F;              /* set all port A pins, including SS (RA5), as digital I/O */

    if (mode == _MASTER_MODE) {
    TRISC = 0b00010000;         /* Set SCK pin (RC3) as output
                                 * SDI pin (RC4) as input
                                 * SDO pin (RC5) as output */
    } else {
    TRISC = 0b00011000;         /* Set SCK pin (RC3) as input
                                 * SDI pin (RC4) as input
                                 * SDO pin (RC5) as output */
    }

    SSPSTAT = 0b00000000;       /* Initialize SSPSTAT register to POR state */
    SSPSTATbits.SMP = _SMP;     /* Configure sample bit */
    SSPSTATbits.CKE = _CKE;     /* Configure clock select bit */

    SSPCON1 = 0b00000000;       /* Initialize SSPCON1 register to POR state */
    SSPCON1bits.CKP = _CKP;     /* Configure clock polarity select bit */
    SSPCON1bits.SSPEN = 1;      /* Enable SPI (set SCK, SDO, SDI, and SS as serial port pins)*/

    if (mode == _MASTER_MODE)
        SSPCON1bits.SSPM = _SSPM_MASTER;    /* Configure sync mode bits for master */
    else
        SSPCON1bits.SSPM = _SSPM_SLAVE;     /* Configure sync mode bits for slave */
}

As of attempt to communicate with another device, I've successfully using this exact same code to make SPI communication between two PIC18F2580 (one as master, another as slave).

Best Regards,
Pat

- - - Updated - - -

Here is the SPI init function for the STM32F4. I only change one line (assign "SPI_Mode_Master" and "SPI_Mode_Slave" to "SPI_InitStruct.SPI_Mode") to configure STM32F4 as master and slave respectively).

As I mentioned earlier, this code along with PIC code I've posted above works when configure STM32F4 as master and PIC as slave, but not the opposite.

If you spot something wrong in the code or have any suggestions, please let me know.

Code:
// this function initializes the SPI1 peripheral
void init_SPI1(void){
	
	GPIO_InitTypeDef GPIO_InitStruct;
	SPI_InitTypeDef SPI_InitStruct;
	
	// enable clock for used IO pins
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	/* configure pins used by SPI1
	 * PA5 = SCK
	 * PA6 = MISO
	 * PA7 = MOSI
	 */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	// connect SPI1 pins to SPI alternate function
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

	// enable clock for used IO pins
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
	
	// enable peripheral clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
	/* configure SPI1
	 * CPOL = 1 --> clock is high when idle
	 * CPHA = 0 --> data is sampled at the second edge
	 */
	SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
	//SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
	SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;        // clock is high when idle
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;      // data sampled at second edge
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; // set the NSS management to internal and pull internal NSS high
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
	SPI_Init(SPI1, &SPI_InitStruct); 
	
	SPI_Cmd(SPI1, ENABLE); // enable SPI1
}

Best Regards,
Pat
 

just check the frequency u have used is same for STM32F4 and PIC18F2580 by checking the value of crystal oscillator.if the frequency is different then execution time wuld also be different...ie clock line may vary..
***********************************
A man must not deny his manifest abilities, for that is to evade his obligations.
William Feather
***************************************
 

Hi,

Thank you all for your suggestion. I have to apologize. I've just found out that I make a wrong setting in the logic analyzer software, so the SCK signal is not displayed. It's very stupid mistake. I'm so sorry.

With PIC configure as master and STM32F4 as slave, PIC is sending correct SCK signal and STM32F4 correctly receives the signal. However, MISO and MOSI are data wrong.

PIC (master) should send 0xAA (0b10101010) and should receive 0xAA in exchange.
Also, STM32F4 (slave) should receive 0xAA and send 0xAA in exchange.

Using logic analyzer (with correct settings), I found that PIC and STM32F4 actually send 0xAA (PIC's MOSI and STM32F4's MISO are correct). However, PIC and STM32F4 doesn't receive the byte (PIC's MISO and STM32F4's MOSI are 0xFF).

Please note that everything works fine when STM32F4 is master and PIC is slave.

I've attached images of logic analyzer output of both configuration. Please take a look and if you have any suggestions, please let me know.

PICmaster_STM32F4slave.jpgSTM32F4master_PICslave.jpg

Thank you very much for your help.

Best Regards,
Pat
 

hi,check the spi flag register as whatever the data is it first get stored in buffer.and also check spi control register.give proper delay for spi communications and one more thing read the datasheet of microcontroller properly as everything lies in it...
 

I see you configure the MISO pin and SCK pin as AF mode,if stm32 as slave,I think you should configure it as input mode.However I'm not sure.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top