哈哈哈哈哈操欧洲电影,久草网在线,亚洲久久熟女熟妇视频,麻豆精品色,久久福利在线视频,日韩中文字幕的,淫乱毛视频一区,亚洲成人一二三,中文人妻日韩精品电影

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

nRF Connect SDK Basic

jf_14701710 ? 來源:jf_14701710 ? 作者:jf_14701710 ? 2025-08-20 10:41 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

用戶在使用 nRF connect SDK 的時候經(jīng)常會操作的外設有GPIO,I2C,SPI,UART。我們就以 nRF connect SDK 2.7.0 中的例程代碼 nrfsamplesbluetoothperipheral_lbs 為基礎,來演示上述外設的簡單使用。使用的硬件是開發(fā)板 nRF52840 DK.

準備工作

首先我們在原本的工程目錄的 boards 文件夾里,添加文件 nrf52840dk_nrf52840.overlay。通過這個文件我們可以修改 devicetree。 編譯完成后,我們可以查看 buildzephyrzephyr.dts,以確認devicetree 的更改是否生效。

我們還可以通過修改 prj.conf 來修改 Kconfig。編譯完成后,我們可以查看 buildzephyr.config 以確認 Kconfig 的更改是否生效。

wKgZPGilNdmACeSdAABK1LsANgo21.jpeg

GPIO 控制

首先我們演示如何刪除原有的按鍵和LED的 node 。按照下面的代碼,來修改 devicetree,就可以刪除 button3 和 led3。

/ {
    aliases {
        /delete-property/ sw3;
        /delete-property/ led3;
    };
};


/delete-node/ &button3;
/delete-node/ &led3;

接著我們來更改控制 led2 的管腳。這里我們用 P0.04 控制 led2。

&led2 {
    gpios = ;
};

最后我們添加一個用戶 GPIO 。這里添加了一個名為 user_gpios 的 node。然后又定義了 user_io0,它是 user_gpios 的 subnode。

/ {
    user_gpios {
        compatible = "gpio-leds";
        user_io0: user_io0 {
            gpios = ;
            label = "user gpio 0";
        };
    };
};

我們不僅在 devicetree 里添加這個 GPIO ,還要在 main.c 里添加代碼使用這個GPIO。下面這句代碼中,我們聲明了結構體變量 user_gpio0,并用宏 GPIO_DT_SPEC_GET 根據(jù) devicetree 里的定義初始化它。

const struct gpio_dt_spec user_gpio_0 = GPIO_DT_SPEC_GET(DT_NODELABEL(user_io0),gpios);

下面這段代碼中 gpio_is_ready_dt 是用來檢查 GPIO 的狀態(tài)是否是就緒。用函數(shù) gpio_pin_configure_dt 把 user_gpio_0 配置成輸出。gpio_pin_toggle_dt 用來翻轉 GPIO。

if (!gpio_is_ready_dt(&user_gpio_0)) {
    printk("%s: device not ready.n", user_gpio_0.port->name);
    return 0;
}
gpio_pin_configure_dt(&user_gpio_0, GPIO_OUTPUT_ACTIVE);

for (index = 0; index < 100; index++) {
    gpio_pin_toggle_dt(&user_gpio_0);
    k_sleep(K_MSEC(100));
}

從下面的代碼可以看出翻轉 GPIO 這個操作有兩種 API 可以調(diào)用。二者的主要區(qū)別是 gpio_pin_toggle_dt 不需要指明引腳 。

/**
 * @brief Toggle pin level from a @p gpio_dt_spec.
 *
 * This is equivalent to:
 *
 *     gpio_pin_toggle(spec->port, spec->pin);
 *
 * @param spec GPIO specification from devicetree
 * @return a value from gpio_pin_toggle()
 */
static inline int gpio_pin_toggle_dt(const struct gpio_dt_spec *spec)
{
    return gpio_pin_toggle(spec->port, spec->pin);
}

I2C 設備控制

Nordic 的芯片中 I2C 接口是由外設 TWI 來實現(xiàn)的,I2C master 由 TWIM 實現(xiàn), I2C master 由 TWIS 實現(xiàn)。這里將演示如何用一個 TWIM 來連接兩個 I2C slave 設備。

