【NCS随笔】添加SPI主机和SPI从机例程

SPI主机设备树 overlay 示例

&pinctrl {
    spi21_default: spi21_default {
        group2 {
            psels = <NRF_PSEL(SPIM_MOSI, 1, 12)>,
                    <NRF_PSEL(SPIM_SCK, 1, 8)>,
                    <NRF_PSEL(SPIM_MISO, 1, 11)>;
            nordic,drive-mode = <NRF_DRIVE_H0H1>;
        };
    };
};

&spi21 {
    status = "okay";
    pinctrl-0 = <&spi21_default>;
    pinctrl-names = "default";
    cs-gpios = <&gpio2 10 (GPIO_ACTIVE_LOW)>;
};

此配置将 SPI21 配置为主机,SCK/MOSI/MISO/CS 分别对应 P1.8/P1.12/P1.11/P2.10


SPI主机 代码示例

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/gpio.h>

#define SPI_DEV_NODE DT_NODELABEL(spi21)

void main(void)
{
    const struct device *spi_dev = DEVICE_DT_GET(SPI_DEV_NODE);
    if (!device_is_ready(spi_dev)) {
        printk("SPI device not ready!\n");
        return;
    }

    struct spi_cs_control cs_ctrl = {
        .gpio = GPIO_DT_SPEC_GET(SPI_DEV_NODE, cs_gpios),
        .delay = 0,
    };

    struct spi_config spi_cfg = {
        .frequency = 1000000,
        .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_OP_MODE_MASTER,
        .slave = 0,
        .cs = &cs_ctrl,
    };

    uint8_t tx_buf[5] = { 0x0A, 0x0B, 0x0C, 0x0D, 0x0E };
    uint8_t rx_buf[5] = {0};

    struct spi_buf tx_spi_buf = { .buf = tx_buf, .len = sizeof(tx_buf) };
    struct spi_buf rx_spi_buf = { .buf = rx_buf, .len = sizeof(rx_buf) };
    struct spi_buf_set tx = { .buffers = &tx_spi_buf, .count = 1 };
    struct spi_buf_set rx = { .buffers = &rx_spi_buf, .count = 1 };

    int ret = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);
    printk("SPI transceive ret: %d\n", ret);
    printk("TX: %02x %02x %02x %02x %02x\n", tx_buf[0], tx_buf[1], tx_buf[2], tx_buf[3], tx_buf[4]);
    printk("RX: %02x %02x %02x %02x %02x\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3], rx_buf[4]);
}

此代码会通过 SPIM 发送 5 字节数据,并打印发送和接收结果


如需 SPI 从机(SPIS)示例,请参考如下 overlay 和代码:

SPI从机 overlay 示例

&pinctrl {
    spis22_default: spis22_default {
        group1 {
            psels = <NRF_PSEL(SPIS_SCK, 2, 6)>,
                    <NRF_PSEL(SPIS_MOSI, 2, 9)>,
                    <NRF_PSEL(SPIS_MISO, 2, 8)>,
                    <NRF_PSEL(SPIS_CSN, 2, 10)>;
        };
    };
};

&spi22 {
    compatible = "nordic,nrf-spis";
    status = "okay";
    pinctrl-0 = <&spis22_default>;
    pinctrl-names = "default";
    def-char = <0x00>;
};

SPI从机 C代码片段

static const struct spi_config spi_cfg = {
    .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_OP_MODE_SLAVE,
    .frequency = 1000000,
    .slave = 1,
};

const struct device *spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi22));

void main(void)
{
    uint8_t tx_buffer[32] = { 's', 'p', 'i', 's', 'l', 'a', 'v', 'e', '\n' };
    uint8_t rx_buffer[32] = {0};

    struct spi_buf tx_buf = { .buf = tx_buffer, .len = sizeof(tx_buffer) };
    struct spi_buf rx_buf = { .buf = rx_buffer, .len = sizeof(rx_buffer) };
    struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 };
    struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 };

    while (1) {
        int err = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);
        printk("SPI error: %d\n", err);
        printk("TX buffer [0]: %x\n", tx_buffer[0]);
        printk("RX buffer [0]: %x\n", rx_buffer[0]);
        k_sleep(K_MSEC(1000));
    }
}
posted @ 2025-08-29 10:53  TedLee  阅读(271)  评论(0)    收藏  举报