STM32F103 SPI solo recibe 0x00

0

Estoy usando SPI para interactuar entre STM32F103 y MRF24J40. Escribo un valor en el registro MRF24J40 y luego leo para confirmar que funciona de manera funcional, pero solo recibo 0x00 del pin MISO. Aquí están mis interfaces SPI Initialize y MRF24J40

Configuración SPI:

SPI_InitTypeDef SPI_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; 
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;    
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI2, &SPI_InitStruct);
SPI_Cmd(SPI2, ENABLE);
GPIOB->BSRR = GPIO_Pin_12;                  //Disable SPI slave

Configuración GPIO:

GPIO_InitTypeDef GPIO_InitStruct;
//Clock providing for SPI peripheral
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

//GPIO config for SCK and MOSI pin
GPIO_InitStruct.GPIO_Pin = (GPIO_Pin_13 | GPIO_Pin_15);     
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;                        
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);

//GPIO config for MISO pin
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStruct);

//GPIO config for NSS pin
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);

Transferencia SPI:

uint8_t SPI_ByteTransfer(uint8_t data)      {
    while(!((SPI2->SR) & SPI_I2S_FLAG_TXE));            //Wait for data transmitted
    SPI_I2S_SendData(SPI2, data & 0xFF);                //Send data to TX buffer
    while(!((SPI2->SR) & SPI_I2S_FLAG_RXNE));           //Wait for data received
    data = SPI_I2S_ReceiveData(SPI2);
    return data;
}

Funciones de registro de escritura y lectura de MRF24J40:

void MRF24J40_WriteShortAddrReg(uint8_t addr, uint8_t data)         {
    addr = (addr << 1) | 0x01;              //MSB = 0 for short, LSB = 1 for writing
    GPIOB->BRR = GPIO_Pin_12;               //Enable SPI slave
    SPI_ByteTransfer(addr);
    SPI_ByteTransfer(data);
    while(SPI2->SR & SPI_I2S_FLAG_BSY);     //Wait for bus free
    GPIOB->BSRR = GPIO_Pin_12;              //Disable SPI slave
}

uint8_t MRF24J40_ReadShortAddrReg(uint8_t addr)         {
    uint8_t data;
    addr <<= 1;                            //MSB = 0 for short, LSB = 0 for reading
    GPIOB->BRR = GPIO_Pin_12;              //Enable SPI slave
    data = SPI_ByteTransfer(addr);
    while(SPI2->SR & SPI_I2S_FLAG_BSY);    //Wait for bus free
    GPIOB->BSRR = GPIO_Pin_12;             //Disable SPI slave
    return data;  
}
    

1 respuesta

4

Como SPI es una interfaz síncrona, los datos se reciben del esclavo al mismo tiempo que los datos son transmitidos por el maestro.

En su función de recepción, los datos se reciben del esclavo mientras se envía el byte de dirección. El esclavo no sabe a qué registro desea acceder cuando desplaza el primer byte, ya que la transmisión del byte de dirección aún está en proceso.

Intente agregar una escritura falsa (por ejemplo, 0x00) después de enviar el byte de dirección para permitir que el esclavo desplace los datos solicitados:

uint8_t MRF24J40_ReadShortAddrReg(uint8_t addr)         {
    uint8_t data;
    addr <<= 1;                            //MSB = 0 for short, LSB = 0 for reading
    GPIOB->BRR = GPIO_Pin_12;              //Enable SPI slave
    SPI_ByteTransfer(addr);                //Send address byte and discard received data
    data = SPI_ByteTransfer(0x00);         //Send dummy byte and receive requested data
    while(SPI2->SR & SPI_I2S_FLAG_BSY);    //Wait for bus free
    GPIOB->BSRR = GPIO_Pin_12;             //Disable SPI slave
    return data;  
}
    
respondido por el M2C8

Lea otras preguntas en las etiquetas