es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo manejar correctamente la función de lectura del registro SPI? Me estoy enfrentando a un error de depuración.

Estoy utilizando el protocolo de comunicación SPI para comunicar mi placa con el NRF. Tengo la placa nucleo stm32l053r8. Estoy trabajando en stmcubeide y tratando de encontrar un problema en la depuración que se basa en la función de lectura de SPI. Todo lo que estoy haciendo es leer de la NRF los valores de reinicio de sus registros, por ejemplo CONFIG, ENAA, STATUS, etc. Estoy utilizando el depurador para eso, usando puntos de interrupción para ver si los valores que la función de lectura de SPI devuelve son correctos. El problema es que solo devuelve el primer valor correcto y después, a pesar de que quiero leer el registro ENAA, sigue devolviendo el valor de CONFIG.

Todas las demás funciones funcionan correctamente.

Función de lectura de SPI:

    uint8_t res=0;

    SPI1->DR=0xff;
    while(READ_BIT(SPI1->SR,SPI_SR_BSY));
    while(!READ_BIT(SPI1->SR,SPI_SR_RXNE));
    res = SPI1->DR;

    while(READ_BIT(SPI1->SR,SPI_SR_RXNE)==1)
    {
        READ_REG(SPI1->DR);
    }
    while(!(READ_BIT(SPI1->SR,SPI_SR_TXE)));
    while(READ_BIT(SPI1->SR,SPI_SR_BSY));

    SPI1->DR = reg;

    while(!(READ_BIT(SPI1->SR,SPI_SR_RXNE)));

    READ_REG(SPI1->DR);
    while(!(READ_BIT(SPI1->SR,SPI_SR_TXE)));
    while(READ_BIT(SPI1->SR,SPI_SR_BSY));
    SPI1->DR = 0xff;
    while(!(READ_BIT(SPI1->SR,SPI_SR_RXNE))); // Espera hasta que haya datos en el búfer antes de comenzar a leer.
    res = SPI1->DR;
    while(!(READ_BIT(SPI1->SR,SPI_SR_TXE)));
    while(READ_BIT(SPI1->SR,SPI_SR_BSY));

    return res;

Y la función principal que es para probar la lectura de SPI:

uint8_t res_1=0;

init_rcc(); // configuraciones del reloj
gpio_configure(); 
spi_configure();

while(1){

    for (uint8_t i=0;i<4;i++){ // Quiero leer los primeros 4 valores de registro
        CS_enable();
        res_1 = SPI_read(CONFIG+i); // empezando desde CONFIG y continuando
        CS_disable();
    }

}

Si lo ejecuto una vez usando un punto de interrupción en CS_enable() cuando spi_read() funciona por primera vez, devuelve el valor correcto que es 8. Después de eso, a pesar de que en el bucle con el comando res_1 = SPI_read(CONFIG+i); después del segundo intento de la lectura de SPI, va a otro registro pero aún devuelve 8, que es el valor para el registro CONFIG. ¿Qué me estoy perdiendo en los pasos de lectura de SPI?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema podría deberse al valor de res que no se reinicializa en cada lectura. Por lo tanto, la variable res solo contendrá el valor de la primera lectura durante las iteraciones posteriores del bucle.

    Para resolver este problema, puedes agregar res=0 al principio de la función spi_read para asegurarte de que la variable res se reinicialice en cada lectura.

    Otro problema podría estar relacionado con el estado de las banderas TXE/RXNE. Asegúrate de que la bandera TXE esté configurada antes de enviar datos y la bandera RXNE esté configurada antes de leer datos.

    Además, puedes agregar un manejo de errores en la función spi_read para detectar problemas de comunicación y evitar que afecten a las lecturas posteriores.

    Finalmente, es recomendable utilizar las funciones de la biblioteca HAL u otras capas de abstracción similares para la comunicación SPI en lugar de escribir código de bajo nivel, ya que proporcionan un mejor manejo de errores y aseguran la compatibilidad del código con diferentes arquitecturas de microcontroladores.

Comments are closed.