首先我們還是先修改 devicetree。我們使用 i2c1 這個 node。 一方面按照應用的要求修改這個 node 的 propertise,另一方面在這個 node 里創(chuàng)建兩個 sub-node。

i2c 的時鐘頻率通過 clock-frequency 來定義。

i2c 的引腳通過 pinctrl-0 和 pinctrl-1 定義。我們將在后面分析 i2c1_default 和 i2c1_sleep 的定義。

這兩個 sub-node 一個是 user_i2c_sensor,另一個是 user_i2c_eeprom。這兩個 sub-node 通過 propertise reg 來定義各自的 I2C 地址。

&i2c1 {
    status = "ok";
    clock-frequency = ;
    pinctrl-0 = < &i2c1_default >;
    pinctrl-1 = < &i2c1_sleep >;
    pinctrl-names = "default", "sleep";
    user_i2c_sensor: user_i2c_sensor@0 {
        compatible = "i2c-user-define";
        reg = ;
    };
    user_i2c_eeprom: user_i2c_eeprom@0 {
        compatible = "i2c-user-define";
        reg = ;
    };
};

i2c1_default 和 i2c1_sleep的定義如下。TWIM_SDA 信號使用的是引腳 P0.04,TWIM_SCL 信號使用的是引腳 P0.03。

&pinctrl {
    i2c1_default: i2c1_default {
        group1 {
            psels = ,
                ;
        };
    };

    i2c1_sleep: i2c1_sleep {
        group1 {
            psels = ,
                ;
            low-power-enable;
        };
    };

};

修改 prj.conf 添加 CONFIG_I2C=y

修改完 devicetree 我們在來添加操作 i2c 的代碼。分別定義 i2c1_sensor 和 i2c1_eeprom,它們對應剛才 i2c1 的兩個子節(jié)點。

const struct i2c_dt_spec i2c1_sensor = I2C_DT_SPEC_GET(DT_NODELABEL(user_i2c_sensor));
const struct i2c_dt_spec i2c1_eeprom= I2C_DT_SPEC_GET(DT_NODELABEL(user_i2c_eeprom));

i2c 設備在讀寫操作前無需調(diào)用 API 來配置 ,直接調(diào)用下面的寫函數(shù)。

err = i2c_write_dt(&i2c1_sensor, buf, 1);

err = i2c_write_dt(&i2c1_eeprom, buf, 1);

通過邏輯分析儀我們可以看到如下的總線數(shù)據(jù),操作的目標地址分別是我們在 devicetree 里設置的數(shù)值 0x05 和 0x0A 。

wKgZPGilNdqATuRpAABLFQTcgaw05.jpeg

SPI 設備控制

Nordic 的芯片中 SPI 接口的 master 端通過 SPIM 實現(xiàn), slave 端通過 SPIS 實現(xiàn)。這里將演示如何用一個 SPIM 來連接兩個 SPI slave 設備。

首先修改 devicetree。

這里我們使用 spi2, 并且關閉 spi1。在 nordic 的nRF52 系列芯片中,相同數(shù)字編號的 TWIM, TWIS, SPIM, SPIS 是共用一組硬件模塊的。在上面 i2c 中我們已經(jīng)使用 i2c1, 所以這里我們就不能同時使用 spi1了。

cs-gpios 定義了 P0.26 和 P0.27 兩 個CS 信號。 SPI 用不同的片選信號,區(qū)分不同的 slave 設備。

devicetree node spi2 下定義了兩個 sub-node 分別是 user_spi_adc 和 user_spi_flash。 sub-node 里定義了三個 propertise。propertise compatible 的取值來自于我們在工程里新添加的文件 dtsbindingsspi-user-define.yaml。 propertise reg 的取值和前面的 propertise cs-gpios 呼應,reg = <0> 的 sub-node 使用 cs-gpios 里面定義的第一個 CS 引腳。reg = <1> 的 sub-node 使用 cs-gpios 里面定義的第二個 CS 引腳。propertise spi-max-frequency 定義 SPI 的時鐘頻率。兩個不同的 SPI 設備可以使用不同的時鐘頻率驅動。

