Using SPI and UART Devices in RT-Thread

RT-Thread uses function calls similar to Linux. Here’s how to use devices in a simple way.

  • Hardware Environment: STM32F103RBT6

User Program Location

User programs are written and called in applications.c in the applications folder under the bsp folder. If you have many programs, create another c file to separate them.

SPI Driver Files

The stm32f10x drivers folder doesn’t have SPI drivers. We need to port them from stm32f107. Copy rt_stm32f10x_spi.c, rt_stm32f10x_spi.h, and platform.c files, then add the call to rt_platform_init() in the rt_init_thread_entry function, and add the headers to the corresponding files. Then modify SConscript to include platform.c and rt_stm32f10x_spi.c for compilation, and add the RT_USING_SPI and RT_USING_SPI1 macro definitions in the config.

Add the following code to the SPI initialization in platform.c to configure the frequency:

        /* config spi */
        {
            struct rt_spi_configuration cfg;
            cfg.data_width = 8;
            cfg.mode = RT_SPI_MODE_3 | RT_SPI_MSB; /* SPI Compatible Modes 3 and SPI_FirstBit_MSB in lis302dl datasheet */
            
            //APB2=168M/2=84M, SPI1 = 84/2,4,8,16,32 = 42M, 21M, 10.5M, 5.25M, 2.625M ...
            cfg.max_hz = 2625000; /* SPI_BaudRatePrescaler_16=84000000/16=5.25MHz. The max_hz of lis302dl is 10MHz in datasheet */ 
            rt_spi_configure(&spi_device, &cfg);
        } /* config spi */  

Hardware Configuration

The hardware pins are configured in the platform.c file. We won’t modify the default configuration, which means PA4567 are the default SPI input/output pins.

/*
 * SPI1_MOSI: PA7
 * SPI1_MISO: PA6
 * SPI1_SCK : PA5
 *
 * CS0: PA4  SD card. You can change this to your own SPI device's CS pin
*/

SPI Calls

SPI calls don’t require the open function, just execute:

    rt_spi_transfer(spi_device, &ReadAddr, &pBuffer, 1);

or rt_spi_send_then_recv can also achieve different effects.

UART Calls

UART calls require the open function. Here’s a simple example of using a serial device:

void device_thread_entry(void* parameter)
{
    rt_device_t device;
    device = rt_device_find("uart2");
    rt_device_open(device, RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_INT_RX);
    char test[10] = "abc";
    while(1){
        rt_size_t reclen = rt_device_read(device, 0, test, 10);
        if(reclen > 0) rt_device_write(device, 0, test, reclen);
        rt_thread_delay(500);
    }
}

You can start this thread, and when we input up to 10 characters in uart2, they will be echoed back after 5 seconds. If more than 10 characters are entered, they should be displayed in the next 5-second cycle. The official markdown documentation uses a message mechanism to handle UART communication, which can also be referenced.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy