Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
I2C_IIC
nuc980
RT-Thread Studio
【NK-980IoT评测】RT-Thread I2C应用实践
发布于 2022-04-02 19:45:37 浏览:1077
订阅该版
[tocm] # 0. 前言 ## 0.1 开发板简介 > NK-980IoT是一块基于NUC980DK61Y微处理器(内核为ARM® ARM926EJ-S)的开发板, > 它具有非常丰富的外设,可以帮助用户轻松设计他们的产品或应用系统。 开发板的正面美图如下所示。 ![0-NK-980IoT美图.png](https://oss-club.rt-thread.org/uploads/20220402/25c3c7e73ddf4e7722c49a8e57972328.png.webp) 关于开发板的板载资源,Nuvoton官方提供了一份开发板配套的“User Manual”,详细地介绍了板载硬件及其连接的GPIO引脚。见下方共享的腾讯文档链接: 【腾讯文档】User_Manual_NK-980IoT_EN_Rev1.00 https://docs.qq.com/pdf/DWmhEZW1rbXVoVnBm ## 0.2 实验环境介绍 本篇博文主要基于RT-Thread测试NK-980 IoT开发板的I2C外设性能,现将相关实验环境介绍如下: ### 0.2.1 硬件环境 ● 开发板:Nuvoton NK-980 IoT ● USB线:Micro-USB 连接线 2 根 ● I2C外设资源:I2C2_SCL - PB5 | I2C2_SDA - PB7 ● 传感器:BH1750光照 | AHT10温湿度 | SGP30二氧化碳 自制传感器电路板,利用I2C的总线特性,将多个传感器并联在一条I2C总线上,电路板实物图如下所示。 ![0-传感器PCB板.jpg](https://oss-club.rt-thread.org/uploads/20220402/d4ca6012872a10d96ab00c24f59153ed.jpg.webp) ### 0.2.2 软件环境 ● IDE:RT-Thread Studio ● BSP:Nuvoton NK-980IoT for RT-Thread ● Programmer:Nuvoton NuWriter V1.16 ● Bootloader:uboot for NUC980DK61Y(位于rt-thread\bsp\nuvoton\nk-980iot\uboot) ● UART Console:MobaXterm # 1. I2C简介 I2C(Inter Integrated Circuit)总线是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。I2C 总线传输数据时只需两根信号线,一根是双向数据线 SDA(serial data),另一根是双向时钟线 SCL(serial clock)。SPI 总线有两根线分别用于主从设备之间接收数据和发送数据,而 I2C 总线只使用一根线进行数据收发。 I2C 和 SPI 一样以主从的方式工作,不同于 SPI 一主多从的结构,它允许同时有多个主设备存在,每个连接到总线上的器件都有唯一的地址,主设备启动数据传输并产生时钟信号,从设备被主设备寻址,同一时刻只允许有一个主设备。如下图所示: ![1-i2c简介.png](https://oss-club.rt-thread.org/uploads/20220402/7bf51075943e41182daa4f648149c26b.png) # 2. RT-Thread I2C设备驱动使用说明 ## 2.1 RT-Thread的I/O设备模型框架 绝大部分的嵌入式系统都包括 I/O 设备,如:显示屏、串行通信接口、以太网接口、SPI接口、I2C接口等。基于上述特性,RT-Thread 提供了一套简单的 I/O 设备模型框架,它位于硬件和应用程序之间,共分为三层,自上而下分别是【I/O 设备管理层】、【设备驱动框架层】和【设备驱动层】,如下图所示。 ![2-io-dev模型框架.png](https://oss-club.rt-thread.org/uploads/20220402/5722a196503e198c48012a39f6354c8d.png) 从上图可以清晰地看到与I2C接口相关的内容。 ## 2.2 访问I2C总线设备 ### 2.2.1 I2C总线设备主从关系 一般情况下,在一条I2C总线中 MCU 与 I2C 器件以主从方式进行通信,MCU 为主机,I2C 器件(如:OLED显示屏)为从机。 RT-Thread 将 I2C 主机抽象为 I2C 总线,I2C 从机则作为一个 I2C 设备挂接在某 I2C 总线上。 ### 2.2.2 RT-Thread I2C相关接口函数 RT-Thread 提供了下列两个I2C相关的接口函数。 ![i2c接口函数.jpg](https://oss-club.rt-thread.org/uploads/20220402/eefc4d2d94d7bbfd0e0324666a3734a8.jpg) 上述函数的具体内容请参考官方文档,在此不赘述: [访问I2C总线设备](I2C总线设备 (rt-thread.org) I2C 总线的自定义传输接口传输的数据也是以一个消息为单位。参数 msgs[] 指向待传输的消息数组,用户可以自定义每条消息的内容,实现 I2C 总线所支持的 2 种不同的数据传输模式。如果主设备需要发送重复开始条件,则需要发送 2 个消息。 I2C 消息数据结构原型如下: ```c struct rt_i2c_msg { rt_uint16_t addr; /* 从机地址 */ rt_uint16_t flags; /* 读、写标志等 */ rt_uint16_t len; /* 读写数据字节数 */ rt_uint8_t *buf; /* 读写数据缓冲区指针 */ } ``` # 3. 测试NK-980IoT的I2C性能 ## 3.1 NUC980微控制器的I2C特性 根据NUC980系列MCU的技术参考手册,其I2C串行接口控制器具有以下特性: ● 支持最多三个I2C端口 ● 主/从模式 ● 主站和从站之间的双向数据传输 ● 多主站总线(无中央主站) ● 支持标准模式(100 kbps)、快速模式(400 kbps)和快速模式+(1 Mbps)。 ● 在同时传输的主站之间进行仲裁,不会破坏总线上的串行数据 ● 串行时钟同步允许具有不同比特率的设备通过一个串行总线进行通信 ● 内置14位超时计数器,在I2C总线挂起和定时器输出计数器溢出时请求I2C中断 ● 可编程时钟可实现多种速率控制 ● 支持7位寻址和10位寻址模式 ● 支持多地址识别(四个带掩码的从属地址)。 ● 支持断电唤醒功能 ● 支持设置/保持时间程序 NK-980 IoT开发板上将 I2C2 接口引出,本篇评测将使用以下接口。 ![3-开发板上i2c2接口.jpg](https://oss-club.rt-thread.org/uploads/20220402/1f34f28c89fdbcc41a41c2682952f3f1.jpg.webp) 从上面的表格可以看到 I2C2_SDA 引脚连接于PB7,位于板上“NU2”接口第9脚,I2C2_SCL 引脚连接于PB5,位于板上“NU2”接口第10脚。 ## 3.2 硬件环境搭建 使用杜邦线将开发板与传感器板相连,效果如下图所示。 ![4-连接开发板与传感器板.jpg](https://oss-club.rt-thread.org/uploads/20220402/66d3ab80174012aa5cace6094ad030e2.jpg.webp) 在本篇应用实践中,各I2C硬件的主从关系见下表,各设备均挂载在 I2C2 总线上。 ![i2c各设备地址主从关系.jpg](https://oss-club.rt-thread.org/uploads/20220402/ad3476e0098ff9b834111127cb38c8cc.jpg) ## 3.3 为工程添加软件包 ### 3.3.1 添加BH1750软件包 在工程中双击“RT-Thread Settings”,在弹出的窗口中选择“Add”,即可打开软件包添加的界面。在关键字中输入“BH1750”,找到软件包后添加,具体如下图所示。 ![添加bh1750软件包.jpg](https://oss-club.rt-thread.org/uploads/20220402/dde66da0288bb5ed86ec2eaa43135be0.jpg.webp) ### 3.3.2 添加AHT10软件包 在工程中双击“RT-Thread Settings”,在弹出的窗口中选择“Add”,即可打开软件包添加的界面。在关键字中输入“AHT10”,找到软件包后添加,具体如下图所示。 ![添加aht10软件包.jpg](https://oss-club.rt-thread.org/uploads/20220402/9245e4c571c66b832d46878e45460a7a.jpg.webp) ### 3.3.3 添加SSD1306软件包 在工程中双击“RT-Thread Settings”,在弹出的窗口中选择“Add”,即可打开软件包添加的界面。在关键字中输入“SSD1306”,找到软件包后添加,具体如下图所示。 ![2b7a40c36f0fae0d46429ed72e9e620b.jpg.webp](https://oss-club.rt-thread.org/uploads/20220402/2b7a40c36f0fae0d46429ed72e9e620b.jpg.webp) SSD1306软件包需要进行少许配置,将鼠标移到SSD1306软件包后,点击“Configs”,即可打开配置界面。按照下图所示进行配置。 ![配置ssd1306软件包.jpg](https://oss-club.rt-thread.org/uploads/20220402/63827e00f3d15309871cbf4ba4d7e33d.jpg.webp) 注:上图中需要注意配置I2C地址、I2C总线号以及使能Sample程序。 ## 3.4 编写传感器读取APP程序 BH1750与AHT10软件包默认不带Sample程序,因此需要用户自己编写传感器读取App程序。 ### 3.4.1 编写BH1750传感器读取程序 在工程“applications”文件夹下创建"app_bh1750.c"文件,键入下列程序: ```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2021-09-24 sulig the first version */ #include
#include
#include
#define DBG_TAG "bh1750" #define DBG_LVL DBG_LOG #include
static rt_thread_t tbh17501 = RT_NULL; #define THREAD_PRIORITY 8 #define THREAD_STACK_SIZE 2048 #define THREAD_TIMESLICE 5 /* * 光照度数据采集 */ static void thread_tbh1750_entry1(void *parameter) { rt_device_t dev = RT_NULL; struct rt_sensor_data light; // float light_value = 0.0; int inte_value = 0, deci_value = 0; rt_size_t res; dev = rt_device_find("li_bh1750"); if (dev == RT_NULL) { LOG_E("can't find device: li_bh1750."); return; } if (rt_device_open(dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK) { LOG_E("open li_bh1750 device failed."); return; } while (1) { /* read light data once from bh1750 */ res = rt_device_read(dev, 0, &light, 1); if (res != 1) { LOG_E("read bh1750 light failed. size = %d", res); } else { inte_value = light.data.light / 10; deci_value = light.data.light % 10; LOG_I("Light:%4d.%d lux.\n", inte_value, deci_value); } rt_thread_mdelay(5000); } } static int app_bh1750(void) { // BH1750光照度线程 tbh17501 = rt_thread_create("tbh1750", thread_tbh1750_entry1, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tbh17501 != RT_NULL) rt_thread_startup(tbh17501); return RT_EOK; } INIT_APP_EXPORT(app_bh1750); ``` ### 3.4.2 编写AHT10传感器读取程序 在工程“applications”文件夹下创建"app_aht10.c"文件,键入下列程序: ```c // 使用AHT10范例 #include "sensor_asair_aht10.h" #define AHT10_I2C_BUS "i2c2" // AHT10温湿度采集 #include "aht10.h" // AHT10端口初始化 int rt_hw_aht10_port(void) { struct rt_sensor_config cfg; cfg.intf.dev_name = AHT10_I2C_BUS; cfg.intf.user_data = (void *)AHT10_I2C_ADDR; rt_hw_aht10_init("aht10", &cfg); return RT_EOK; } /* 定义一个温湿度采集线程句柄结构体指针 */ static rt_thread_t aht10_thread = RT_NULL; float humidity, temperature; /* 温湿度采集线程入口函数*/ static void aht10_thread_entry(void *parameter) { rt_err_t res; aht10_device_t dev; rt_hw_aht10_port(); dev = aht10_init(AHT10_I2C_BUS); if (dev == RT_NULL) { rt_kprintf(" The sensor initializes failure"); return; } else { rt_kprintf(" The sensor initializes ok!"); } while (1) { /* read humidity 采集湿度 */ humidity = aht10_read_humidity(dev); rt_kprintf("humidity : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10); /* former is integer and behind is decimal */ /* read temperature 采集温度 */ temperature = aht10_read_temperature(dev); rt_kprintf("temperature: %d.%d \n", (int)temperature, (int)(temperature * 10) % 10); /* former is integer and behind is decimal */ rt_thread_mdelay(5000); } } static int app_aht10_init(void) { rt_err_t rt_err; /* 创建温湿度采集线程*/ aht10_thread = rt_thread_create("aht10 thread",/* 线程的名称 */ aht10_thread_entry,/* 线程入口函数 */ RT_NULL,/* 线程入口函数的参数 */ 1024,/* 线程栈大小,单位是字节 */ 8,/* 线程的优先级*/ 10);/* 线程的时间片大小 */ /* 如果获得线程控制块,启动这个线程 */ if (aht10_thread != RT_NULL) rt_err = rt_thread_startup(aht10_thread); else rt_kprintf("aht10 thread create failure !!! \n"); /* 判断线程是否创建成功 */ if (rt_err != RT_EOK) rt_kprintf("aht10 thread startup err. \n"); return RT_EOK; } INIT_APP_EXPORT(app_aht10_init); ``` ## 3.5 编译并烧写固件 按下“CTRL+B”按键完成程序编写,完成“rtthread.bin”固件的烧写。 ## 3.6 程序执行结果 本工程中SSD1306的程序需要通过控制台命令启动,在控制台中输入以下命令: - ssd1306_testAll ### 3.6.1 传感器数据读取效果 温湿度和光照度传感器数据读取效果如下图所示。 ![10-传感器数据读取效果mobaxterm.jpg](https://oss-club.rt-thread.org/uploads/20220402/36e4edbd80d1691a8cab3f8b485702f3.jpg.webp) ### 3.6.2 OLED屏幕显示效果 OLED屏幕显示效果如下。 ![4-连接开发板与传感器板.jpg](https://oss-club.rt-thread.org/uploads/20220402/66d3ab80174012aa5cace6094ad030e2.jpg.webp) 可以看到屏幕上的画面每隔一段时间切换一次。 [代码工程gitee仓库链接](https://gitee.com/mxdx-aiot/nk980iot-rtt-std) [B站演示视频地址](https://www.bilibili.com/video/BV1cP4y1K7R1/) # 4. 心得体会 本篇应用实践对NK-980IoT开发板的I2C特性进行的评测,得出以下结论: - NUC980微控制器的 I2C 性能良好,各传感器正常读取数据,屏幕显示效果正常; - NUC980微控制器的 I2C 总线挂接设备的性能良好。经测试,可同时挂接3个传感器。在测试过程中发现有几点需要注意的。 - 一是挂接多个设备时,供电电流应充足,否则可能造成某个设备无法工作的不稳定现象。 - 二是挂接在同一条I2C总线上的各个设备地址应具备唯一性,否则读取时将产生冲突。 - 官方针对NUC980移植的RT-Thread I2C驱动程序框架暂时未发现bug; - 最重要的一点:感觉学会了RT-Thread就学会了所有的单片机(前提是:单片机生产厂商针对RT-Thread移植好相关外设驱动程序。
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
iotfans
满血工作中……
文章
3
回答
1
被采纳
0
关注TA
发私信
相关文章
1
NXP的I2C应该比ST的好用吧
2
Use of I2C device driver
3
关于I2C 驱动问题请教
4
我如何知道这个iic的io配置和我电路设计的是一致的?
5
I2C模拟读操作失败,不知道问什么进不去读函数
6
RTT的I2C有官方文档资料没有
7
求 STM32F103 IIC 自定义IO初始化 代码
8
报一个LPC4008代码中I2C的bug
9
RTOS IIC总线使用
10
关于在RTT中使用STM32 I2C的疑问
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部