&spi1 {
    status = "disabled";
};
&spi2 {
    status = "okay";
    cs-gpios = ,
               ;
    pinctrl-0 = < &spi2_default >;
    pinctrl-1 = < &spi2_sleep >;
    pinctrl-names = "default", "sleep";

    user_spi_adc: user_spi_adc@0 {
        compatible = "spi-user-define";
        reg = ;
        spi-max-frequency = ;
    };
    user_spi_flash: user_spi_flash@0 {
        compatible = "spi-user-define";
        reg = ;
        spi-max-frequency = ;
    };
};

來看一下我們新添加的 dtsbindingsspi-user-define.yaml 里面的內(nèi)容。如下圖 spi-user-define.yaml 里面包含了 spi-device.yaml 文件,這個文件的位置在目錄 zephyrdtsbindingsspi 。

compatible: "spi-user-define"

include: [spi-device.yaml]

spi-device.yaml 文件里面定義了 spi 節(jié)點需要的一些 propertise。 比如我們在 sub-node 里定義的 propertise spi-max-frequency。

# Copyright (c) 2018, I-SENSE group of ICCS
# SPDX-License-Identifier: Apache-2.0

# Common fields for SPI devices

include: [base.yaml, power.yaml]

on-bus: spi

properties:
  reg:
    required: true
  spi-max-frequency:
    type: int
    required: true
    description: Maximum clock frequency of device's SPI interface in Hz
  duplex:
    type: int
    default: 0
    description: |
      Duplex mode, full or half. By default it's always full duplex thus 0
      as this is, by far, the most common mode.
      Use the macros not the actual enum value, here is the concordance
      list (see dt-bindings/spi/spi.h)
        0    SPI_FULL_DUPLEX
        2048 SPI_HALF_DUPLEX
    enum:
      - 0
      - 2048
  frame-format:
    type: int
    default: 0
    description: |
      Motorola or TI frame format. By default it's always Motorola's,
      thus 0 as this is, by far, the most common format.
      Use the macros not the actual enum value, here is the concordance
      list (see dt-bindings/spi/spi.h)
        0     SPI_FRAME_FORMAT_MOTOROLA
        32768 SPI_FRAME_FORMAT_TI
    enum:
      - 0
      - 32768
  spi-cpol:

SPI 引腳定義如下 CLK P0.28, MISO P0.29, MOSI P0.30。

spi2_default: spi2_default {
    group1 {
        psels = ,
                ,
                ;
    };
};
spi2_sleep: spi2_sleep {
    group1 {
        psels = ,
                ,
                ;
        low-power-enable;
    };
};

修改 prj.conf 添加 CONFIG_SPI=y CONFIG_SPI_ASYNC=y。

在 main.c 里添加 SPI 的應用代碼。下面這段代碼定義了兩個結構體變量,并通過宏 SPI_DT_SPEC_GET 用 devicetree 里的參數(shù)初始化了這兩個結構體變量。

#define SPI_OP     SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA 
                   | SPI_WORD_SET(8) | SPI_LINES_SINGLE
static struct spi_dt_spec spim2_adc = SPI_DT_SPEC_GET(DT_NODELABEL(user_spi_adc), SPI_OP, 0);
static struct spi_dt_spec spim2_flash = SPI_DT_SPEC_GET(DT_NODELABEL(user_spi_flash), SPI_OP, 0);

spi 驅動支持多 buffer 所以要定義 buffer 個數(shù),和每個 buffer 的長度。同樣 spi 在讀寫之前無需調(diào)用配置函數(shù),直接調(diào)用讀寫函數(shù)就行。

struct spi_buf_set tx_bufs;
struct spi_buf spi_tx_buf;

tx_bufs.buffers = &spi_tx_buf;
tx_bufs.count = 1;
spi_tx_buf.buf = buf;
spi_tx_buf.len = 2;

err = spi_write_dt(&spim2_adc, &tx_bufs);
err = spi_write_dt(&spim2_flash, &tx_bufs);

