cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Transmission Problem

heinsmatt
Associate II
Posted on October 23, 2012 at 04:00

I've got an STM32F103 chip transmitting SPI. It works fine most of the time. It's configured to be idle low. It is idle low when transmitting most values, but when I transmit the value 0b1000000, the data line goes high on the last falling edge of the clock signal. I'm pretty sure this is giving my shift register fits. Anybody know how to fix this problem?

6 REPLIES 6
Posted on October 23, 2012 at 08:46

Any code?

JW
Posted on October 23, 2012 at 08:50

[sorry, duplicated post - due to the corporate crap which is used here instead of proper bulletin board software]

heinsmatt
Associate II
Posted on October 23, 2012 at 16:01

I apologize and yes, this bulletin board is nonsense.

Here's the configuration:

/*SPI Config*/

SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStructure);

SPI_Init(SPI2, &SPI_InitStructure);

/* Enable SPI */

SPI_Cmd(SPI1, ENABLE);

SPI_Cmd(SPI2, ENABLE);

And the I/O configuration.

I'm manually performing the chip select as I plan to have more devices on the bus later.

/* Configure SPI2 SCK and MOSI pins as Alternate Function Push Pull */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);

/*Configure Chip Select*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);

Here's the sending code. I'm using FreeRTOS, which may or may not be part of my problem. The tick rate is about 20us. I've checked the chip select line and it's timing is appropriate:

CLEAR_LED_SELECT;

vTaskDelay(1);

SPI_I2S_SendData(SPI2, un8Data);

SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);

vTaskDelay(3);

SET_LED_SELECT;

And here's the interrupt:

void

SPI2_IRQHandler(void)

{

/*Clear the Tx Empty interrupt*/

SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_TXE);

/*Disable the Tx Empty interrupt so that it doesn't keep occurring*/

SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);

/*Give the SPI Tx Empty Semaphore*/

xSemaphoreGiveFromISR(xSemaphoreSPI2TxEmpty, NULL);

}

I'm pretty much stumped. My next plan of attack is to separate the SPI transmission from the rest of my program to test it in isolation. Is it possible that sending with both SPI1 and SPI2 at the same time causes some conflict?

Thanks

heinsmatt
Associate II
Posted on October 24, 2012 at 04:12

After isolating the SPI transmission, this happens whenever the MSB is 1.

heinsmatt
Associate II
Posted on October 24, 2012 at 04:24

Problem solved. I had left the Output Enable pin floating on my breadboard with the 595 shift register. The lingering '1' on the MOSI pin must've been capacitively coupling to the Output Enable pin causing the output to turn off. It is odd though that the idle low is not the case when the MSB is a '1'.

Posted on October 24, 2012 at 09:24

> It is odd though that the idle low is not the case when the MSB is a '1'.

You misunderstood the datasheet (and I misread your original post). The ''idle state'' relates to SCK, not to MOSI. MOSI is plainly output from a shift register, that's why it retains the last transmitted bit's state.

JW