2013-03-20 07:29 AM
Hello, I´m using STM32F303 and I´m trying to communicate via SPI (simplex SPI1-SPI2 using interrupts). It couldn´t be easier but it doesn´t work and I can´t find mistake. I connect PB3 (SPI1_SCK) with PB13(SPI2_SCK) and PB5(SPI1_MOSI) with PB14(SPI2_MISO) but it doesn´t generate interrupts. Here is my code. Thanks a lot for your help.
/* Private variables ---------------------------------------------------------*/ NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; __IO uint32_t TimDelay = 0; uint8_t SPI_MASTER_Buffer_Tx[]={1}; uint8_t ReceivedData; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ void SPI_Ini(void); int main(void) { SPI_Ini(); /* GPIOE Periph clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); /* Configure PE.9 (LED) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); while(1){ /* Send SPI_MASTER data */ SPI_SendData8(SPI1, SPI_MASTER_Buffer_Tx[0]); if(ReceivedData!=0)GPIOE->BSRR = 0x200; // LED on for(TimDelay=0; TimDelay < 100000; TimDelay++); } } void SPI_Ini(void) { SPI_InitTypeDef SPI_InitStructure; /* Enable GPIOB for SCK, MISO, MOSI GPIO clocks */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); /* Enable the SPI1 periph */ RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /* Enable the SPI2 periph */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /*----------------------Inicialization SPI master------------------------------------*/ /* SPI1 SCK pin configuration: AF PP output 50MHz */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5); // PB3: SPI1 SCK GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // alternate mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // push pull output //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI1 MOSI pin configuration: AF PP output 50MHz */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5); // PB5: SPI1 MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // alternate mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // push pull output //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI1 configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPI1); SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; 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_2; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init(SPI1, &SPI_InitStructure); /*----------------------Inicialization SPI slave------------------------------------*/ /* SPI2 SCK pin configuration: input mode 50MHz */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // input mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI2 MISO pin configuration: AF PP output 50MHz */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); // PB14: SPI2 MISO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // alternative mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // push pull output //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI2 configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPI2); SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx; SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_Init(SPI2, &SPI_InitStructure); /* Enable the Rx buffer not empty interrupt */ SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE); /* Configure the SPI interrupt priority */ NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the SPI peripheral */ SPI_Cmd(SPI2, ENABLE); /* Enable the SPI peripheral */ SPI_Cmd(SPI1, ENABLE); } void SPI2_IRQHandler(void) { /* SPI in Slave Receiver mode--------------------------------------- */ if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET) { ReceivedData = SPI_ReceiveData8(SPI2); } }2013-03-20 08:49 AM
A Master MOSI (output) needs to go to a Slave MOSI (input)
You should wait for TXE before sending data. Config clock and data output with a scope. RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // APB2!!2013-03-20 10:01 AM
Thanks Clive. I would never have found mistake APB1->APB2. I fix code according your ideas. It is sending data now, but still not receiving (SPI2 handler is not called).
Are you sure that I would use MOSI instead of MISO in slave? For example in reference manual for STM32F10x and this application note (page 5): is written that in simplex mode should be connected MOSI (master) with MISO (slave). I thing that mistake should be in setting pull ups/down, I don´t undertad where use PU or PD or no PUPD. Thank you for answer. int main(void) { SPI_Ini(); /* Enable SPI_MASTER TXE interrupt */ SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);//********************************************** /* Enable the Rx buffer not empty interrupt */ SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE); /* Enable the SPI peripheral */ SPI_Cmd(SPI2, ENABLE); /* Enable the SPI peripheral */ SPI_Cmd(SPI1, ENABLE); while(1){ } } void SPI_Ini(void) { SPI_InitTypeDef SPI_InitStructure; /* Enable GPIOB for SCK, MISO, MOSI GPIO clocks */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* Enable the SPI1 periph */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /* Enable the SPI2 periph */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /*--------+-------------Inicializace SPI master------------------------------------*/ /* SPI1 SCK pin configuration: AF PP output 50MHz */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5); // PB3: SPI1 SCK GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // alternate mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // push pull output //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//??????????????????????????????? GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI1 MOSI pin configuration: AF PP output 50MHz */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5); // PB5: SPI1 MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // alternate mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // push pull output //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//?????????????????????????????? GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI1 configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPI1); SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; 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_2; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init(SPI1, &SPI_InitStructure); /*--------+-------------Inicialization SPI slave------------------------------------*/ /* SPI2 SCK pin configuration: input mode 50MHz */ //GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // input mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//?????????????????????????? GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI2 MOSI pin configuration: input 50MHz */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; // PB15: SPI2 MOSI GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // alternative mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // push pull output //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//?????????????????????????????? GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI2 configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPI2); SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx; SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_Init(SPI2, &SPI_InitStructure); /* Configure the Priority Group to 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Configure the SPI interrupt priority */ NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure the SPI interrupt priority */ NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void SPI2_IRQHandler(void)//***********************************never called { /* SPI in Slave Receiver mode--------------------------------------- */ if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET) { ReceivedData = SPI_ReceiveData8(SPI2); } } void SPI1_IRQHandler(void) { if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_TXE) != RESET) { SPI_SendData8(SPI1, SPI_MASTER_Buffer_Tx[TxIdx++]); if (TxIdx == 4) { SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, DISABLE); } } }2013-03-20 10:07 AM
Not sure how the 1 wire settings impact things, MOSI (Master Out, Slave In) are common in the 2 wire modes. What does the manual say?
2013-03-20 10:14 AM
SPIx_MOSI | Simplex bidirectional data wire/ slave | Not used. Can be used as a GPIO
SPIx_MISO | Simplex bidirectional data wire/ slave | (point to point) AF push-pull2013-03-20 10:24 AM
Do you see any data on the wire with a scope?
The pull-up is irrelevant in PP (Push-Pull) mode, the pin is driven actively in both directions when in output mode. In input mode it's also not going to make any difference when it's connected to a PP driver.2013-03-22 07:53 AM
Yes, data looks fine on Scope. But when I simulate SCK (I give 3V on SCK_slave) it works....
I am lost :( But clock signal is sinus.... and I think that it should be square.... But I have SCK pins directly connected by wire...