下面是SPI的波形。可以看到和不同的 spi slave 設備通訊的時候, spi master 會拉低不同的 CS 引腳。

wKgZO2ilNdqAfdkyAAAzjUGgVu089.jpeg

UART 控制

Nordic 的芯片中 UART 接口叫做 UARTE。這里的 E 是指 EasyDMA , UART 可以使用 DMA 來連續(xù)收發(fā)。

修改 Devicetree。這里使用 uart1。propertise current-speed 設置 uart 的波特率。

&uart1 {
    status = "okay";
    current-speed = ;
    pinctrl-0 = < &uart1_default >;
    pinctrl-1 = < &uart1_sleep >;
    pinctrl-names = "default", "sleep";
};

TXD pin 為 P1.02, RXD pin 為 P1.01。

 uart1_default: uart1_default {
    group1 {
        psels = ;
        bias-pull-up;
    };
    group2 {
        psels = ;
    };
};

uart1_sleep: uart1_sleep {
    group1 {
        psels = ,
            ;
        low-power-enable;
    };
};

修改 prj.conf 在里面添加 CONFIG_UART_ASYNC_API=y CONFIG_UART_ASYNC_RX_HELPER=y。

修改 main.c 添加 uart 收發(fā)代碼。 uart_callback_set 設置 callback 函數(shù) uart_cb。因為這里采用的是異步收發(fā)的模式,所以設置callback 函數(shù)是必備的。uart_rx_enable 使能接收。uart_tx 發(fā)送數(shù)據(jù)。

err = uart_callback_set(uart1, uart_cb, NULL);
//printk("uart_callback_set return %dn", err);

err = uart_rx_enable(uart1, uart_rx_buf, MAX_UART_BUF_LEN, UART_RX_TIMEOUT_MS);
//printk("uart_rx_enable return %dn", err);

err = uart_tx(uart1, uart_tx_buf, 6, SYS_FOREVER_MS);
//printk("uart_tx return %dn", err);

callback 函數(shù) uart_cb 可能由多種事件觸發(fā)。比如當接收到數(shù)據(jù)后會觸發(fā)回調(diào),并在參數(shù) EVT 傳遞 UART_RX_RDY 和接收到的數(shù)據(jù)和長度。

static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
    ARG_UNUSED(dev);

    //LOG_INF("uart_cb evt->type:%d", evt->type);
    switch (evt->type) {
    case UART_TX_DONE:
        printk("UART_TX_DONEn");
        break;

    case UART_RX_RDY:
        printk("UART_RX_RDYn");
        printk("received %d bytesn", evt->data.rx.len);
        break;

    case UART_RX_DISABLED:
        printk("UART_RX_DISABLEDn");
        break;

    case UART_RX_BUF_REQUEST:
        printk("UART_RX_BUF_REQUESTn");
        uart_rx_buf_rsp(uart1, uart_rx_buf2, MAX_UART_BUF_LEN);
        break;

    case UART_RX_BUF_RELEASED:
        printk("UART_RX_BUF_RELEASEDn");
        break;

    case UART_TX_ABORTED:
        printk("UART_TX_ABORTEDn");
        break;

    default:
        break;
    }
}

我們在 DK 上把 TXD 引腳和 RXD 引腳短接來測試 UART 的收發(fā),可以看到如下的 log 信息。UART 收到了自己發(fā)送的6字節(jié)的數(shù)據(jù)。

wKgZPGilNduAY7_BAACdqEMlnvU82.jpeg

UART 應用代碼的優(yōu)化

上面的 uart 演示代碼中,我們只實現(xiàn)了簡單的收發(fā)。下面我們將進一步在此基礎上優(yōu)化 UART 的收發(fā)代碼。這一部分的修改都在 main.c 里,主要涉及下面幾個部分:

Thread 線程

Semaphore 信號量

線程間通訊 Message queue

線程 下面的代碼中通過 K_THREAD_DEFINE 定義了 一個獨立的線程來處理 uart 相關的代碼。線程處理函數(shù) uart_thread_task 中:也是先用 uart_callback_set 設置了回調(diào)函數(shù);再用 uart_rx_enable 使能了接收;然后是一個 for 循環(huán),在里面不斷的接收消息,根據(jù)消息中的指令發(fā)送數(shù)據(jù),或者處理接收到的數(shù)據(jù)。

#define UART_THREAD_STACK_SIZE    512
#define UART_THREAD_PRIORITY      -1

void uart_thread_task(void)
{
    int err;
    struct uart_data_item_type uart_msgq;

    k_sem_take(&uart_thread_start, K_FOREVER);

    printk("uart_thread_taskn");

    err = uart_callback_set(uart1, uart_cb, NULL);

    err = uart_rx_enable(uart1, uart_rx_buf, MAX_UART_BUF_LEN, UART_RX_TIMEOUT_MS);

    for (;;) {
        k_msgq_get(&uart_data_msgq, &uart_msgq, K_FOREVER);
        printk("received uart data itemn");

        switch(uart_msgq.cmd) {
        case UART_CMD_TX:
        memcpy(uart_tx_buf,&uart_msgq.data, sizeof(uint32_t));
        err = uart_tx(uart1, uart_tx_buf, sizeof(uint32_t), SYS_FOREVER_MS);
        break;

        case UART_CMD_DATA_PROCESS:
        break;

        default:
            break;
        }
    }
}

K_THREAD_DEFINE(uart_thread_id, UART_THREAD_STACK_SIZE, uart_thread_task, NULL, NULL,
                NULL, UART_THREAD_PRIORITY, 0, 0);

上面的代碼中用 K_THREAD_DEFINE 定義線程的時候,需要指定此線程的優(yōu)先級 UART_THREAD_PRIORITY。UART_THREAD_PRIORITY 的數(shù)據(jù)類型是 integer,可以是正數(shù)也可以是負數(shù)。優(yōu)先級的數(shù)字越小,優(yōu)先級越高,負數(shù)的優(yōu)先級比正數(shù)高。thread 的優(yōu)先級取值為負數(shù)時,此 thread 為協(xié)同線程 cooperative thread 。當這種線程正在執(zhí)行的時候,其它更高優(yōu)先級的線程不能打斷它,必須等它執(zhí)行完再執(zhí)行下一個線程。當 thread 的優(yōu)先級取值為正數(shù),此 thread 為搶占線程 preemptible thread。當這種線程正在執(zhí)行的時候,其它更高優(yōu)先級的線程可以打斷它,跳轉到高優(yōu)先級的任務。等高優(yōu)先級的線程執(zhí)行完才返回原 thread 繼續(xù)執(zhí)行?;氐嚼檀a,從應用的角度出發(fā),我們希望 uart_thread_task 的執(zhí)行優(yōu)先級大于 main 函數(shù)。通過查詢文件 buildzephyr.config 我們得知 CONFIG_MAIN_THREAD_PRIORITY 的取值為 0,也就是說 main thread 當前的優(yōu)先級為 0, 所以我們定義了 UART_THREAD_PRIORITY 為 -1。這樣 uart thread 的優(yōu)先級就高于 main thread, 而且 uart thread 的執(zhí)行不會被其它更高優(yōu)先級的 thread 打斷。需要注意的是這里的不能被打斷只是對 thread 而言,中斷是可以打斷 cooperative thread 的。

信號量 函數(shù) uart_thread_task 的優(yōu)先級比 main 函數(shù)高,所以會先于main 函數(shù)執(zhí)行。如果之前的函數(shù) uart_thread_task 里沒有 k_sem_take(&uart_thread_start, K_FOREVER),就會出現(xiàn)如下圖的現(xiàn)象。我們看到 uart thread 的 log 是先于 main thread 被打印出來的。

wKgZO2ilNdyASkHZAACxi5yzJDg78.jpeg

