Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
I2C_IIC
【分享】使用RT-Thread I2C 设备框架读取光环境传感器BH1750
发布于 2019-09-18 10:25:53 浏览:3212
订阅该版
[tocm] * 本帖最后由 Mculover666 于 2019-9-18 10:27 编辑 * # 1. 裸机HAL驱动 裸机驱动可以参考我的博客:[【STM32Cube_14】使用硬件I2C读写环境光强度传感器(BH1750)](https://www.mculover666.cn/2019/08/04/2-STM32Cube/【STM32Cube-14】使用硬件I2C读取环境光强度传感器数据(BH1750)/)。 # 2. menuconfig 配置说明 在小熊派开发板的BSP中(`rt-thread\bsp\stm32\stm32l431-iotclub-bearpi`)右键,选择`ConEmu Here`,输入 `menuconfig` 打开 menuconfig 配置工具: ![FastAdmin](http://mculover666.cn/image/20190830/W4V7PBBmsYSY.png) ## 2.1. 开启 IIC 硬件(软件模拟IIC) 进入 `Hardware Drivers Config → On-chip Peripheral Drivers` 配置,然后开启 IIC 硬件外设驱动: ![FastAdmin](http://mculover666.cn/image/20190916/sY9snpeuJ8Co.png) ## 2.2. 开启 RT-Thread 通用IIC设备驱动框架(I/O设备管理层) >在上一步中使能 IIC 硬件后,**配置工具会自动开启使用通用 IIC 设备驱动框架**,这里仅仅是为了演示如何手动开启! 进入`RT-Thread Components → Device Drivers` 配置,可以看到 RT-Thread 通用 IIC 设备驱动已经开启: ![FastAdmin](http://mculover666.cn/image/20190916/4oeclvVMjNRJ.png) ## 2.3. 保存配置退出并生成工程 UART硬件驱动层和 RT-Thread IIC 设备管理层已经开启,接下来保存配置退出,然后使用如下命令生成工程,在 MDK 中编写用户层代码 ``` scons --target=mdk5 ``` # 3. 检查 IIC 设备是否成功注册 打开生成的 MDK 工程即可看到相关的文件: ![FastAdmin](http://mculover666.cn/image/20190916/MNu3zfh0NPta.png) 然后编译整个工程,下载到开发板中,在串口终端可以看到RT-Thread打印的信息。 在串口终端中输入 `list_device` 查看当前注册到内核的设备: ![FastAdmin](http://mculover666.cn/image/20190916/qe3N5Olticll.png) # 4. 调用 API 编写应用层代码 ## 4.1. I/O 设备驱动框架提供的API >API 参考自RT-Thread官方文档! 应用程序通过 RT-Thread提供的 I/O 设备管理框架提供的 API 来访问IIC硬件,这些 API 存放在`rt-thread\components\drivers\include\drivers\i2c.h` 文件中,所以**要想使用这些 API, 首先要包含头文件**: ```c #include
``` 提供的API列表如下: |API|功能| |:---:|:---:| |rt_device_find|根据 I2C 总线设备名称查找设备获取设备句柄| |rt_i2c_transfer|传输数据(可以发送,也可以接收)| |rt_i2c_master_send|发送数据| |rt_i2c_master_recv|接收数据| 其中,重点是 API `rt_i2c_transfer`,其说明如下: API原型: ```c rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num); ``` 参数说明: |参数 |描述| |:--:|:--:| |bus |I2C 总线设备句柄| |msgs[] |待传输的消息数组指针| |num |消息数组的元素个数| |返回值 |——| |消息数组的元素个数| 成功| |错误码 |失败| I2C 消息数据结构原型如下: ```c struct rt_i2c_msg { rt_uint16_t addr; /* 从机地址 */ rt_uint16_t flags; /* 读、写标志等 */ rt_uint16_t len; /* 读写数据字节数 */ rt_uint8_t *buf; /* 读写数据缓冲区指针 */ } ``` 从机地址支持7位或者10位,默认是** 7 位**,并且**不包括读写位**,读写位控制需修改标志 flags。 标志 flags 可取值为以下宏定义,根据需要可以与其他宏使用位运算 “|” 组合起来使用: ```c #define RT_I2C_WR 0x0000 /* 写标志 */ #define RT_I2C_RD (1u << 0) /* 读标志 */ #define RT_I2C_ADDR_10BIT (1u << 2) /* 10 位地址模式 */ #define RT_I2C_NO_START (1u << 4) /* 无开始条件 */ #define RT_I2C_IGNORE_NACK (1u << 5) /* 忽视 NACK */ #define RT_I2C_NO_READ_ACK (1u << 6) /* 读的时候不发送 ACK */ ``` ## 4.2. 读取BH1750数据 ### 实验代码 ```c #include
#include
#define BH1750_I2C_BUS_NAME "i2c1" /* 传感器连接的I2C总线设备名称 */ #define BH1750_ADDR 0x23 /* 从机地址 */ typedef enum { POWER_OFF_CMD = 0x00, //断电:无激活状态 POWER_ON_CMD = 0x01, //通电:等待测量指令 RESET_REGISTER = 0x07, //重置数字寄存器(在断电状态下不起作用) CONT_H_MODE = 0x10, //连续H分辨率模式:在11x分辨率下开始测量,测量时间120ms CONT_H_MODE2 = 0x11, //连续H分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms CONT_L_MODE = 0x13, //连续L分辨率模式:在411分辨率下开始测量,测量时间16ms ONCE_H_MODE = 0x20, //一次高分辨率模式:在11x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式 ONCE_H_MODE2 = 0x21, //一次高分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式 ONCE_L_MODE = 0x23 //一次低分辨率模式:在411x分辨率下开始测量,测量时间16ms,测量后自动设置为断电模式 } BH1750_MODE; static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */ /** * @brief 向BH1750发送一条指令 * @param cmd —— BH1750工作模式指令(在BH1750_MODE中枚举定义) * @retval 成功返回RT_EOK */ rt_err_t BH1750_Send_Cmd(BH1750_MODE cmd) { struct rt_i2c_msg msgs; msgs.addr = BH1750_ADDR; msgs.flags = RT_I2C_WR; msgs.len = 1; msgs.buf = (rt_uint8_t*)&cmd; /* 调用I2C设备接口传输数据 */ if (rt_i2c_transfer(i2c_bus, &msgs, 1) == 1) { return RT_EOK; } else { return -RT_ERROR; } } /** * @brief 从BH1750接收一次光强数据 * @param dat —— 存储光照强度的地址(两个字节数组) * @retval 成功 —— 返回RT_EOK */ rt_err_t BH1750_Read_Dat(rt_uint8_t* dat) { struct rt_i2c_msg msgs; msgs.addr = BH1750_ADDR; msgs.flags = RT_I2C_RD; msgs.len = 2; msgs.buf = dat; /* 调用I2C设备接口传输数据 */ if (rt_i2c_transfer(i2c_bus, &msgs, 2) == 2) { return RT_EOK; } else { return -RT_ERROR; } } /** * @brief 将BH1750的两个字节数据转换为光照强度值(0-65535) * @param dat —— 存储光照强度的地址(两个字节数组) * @retval 成功 —— 返回光照强度值 */ rt_uint16_t BH1750_Dat_To_Lux(rt_uint8_t* dat) { rt_uint16_t lux = 0; lux = dat[0]; lux <<= 8; lux += dat[1]; lux = (int)(lux / 1.2); return lux; } void i2c_bh1750_example_entry(void *parameter) { rt_uint8_t dat[2] = {0}; //dat[0]是高字节,dat[1]是低字节 /* 查找I2C总线设备,获取I2C总线设备句柄 */ i2c_bus = (struct rt_i2c_bus_device*)rt_device_find(BH1750_I2C_BUS_NAME); if(i2c_bus == RT_NULL) { rt_kprintf("can't find %s device!
", BH1750_I2C_BUS_NAME); } while(1) { /* 发送命令设置模式 */ BH1750_Send_Cmd(ONCE_H_MODE); /* 等待数据转换完成 */ rt_thread_mdelay(150); /* 读取数据 */ BH1750_Read_Dat(dat); /* 转换数据并打印 */ rt_kprintf("current: %5d lux
", BH1750_Dat_To_Lux(dat)); rt_thread_mdelay(1000); } } int i2c_bh1750_example(void) { rt_thread_t tid; //线程句柄 tid = rt_thread_create("bh1750_thread", i2c_bh1750_example_entry, RT_NULL, 512, 9, 10); if(tid != RT_NULL) { //线程创建成功,启动线程 rt_thread_startup(tid); } return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(i2c_bh1750_example, i2c bh1750 example); ``` ### 实验结果 ![FastAdmin](http://mculover666.cn/image/20190917/7xYlFgxd9VK3.png)
查看更多
4
个回答
默认排序
按发布时间排序
Mculover666
2019-09-18
这家伙很懒,什么也没写!
>感谢分享! >另外官方也有BH1750的软件包,也可以试着用用看~:http://packages.rt-thread.org/itemDetail.h ... --- 好东西:victory:
赛亚人
2019-09-26
这家伙很懒,什么也没写!
if (rt_i2c_transfer(i2c_bus, &msgs, 2) == 2) 这里参数写错了吧,最后一个参数是msg个数,不是msg中buf长度
Mculover666
2019-09-27
这家伙很懒,什么也没写!
>if (rt_i2c_transfer(i2c_bus, &msgs, 2) == 2) > >这里参数写错了吧,最后一个参数是msg个数,不是msg中buf ... --- 确实写错了,谢谢提醒
撰写答案
登录
注册新账号
关注者
0
被浏览
3.2k
关于作者
Mculover666
这家伙很懒,什么也没写!
提问
10
回答
14
被采纳
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组件
最新文章
1
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
2
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
3
RT-Thread EtherKit开源以太网硬件正式发布
4
如何在master上的BSP中添加配置yml文件
5
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
热门标签
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
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
a1012112796
20
个答案
3
次被采纳
张世争
11
个答案
3
次被采纳
踩姑娘的小蘑菇
7
个答案
3
次被采纳
rv666
9
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部