Hallo Allerseits,
ich versuche das SPI Interface des STM32F4 zu initialisieren um damit
ein RFM01/02 anzusprechen. Es scheitert allerdings schon bei der
Initialisierung. Die Interrupt Handler der beiden SPI Interfaces(2 & 3)
werden angesprungen, bevor ich überhaupt ein Zeichen sende.
Hat jemand von euch die SPI Schnittstelle des F4 schon erfolgreich in
Betrieb genommen? Beispielcode ist willkommen :)
Anbei mal meine nicht funktionierende Variante:
void SPI2_IRQHandler(void)
{
if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE)!= RESET)
{
SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_TXE);
}
}
void SPI3_IRQHandler(void)
{
if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE)!= RESET)
{
SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_TXE);
}
}
void init_RFM02(void){
/* Disable SPI Interrupts during init */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, DISABLE);
//Transmitter init
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_CFG | RFM12_CFG_EL | RFM12_CFG_EF |
RFM12_BAND_433| RFM12_XTAL_12PF);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_PWRMGT | RFM12_PWRMGT_DC |
RFM12_PWRMGT_EX | RFM12_PWRMGT_ES | RFM12_PWRMGT_ET);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
//430.9MHz
SPI_I2S_SendData(SPI3,RFM12_CMD_FREQUENCY | 36);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_DATARATE | 17);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_RXCTRL | RFM12_RXCTRL_P16_VDI |
RFM12_RXCTRL_VDI_FAST | RFM12_RXCTRL_BW_134 | RFM12_RXCTRL_LNA_0 |
RFM12_RXCTRL_RSSI_103);;
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_DATAFILTER | RFM12_DATAFILTER_AL |
RFM12_DATAFILTER_S | 0xC);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_FIFORESET | RFM12_FIFORESET_DR |
0x80);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_AFC | RFM12_AFC_AUTO_ONCE |
RFM12_AFC_OE | RFM12_AFC_EN);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_TXCONF| 0x50);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_WAKEUP);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_DUTYCYCLE);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
SPI3_CS_LOW;
SPI_I2S_SendData(SPI3,RFM12_CMD_LBDMCD);
while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
SPI3_CS_HIGH;
/* Enable the Tx buffer empty interrupt */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);
}
void init_SPI(void) {
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SPI_DeInit(SPI2);
SPI_DeInit(SPI3);
/* Enable the SPI clock 2 & 3 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 | RCC_APB1Periph_SPI3,
ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
/* SPI GPIO Configuration
--------------------------------------------------*/
/* Connect SPI pins to AF */
//PB3/13 SCK
//PB4/14 MISO
//PB5/15 MOSI
//PB2/12 CS
//PB1/11 nIRQ
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5
|GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//GPIO CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_2 | GPIO_Pin_12);
/* Enable SYSCFG clock */
//EXI
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
GPIO_Init(GPIOB, &GPIO_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line1 | EXTI_Line11;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
SPI_InitTypeDef SPI_InitStructure;
/* Initializes the SPI communication */
SPI_StructInit(&SPI_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
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_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_Init(SPI3, &SPI_InitStructure);
/* Enable the SPI peripheral */
SPI_Cmd(SPI2, ENABLE);
SPI_Cmd(SPI3, ENABLE);
/* Enable the Tx buffer empty interrupt */
SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_TXE);
SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_TXE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Schonmal vielen Dank für kommende Hilfe :)
Der Takt ist da, auch wenn man das in dem Codegewirr kaum sieht. Allerdings bringt es nichts, ein taktloses SPI zu deinitialisieren. Es könnte allerdings sein, das die AFIO keinen Takt hat.
Besucher schrieb: > Die Interrupt Handler der beiden SPI Interfaces(2 & 3) > werden angesprungen, bevor ich überhaupt ein Zeichen sende. Was mich bei eingeschaltetem "Tx buffer empty interrupt" nicht wirklich erstaunt.
Hi, das Flag wird doch gelöscht, somit sollte der doch nicht angesprungen werden? Der SPI Takt ist an und einen AFIO Takt gibts doch beim F4 nicht mehr, oder? Mfg
Besucher schrieb: > das Flag wird doch gelöscht, somit sollte der doch nicht angesprungen > werden? Wird der ausgelöst solange der Puffer leer ist oder beim Übergang von voll zu leer?
Ok, vorerst gelöst. Hab die Interrupts deaktiviert, die werden anscheinend permanent wieder gesetzt.. Dachte immer nur einmal, wenn das Transmit Register leer geworden ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.