從應用的角度,我們希望 uart_thread_task 在 main 函數(shù)啟動完廣播之后再執(zhí)行。這就引入了一個不同線程之間的同步問題。Zephyr RTOS 中可以通過 semaphore 解決不同 thread 間的同步問題。下面的代碼中通過 K_SEM_DEFINE 定義了一個為 uart_thread_start 的 semaphore 。 函數(shù) uart_thread_task 執(zhí)行到函數(shù) k_sem_take 時,如果 uart_thread_start 沒有被釋放,當前 thread 會被掛起等待,直到 semaphore 被釋放。

static K_SEM_DEFINE(uart_thread_start, 0, 1);

#define UART_THREAD_STACK_SIZE    512
#define UART_THREAD_PRIORITY      -1

void uart_thread_task(void)
{
    int err;
    struct uart_data_item_type uart_msgq;

    k_sem_take(&uart_thread_start, K_FOREVER);

    printk("uart_thread_taskn");

    err = uart_callback_set(uart1, uart_cb, NULL);

    err = uart_rx_enable(uart1, uart_rx_buf, MAX_UART_BUF_LEN, UART_RX_TIMEOUT_MS);

    for (;;) {

在 main 里通過 k_sem_give 釋放 uart_thread_start。uart 線程會打斷當前的 main thread 從 k_sem_take 繼續(xù)執(zhí)行。

err = spi_write_dt(&spim2_adc, &tx_bufs);
err = spi_write_dt(&spim2_flash, &tx_bufs);

k_sem_give(&uart_thread_start);

struct uart_data_item_type main_msgq;

main_msgq.cmd = UART_CMD_TX;
main_msgq.data = 0;

for (;;) {

    while (k_msgq_put(&uart_data_msgq, &main_msgq, K_NO_WAIT) != 0) {
        /* message queue is full: purge old data & try again */
        k_msgq_purge(&uart_data_msgq);
    }
    main_msgq.data++;

    dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
}

線程間通訊 演示代碼中 main thread 會把要發(fā)送的數(shù)據(jù)通過線程通訊發(fā)送到 uart thread, uart thread 調(diào)用驅動函數(shù)發(fā)送。zephyr 中提供了多種線程間通訊方式,具體如下圖,這里使用的是 message queue。

wKgZPGilNdyADvoPAABtzOcdD7823.jpeg

下面的代碼中 K_MSGQ_DEFINE 定義了一個名為 uart_data_msgq 的 message queue。uart_data_msgq 的緩沖區(qū)里最多可以容納 8 個消息。

struct uart_data_item_type {
    uint8_t cmd;
    uint32_t data;
};

K_MSGQ_DEFINE(uart_data_msgq, sizeof(struct uart_data_item_type), 8, 4);

下面這段代碼來自于 main thread 的 main 函數(shù)。代碼會定時循環(huán)把待發(fā)送的數(shù)據(jù)打包成一個 message,然后推送到 message queue 里面。

struct uart_data_item_type main_msgq;

main_msgq.cmd = UART_CMD_TX;
main_msgq.data = 0;

for (;;) {

    while (k_msgq_put(&uart_data_msgq, &main_msgq, K_NO_WAIT) != 0) {
        /* message queue is full: purge old data & try again */
        k_msgq_purge(&uart_data_msgq);
    }
    main_msgq.data++;

    dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
}

下面的代碼來自 uart thread 的 uart_thread_task 函數(shù)。 函數(shù)等待 message queue 里推送來的 message。得到 message 后,根據(jù)里面的 cmd 字段來處理發(fā)送或者接收數(shù)據(jù)。

void uart_thread_task(void)
{
    int err;
    struct uart_data_item_type uart_msgq;

    k_sem_take(&uart_thread_start, K_FOREVER);

    printk("uart_thread_taskn");

    err = uart_callback_set(uart1, uart_cb, NULL);

    err = uart_rx_enable(uart1, uart_rx_buf, MAX_UART_BUF_LEN, UART_RX_TIMEOUT_MS);

    for (;;) {
        k_msgq_get(&uart_data_msgq, &uart_msgq, K_FOREVER);
        printk("received uart data itemn");

        switch(uart_msgq.cmd) {
        case UART_CMD_TX:
        memcpy(uart_tx_buf,&uart_msgq.data, sizeof(uint32_t));
        err = uart_tx(uart1, uart_tx_buf, sizeof(uint32_t), SYS_FOREVER_MS);
        break;

        case UART_CMD_DATA_PROCESS:
        break;

        default:
            break;
        }
    }
}

下面是加入線程間通訊的代碼后得到的 log,當我們把 TX 和 RX 引腳短接后可以看出 uart thread 不斷的發(fā)送從 main thread 傳輸?shù)臄?shù)據(jù)。

