Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
i2ctools
NXP 微控制器
NXP-MCXN236
NXP MCXN236测评-软件模拟I2C
发布于 2024-06-25 17:01:46 浏览:382
订阅该版
[tocm] ## 简介 本文介绍如何在FRDM-MCXN236 开发板上通过GPIO 模拟的I2C,使用i2ctool 工具扫描总线上的挂载的节点,并通过使用i2ctool 读写板子上自带的FXLS8974 传感器寄存器信息。 ## I2C硬件配置 FRDM-MCXN236 开发板上已经集成了个I2C传感器器件,本次的I2C 评测无需外接I2C设备直接使用板子自带的外设即可,板子上的I2C使用的是P4_0/P4_1(FLEXCOM2)接口,对应原理图如下: ![I2C_HW.png](https://oss-club.rt-thread.org/uploads/20240625/e5362530ce1b6e82e6b7789b79a3e69e.png.webp) ## I2C软件配置 - MCXNxxx 的bsp 驱动里只实现了硬件I2C的适配并没有适配软件GPIO模拟的I2C驱动实现,软件模拟的I2C 依赖pin 驱动,I2C的算法在rt-thread 中已经集成,我们只要实现依赖芯片相关的GPIO 配置即可,对应ops 定义如下 ```c struct rt_i2c_bit_ops { void *data; /* private data for lowlevel routines */ void (*set_sda)(void *data, rt_int32_t state); void (*set_scl)(void *data, rt_int32_t state); rt_int32_t (*get_sda)(void *data); rt_int32_t (*get_scl)(void *data); void (*udelay)(rt_uint32_t us); rt_uint32_t delay_us; /* scl and sda line delay */ rt_uint32_t timeout; /* in tick */ void (*pin_init)(void); rt_bool_t i2c_pin_init_flag; }; ``` - 适配软件I2C的过程就是填充上述结构成员,并构造一个对象注册到系统即可 set_sda/set_scl/get_sda/get_scl/udelay/pin_init 函数实现如下 ```c /** * @brief This function initializes the i2c pin. * @param i2c * @retval None */ static void mcxnxxx_i2c_gpio_init(struct mcxnxxx_i2c *i2c) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)i2c->ops.data; rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); rt_pin_write(cfg->scl, PIN_HIGH); rt_pin_write(cfg->sda, PIN_HIGH); } /** * @brief This function sets the sda pin. * @param data, state * @retval None */ static void mcxnxxx_set_sda(void *data, rt_int32_t state) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); if (state) { rt_pin_write(cfg->sda, PIN_HIGH); } else { rt_pin_write(cfg->sda, PIN_LOW); } } /** * @brief This function sets the scl pin. * @param data, state * @retval None */ static void mcxnxxx_set_scl(void *data, rt_int32_t state) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); if (state) { rt_pin_write(cfg->scl, PIN_HIGH); } else { rt_pin_write(cfg->scl, PIN_LOW); } } /** * @brief This function gets the sda pin state. * @param data * @retval None */ static rt_int32_t mcxnxxx_get_sda(void *data) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->sda, PIN_MODE_INPUT); return rt_pin_read(cfg->sda); } /** * @brief This function gets the scl pin state. * @param data * @retval None */ static rt_int32_t mcxnxxx_get_scl(void *data) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->scl,PIN_MODE_INPUT); return rt_pin_read(cfg->scl); } /** * @brief The time delay function. * @param us * @retval None */ static void mcxnxxx_udelay(rt_uint32_t us) { rt_uint32_t frequency = CLOCK_GetCoreSysClkFreq(); int i = (frequency/ 4000000 * us); while(i) { i--; } } static const struct rt_i2c_bit_ops mcxnxxx_bit_ops_default = { .data = RT_NULL, .set_sda = mcxnxxx_set_sda, .set_scl = mcxnxxx_set_scl, .get_sda = mcxnxxx_get_sda, .get_scl = mcxnxxx_get_scl, .udelay = mcxnxxx_udelay, .delay_us = 1, .timeout = 100 }; ``` - 注册上述的ops 函数到系统 ```c /** * @brief This function initializes the i2c pin. * @param i2c * @retval None */ static void mcxnxxx_i2c_gpio_init(struct mcxnxxx_i2c *i2c) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)i2c->ops.data; rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); rt_pin_write(cfg->scl, PIN_HIGH); rt_pin_write(cfg->sda, PIN_HIGH); } /** * @brief This function sets the sda pin. * @param data, state * @retval None */ static void mcxnxxx_set_sda(void *data, rt_int32_t state) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); if (state) { rt_pin_write(cfg->sda, PIN_HIGH); } else { rt_pin_write(cfg->sda, PIN_LOW); } } /** * @brief This function sets the scl pin. * @param data, state * @retval None */ static void mcxnxxx_set_scl(void *data, rt_int32_t state) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); if (state) { rt_pin_write(cfg->scl, PIN_HIGH); } else { rt_pin_write(cfg->scl, PIN_LOW); } } /** * @brief This function gets the sda pin state. * @param data * @retval None */ static rt_int32_t mcxnxxx_get_sda(void *data) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->sda, PIN_MODE_INPUT); return rt_pin_read(cfg->sda); } /** * @brief This function gets the scl pin state. * @param data * @retval None */ static rt_int32_t mcxnxxx_get_scl(void *data) { struct mcxnxxx_soft_i2c_config* cfg = (struct mcxnxxx_soft_i2c_config*)data; rt_pin_mode(cfg->scl,PIN_MODE_INPUT); return rt_pin_read(cfg->scl); } /** * @brief The time delay function. * @param us * @retval None */ static void mcxnxxx_udelay(rt_uint32_t us) { rt_uint32_t frequency = CLOCK_GetCoreSysClkFreq(); int i = (frequency/ 4000000 * us); while(i) { i--; } } static const struct rt_i2c_bit_ops mcxnxxx_bit_ops_default = { .data = RT_NULL, .set_sda = mcxnxxx_set_sda, .set_scl = mcxnxxx_set_scl, .get_sda = mcxnxxx_get_sda, .get_scl = mcxnxxx_get_scl, .udelay = mcxnxxx_udelay, .delay_us = 1, .timeout = 100 }; ``` - 基于mcxn236/board/Kconfig 更新配置添加softi2c 配置菜单 ```c diff --git a/bsp/nxp/mcx/mcxn/frdm-mcxn236/board/Kconfig b/bsp/nxp/mcx/mcxn/frdm-mcxn236/board/Kconfig index 93452d780e..44f287a0f2 100644 --- a/bsp/nxp/mcx/mcxn/frdm-mcxn236/board/Kconfig +++ b/bsp/nxp/mcx/mcxn/frdm-mcxn236/board/Kconfig @@ -53,6 +53,28 @@ menu "On-chip Peripheral Drivers" default y endif + menuconfig BSP_USING_SW_I2C + bool "Enable I2C BUS (software simulation)" + default n + select RT_USING_I2C + select RT_USING_I2C_BITOPS + select RT_USING_PIN + if BSP_USING_SW_I2C + config BSP_USING_SW_I2C0 + bool "Enable soft I2C0" + default y + if BSP_USING_SW_I2C0 + config BSP_SW_I2C0_SCL_PIN + int "SWI2C0 scl pin number" + range 0 159 + default 129 + config BSP_SW_I2C0_SDA_PIN + int "SWI2C0 sda pin number" + range 0 159 + default 128 + endif + endif + ``` - 修改Kconfig 后通过menuconfig 命令打开软件I2C配置 ![1111111.png](https://oss-club.rt-thread.org/uploads/20240625/09d00486e51f3463026bfc7cecd0cda7.png.webp) - 开启软件i2c后使用 “scons --target=iar” 生成工程烧写到板子内运行list device 命令发现swi2c0 bus 总线设备已经注册到系统内部了 ```c msh >list device device type ref count -------- -------------------- ---------- swi2c0 I2C Bus 0 pin Pin Device 0 uart5 Character Device 0 uart4 Character Device 2 uart2 Character Device 0 msh > ``` ## I2C功能验证 - Rt-thread 有着丰富的组件资源,验证I2C 功能可以使用i2ctool 工具来测试I2C 总线通信状况,通过如下路径开启软件包。 ![i2ctool.png](https://oss-club.rt-thread.org/uploads/20240625/21cc613523627cb944d57dbe3b9bbd2d.png.webp) - 配置完成后输入“ pkgs --update” 命令会通过网络下载源代码到本地,运行结果如下 ```c pkgs --update [Use Github server - auto decision based on IP location] Cloning into 'E:\rt-thread_github_andeyqi\bsp\nxp\mcx\mcxn\frdm-mcxn236\packages\rt_vsnprintf_full-latest'... remote: Enumerating objects: 9, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (9/9), done. remote: Total 9 (delta 0), reused 6 (delta 0), pack-reused 0 Receiving objects: 100% (9/9), 127.66 KiB | 375.00 KiB/s, done. ==============================> RT_VSNPRINTF_FULL latest is downloaded successfully. Cloning into 'E:\rt-thread_github_andeyqi\bsp\nxp\mcx\mcxn\frdm-mcxn236\packages\i2c-tools-latest'... remote: Enumerating objects: 18, done. remote: Counting objects: 100% (18/18), done. remote: Compressing objects: 100% (16/16), done. remote: Total 18 (delta 0), reused 11 (delta 0), pack-reused 0 Receiving objects: 100% (18/18), 2.00 MiB | 2.34 MiB/s, done. ==============================> I2C_TOOLS latest is downloaded successfully. E:\rt-thread_github_andeyqi\bsp\nxp\mcx\mcxn\frdm-mcxn236\packages\rt_vsnprintf_full-latest ==============================> rt_vsnprintf_full update done E:\rt-thread_github_andeyqi\bsp\nxp\mcx\mcxn\frdm-mcxn236\packages\i2c-tools-latest ==============================> i2c-tools update done Operation completed successfully. ``` - 使用“scons --target=iar” 重新生成工程发现工程目录下已经加入了i2ctool 的源码了 ![i2ctool_code.png](https://oss-club.rt-thread.org/uploads/20240625/53d9367546fb5c5f11b402d5b6a2f263.png.webp) - 编译发现i2ctool 源码是cpp 后缀的,会有如下编译错误 ![i2ctool_error.png](https://oss-club.rt-thread.org/uploads/20240625/33eedd4bf0a4bb520741f6c5cfdb9952.png.webp) - IAR 工程开启如下配置即可解决上述编译错误,默认配置编译器归把所有的文件按照c语言编译,配置修改为Auto自动根据文件扩展来识别文件为c或c++ ![fix_error.png](https://oss-club.rt-thread.org/uploads/20240625/64624de06f346cb0874bd2e80e31595a.png.webp) ## 使用i2c tool 验证I2C功能 加入i2ctool 工具后系统会集成i2c 命令,对应使用说明如下 ```c msh >i2c --------------- i2c tools help: --------------- i2c scan pin_sda pin_scl [start addr] [stop addr] i2c read pin_sda pin_scl address register [len=1] i2c write pin_sda pin_scl address [register] data_0 data_1 ... ``` 根据上面的原理图SCL 脚是P4_1 ,SDA 脚是P4_0 对应的引脚转换成PIN id 为129 和 128(对应公式为port*32+index) 输入 i2c scan 128 129 命令扫描i2c节点,发现扫描到0x18的节点,对应的为7bit 地址和板子上的I2C外设保持一致,说明软件I2C已经正常工作可以和芯片通信了。 ```c msh >i2c scan 128 129 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- msh > msh >i ``` 上述的测试是通过传入pin id 的方式来访问软件i2c,我们也可以通过访问总线的方式来访问i2c,修改i2ctool 配置关闭,重新生成IAR工程 ![ictool15005.jpg](https://oss-club.rt-thread.org/uploads/20240626/c96286df62fdac999220044d91cfe1bc.jpg) 此时就可以通过i2c 总线设备来访问i2c 总线设备了,访问方式如下 ```c msh >i2c --------------- i2c tools help: --------------- i2c scan bus_name [start addr] [stop addr] i2c read bus_name address register [len=1] i2c write bus_name address [register] data_0 data_1 ... ``` 此时输入 i2c scan swi2c0 命令检测到的节点存在状况和通过pin id 方式保持一致 ```c msh >i2c scan swi2c0 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- msh > ``` 使用i2c read 功能 查看原理图板子上的I2C 连接的芯片为NXP 的 FXLS8974CF 12位数字物联网加速度计,我们查看手册芯片的WHO_AM_I 寄存器代表的产品ID,我们读取该寄存器数值看看是否和手册的0X86保持一致,芯片手册上寄存器描述如下: ![acc.png](https://oss-club.rt-thread.org/uploads/20240626/258b2ebc33f6324577d0b0d6e3e64e86.png.webp) 输入“i2c read swi2c0 24 19” 命令读取寄存器返回结果如下,和芯片手册的0x86保持一致,从而验证I2C 读取功能OK ```c msh >i2c read swi2c0 24 19 [ 0x86 ] ``` 我们找个I2C可写入的寄存器,进行写入回读验证写功能,回读的数据和写入的一致说明通路都是ok的。 ```c msh >i2c read swi2c0 24 22 [ 0x00 ] msh >i2c write swi2c0 24 22 0xfb msh >i2c read swi2c0 24 22 [ 0xFB ] msh > ```
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
andeyqi
这家伙很懒,什么也没写!
文章
7
回答
6
被采纳
0
关注TA
发私信
相关文章
1
试贴-消灭0主题
2
LPC M4的一些资料
3
LPC4088的临时分支
4
lpc1788 ad 不稳定
5
1788 LCD控制器缓冲区字节问题
6
一起来学习LPC4088吧
7
上传LPC4088的realtouch主工程
8
RealBoard 4088预定帖 [第一批板子不多,预定提前结束]
9
晒RealBoard LPC4088开箱照啦,速带小板凳前来围观
10
4088主程序需要的SD卡资源
推荐文章
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
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
7
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部