wKgZPGilNb6AbhUUAAJR31FvtbQ998.png

總結

本文從實際操作出發(fā),介紹了用戶最常用的一些外設如 GPIO, I2C, SPI, UART 的配置和使用方法。并介紹了一些簡單 RTOS 組件的應用如 thread, semaphore, message queue。希望能幫助 Nordic 用戶加快 nRF Connect SDK 的開發(fā)速度。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • NRF
    NRF
    +關注

    關注

    0

    文章

    50

    瀏覽量

    38778
  • SDK
    SDK
    +關注

    關注

    3

    文章

    1109

    瀏覽量

    51980
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Nordic 推出nRF Connect for Cloud 的無線物聯(lián)網(wǎng)設計方案

    Nordic Semiconductor宣布推出nRF Connect for Cloud,用于免費評估、測試和驗證基于云并且采用Nordic nRF51和nRF52系列多協(xié)議低功耗藍
    的頭像 發(fā)表于 06-21 15:05 ?9948次閱讀

    nRF Connect SDK(NCS)/Zephyr固件升級詳解 – 重點講述MCUboot和藍牙空中升級

    如何在nRF Connect SDK(NCS)中實現(xiàn)藍牙空中升級?MCUboot和B0兩個Bootloader有什么區(qū)別?MCUboot升級使用的image格式是怎么樣的?什么是SMP協(xié)議?CBOR
    的頭像 發(fā)表于 05-09 14:14 ?3818次閱讀
    <b class='flag-5'>nRF</b> <b class='flag-5'>Connect</b> <b class='flag-5'>SDK</b>(NCS)/Zephyr固件升級詳解 – 重點講述MCUboot和藍牙空中升級

    Nordic nRF5 SDK和softdevice介紹

    Connect SDK。一般來說,開發(fā)nRF51/52產(chǎn)品推薦使用nRF5 SDK,開發(fā)nRF
    的頭像 發(fā)表于 08-20 09:54 ?3297次閱讀
    Nordic <b class='flag-5'>nRF</b>5 <b class='flag-5'>SDK</b>和softdevice介紹

    Nordic nRF Connect SDK 官方開發(fā)文檔、學習資料下載鏈接

    /14174427.html nRF Connect SDK詳解 https://lgl88911.gitee.io/ 其他博客 https://academy.nordicsemi.com/courses
    發(fā)表于 04-23 13:48

    如何調(diào)試nRF5 SDK

    本文將講述Nordic nRF5 SDK的主要調(diào)試手段,以幫助大家快速定位問題,并解決問題。一般來說,你可以通過打log方式,IDE的debug模式,SDK自帶的app_error_check函數(shù)
    發(fā)表于 04-26 23:13

    Nordic無線開發(fā)---nRF Connect SDK 3.0更新版的安裝入門介紹

    系統(tǒng)上git狀態(tài)錯誤的問題 nRF Connect SDK,簡稱NCS,是Nordic最新的SDK平臺。該平臺支持Nordic的三大產(chǎn)品線: 1.短距離 2.4G MCU: Bluet
    發(fā)表于 10-29 20:40

    深度技術解析低功耗藍牙廠商nordic的nRF Connect SDK裸機選項方案

    自2018年以來,Nordic Semiconductor一直致力于開發(fā)基于Zephyr實時操作系統(tǒng)( RTOS)的nRF Connect SDK,并不斷發(fā)展,提供最佳的工具與軟件,助力開發(fā)者在
    發(fā)表于 10-29 21:17

    使用nRF52840芯片的USB Host 功能參考例程

    Host 示例 Nordic 的 nRF5 SDK(或 nRF Connect SDK,取決于你使用的開發(fā)框架)中包含專門的 USB Ho
    發(fā)表于 10-31 12:47

    深度技術解析nRF Connect SDK裸機選項方案

    nRF Connect SDK裸機選項是nRF Connect SDK 環(huán)境中新增的替代開發(fā)路徑
    發(fā)表于 10-31 23:11

    講述Nordic nRF5 SDK的主要調(diào)試手段,以幫助大家快速定位問題

    nRF5 SDK日志打印功能是通過nRF_Log模塊實現(xiàn)的(上面展示的日志都是通過nRF_Log打印出來的),SDK包含的大部分例子都自帶打
    的頭像 發(fā)表于 04-15 15:38 ?1.5w次閱讀
    講述Nordic <b class='flag-5'>nRF</b>5 <b class='flag-5'>SDK</b>的主要調(diào)試手段,以幫助大家快速定位問題

    nRF5 SDK軟件架構及softdevice工作原理

    本文將介紹Nordic nRF5 SDK軟件架構以及softdevice工作原理,以加深大家對Nordic產(chǎn)品開發(fā)的理解,這樣開發(fā)過程中碰到問題時,大家也知道如何去調(diào)試。 如果你剛開始接觸nRF
    的頭像 發(fā)表于 06-23 11:08 ?832次閱讀
    <b class='flag-5'>nRF</b>5 <b class='flag-5'>SDK</b>軟件架構及softdevice工作原理

    如何調(diào)試nRF5 SDK

    本文將講述Nordic nRF5 SDK的主要調(diào)試手段,以幫助大家快速定位問題,并解決問題。一般來說,你可以通過打log方式,IDE的debug模式,SDK自帶的app_error_check函數(shù)
    的頭像 發(fā)表于 06-24 08:59 ?1122次閱讀
    如何調(diào)試<b class='flag-5'>nRF</b>5 <b class='flag-5'>SDK</b>

    nRF Connect SDK 使用 nPM2100 評估套件 (PCA10170) 為 nPM2100 電源管理 IC (PMIC) 的開發(fā)

    and libraries nRF Connect SDK 提供了多個 PMIC 示例 ,演示了使用 nPM2100 EK 的 nPM2100 的特性和功能。 nRF
    的頭像 發(fā)表于 07-28 17:48 ?833次閱讀
    <b class='flag-5'>nRF</b> <b class='flag-5'>Connect</b> <b class='flag-5'>SDK</b> 使用 nPM2100 評估套件 (PCA10170) 為 nPM2100 電源管理 IC (PMIC) 的開發(fā)

    【Nordic隨筆】從零開始學習使用nRF Connect SDK(一、安裝ncs3.2.0步驟)

    本文章主要是介紹一些沒有使用過Nordic的nRF Connect SDK的環(huán)境搭建教學。
    的頭像 發(fā)表于 12-28 15:03 ?2180次閱讀
    【Nordic隨筆】從零開始學習使用<b class='flag-5'>nRF</b> <b class='flag-5'>Connect</b> <b class='flag-5'>SDK</b>(一、安裝ncs3.2.0步驟)

    Nordic nRF Connect SDK裸機選項v1.0.0版本的亮點

    我們近期發(fā)布了nRF Connect SDK裸機選項的新版本(v1.0.0)。本次更新帶來了令人興奮的新功能和改進,希望您會喜歡。
    的頭像 發(fā)表于 01-16 11:18 ?1333次閱讀
    抚州市| 云和县| 绥宁县| 沅江市| 紫金县| 邵阳市| 电白县| 石台县| 洮南市| 宽城| 甘德县| 东源县| 高青县| 建昌县| 邯郸市| 平昌县| 铜陵市| 寿阳县| 林芝县| 中牟县| 佛学| 揭东县| 嫩江县| 曲水县| 平和县| 咸阳市| 永嘉县| 拉萨市| 湘阴县| 香港 | 平度市| 沁源县| 丰顺县| 偏关县| 惠来县| 鹿泉市| 崇仁县| 得荣县| 裕民县| 泰兴市| 汉川市|