0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32L051上使用RT-Threa (三、I2C通讯)

矜辰所致 来源:矜辰所致 作者:矜辰所致 2022-06-27 10:32 次阅读
应用篇-在STM32L051上使用RT-Thread 第三篇,学习RT-Thread Studio如何添加自定义的.c .h文件,
同时开始我们的程序移植和设计。

目录

前言
一、RT-Thread Studio添加自定义的.c .h文件

1.1 在现有文件夹下添加
1.2 新建文件夹添加
1.2.1 手动添加路径
1.2.1 使用`SConscript`脚本添加

二、I2C驱动移植

2.1 移植步骤
2.2 使用测试
2.3 好多的问题= =!
问题的解决
2.4 RT-Thread nano打印浮点数

三、时刻关注占RAM大小
结语

前言

经过前面两篇文章的准备,我们终于可以开始写应用代码了,在添加我们自己的驱动文件之前,本文会说明一下 RT-Thread Studio 如何添加自己的.c 和 .h文件。

然后在此基础上,完成 SHT21 温湿度传感器的 I2C 驱动移植。

❤️
本 RT-Thread 专栏记录的开发环境:
RT-Thread记录(一、RT-Thread 版本、RT-Thread Studio开发环境 及 配合CubeMX开发快速上手)
RT-Thread记录(二、RT-Thread内核启动流程 — 启动文件和源码分析)
❤️
RT-Thread 内核篇系列博文链接:
RT-Thread记录(三、RT-Thread 线程操作函数及线程管理与FreeRTOS的比较)
RT-Thread记录(四、RT-Thread 时钟节拍和软件定时器
RT-Thread记录(五、RT-Thread 临界区保护)
RT-Thread记录(六、IPC机制之信号量、互斥量和事件集)
RT-Thread记录(七、IPC机制之邮箱、消息队列)
RT-Thread记录(八、理解 RT-Thread 内存管理)
RT-Thread记录(九、RT-Thread 中断处理与阶段小结)
❤️
在STM32L051C8 上使用 RT-Thread 应用篇系列博文连接:
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (一、无线温湿度传感器 之 新建项目)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (二、无线温湿度传感器 之 CubeMX配置)

一、RT-Thread Studio添加自定义的.c .h文件

使用RT-Thread Studio添加自定义的.c .h文件有多种方式,本文根据博主的实际测试,分别说明一下。

1.1 在现有文件夹下添加

直接在工程现有的文件夹下面右击,选择新建头文件或者源文件,如下图:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

添加完成以后就可以直接编译了,上面我在 cubemx 文件夹下的Src 和 Inc 下分别添加了i2c.c和两个头文件,直接编译会关联进去的:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

但是这里得说明下,cubemx 是通过SConscript受SCons 构建工具管理的,所以直接这样添加的话,每次我们自己增加一个.c文件,需要在 SConscript 文件中增加对应部分,要不然同步一下scons,不相关的.c文件就会被排除构建:

poYBAGK4LO-ATvJ4AAAR9NJaT5c314.png

当然我们也可以在其他文件夹下添加,比如 drivers 文件夹,里面.c.h文件是混在一起,我们也可以直接在这里面新建,如下图:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_12,color_FFFFFF,t_70,g_se,x_16

总结一下,在现有文件夹下面添加是比较方便的一种方式,因为项目整体的构建系统已经处理好了这些文件下的.c.h文件的包含关系,我们不用再进行添加头文件路径这种操作。
但是这种方式会影响项目原始框架,小项目的文件少倒是无所谓,文件多了的话就很乱了。

1.2 新建文件夹添加

所以我们要讲一下如果新建文件夹放置我们自己的驱动程序应该怎么做。

首先,还是右击选择新建文件夹,然后出选择文件夹放置的位置,输入文件夹名字:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

新建好以后,我们在左边资源管理器可以看到有文件夹了,我们可以通过上面 1.1小节的内容添加文件,也可以直接打开文件夹所在的目录,直接把我们要的文件复制过来,如下图:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

新建文件夹复制文件过来,不做任何操作直接编译,可以参与编译:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

但是要备其他文件夹中的文件包含,需要添加头文件路径,如果不添加,会出现如下错误:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

1.2.1 手动添加路径

工程资源管理器界面右击点击构建配置,如下图:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_17,color_FFFFFF,t_70,g_se,x_16

然后按照下图所示步骤,把我们自己新建的头文件所在文件夹路径添加(和keil工具一样的添加)即可:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

1.2.1 使用SConscript脚本添加

在自己想要放驱动的文件夹下面新建一个SConscript脚本,如下图:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

然后把自己想添加的.c.h文件放在对应文件夹下面,新建完成刷新工程,然后再右击,选择“同步scons配置至项目”即可,脚本会把该文件路径自动添加至编译的路径中。

脚本内容如下:

from building import *

cwd     = GetCurrentDir()
src     = Glob('*.c') + Glob('*.S')

libpath = [cwd]
CPPPATH = [os.path.join(cwd)]
 
group = DefineGroup('mydrivers', src, depend = [''], CPPPATH = CPPPATH,LIBPATH = libpath)

Return('group')

二、I2C驱动移植

上面我们讲解了如果添加自己的驱动文件,那么我们就直接把以前驱动文件移植过来,因为 SHT21 的驱动文件,在我以前博文 STM32L051 和 nRF52832 专栏都说明过 SHT21的程序(等本次应用篇结束我会把最终的源码上传的):

STM32L051测试 (三、I2C协议设备的添加测试)

nRF52832学习记录(十一、TWI总线的应用 SHT21程序移植)

我们这里只是把裸机使用的文件改成在 RT-Thread 上使用的文件。

2.1 移植步骤

首先我们把驱动文件都拷贝过来(Datadef.h 是我个人习惯使用的一些数据类型宏定义):

pYYBAGK4LPKANqCnAAAcou4aCMo617.png

编译过后,还是正常通过除了上面报的那个延时函数的警告:

poYBAGK4LPKAZpSDAAA93sNpoAs334.png

这是因为delay_us()这个函数在HAL库中是没有的额,以前使用裸机的时候是我自己实现的,这里我们既然使用了 RT-Thread ,在我们《RT-Thread记录(四、RT-Thread 时钟节拍和软件定时器)》中正好介绍到过 RT-Thread 中有 us 延时函数,我们拿过来用用试试看。

我们把所有 delay_us 改成rt_hw_us_delay,记得包含一下头文件:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_15,color_FFFFFF,t_70,g_se,x_16

然后把文件驱动文件中中所有的HAL_Delay改成rt_thread_mdelay,比如:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_16,color_FFFFFF,t_70,g_se,x_16

感觉已经好了……那么接下来看看效果。

2.2 使用测试

上面我们驱动移植好了,我们直接来测试一下,这里我们还是新建一个线程把,这个温湿度读取的线程我根据经验,设置为192字节,然后每隔3s读取一次温湿度打印:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_18,color_FFFFFF,t_70,g_se,x_16

程序编译正常没有问题,但是跑起来出问题了…

2.3 好多的问题= =!

按键没有修改,上篇文章一样预留的:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_18,color_FFFFFF,t_70,g_se,x_16

虽然占用了7000多字节,但是应该还是有空间的,但是在程序运行直接报错:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_15,color_FFFFFF,t_70,g_se,x_16

key线程昨天测试的时候完全没问题啊,这里居然出错了,我考虑到今天也就多加了一个sht的线程,于是我将温湿度读取线程中的逻辑去掉,又出另外的问题提示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_17,color_FFFFFF,t_70,g_se,x_16

然后想着是不是刚启动的时候等一会读传感器,没有为什么,讲不出道理= =!于是:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_17,color_FFFFFF,t_70,g_se,x_16

在这个时候我忽然想到浮点数的特殊性,以前记得使用 RT-Thread 遇到过,然后网上查了下确实,rt_kprintf是不能打印浮点数的,是不是浮点数的问题。

因为上面显示 sht21 线程栈溢出,说明线程栈给的不够,其实按照经验来说,是足够的,这里不管,那我给他增加线程栈看看结果,如下图:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_19,color_FFFFFF,t_70,g_se,x_16

好吧!还是有问题,没救了,先把浮点数的问题处理了吧。

改了一个不打印浮点数的,结果看图吧:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

这么看来,或许应该是驱动修改的问题吧,我首先想到的就是 us延时函数,那个延时函数有问题,于是我用了裸机中的干等函数……:

(后面证明不是这个原因,us延时函数可用)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

经验不管用,虽然在使用 FreeRTOS 的时候 192字节有余:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

但是在这里使用的时候,256字节大小都出错了,直到我继续增大:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_19,color_FFFFFF,t_70,g_se,x_16

问题的解决

到头来,原来是这个驱动函数在 RT-Thread 线程中需要的线程栈大小相对 FreeRTOS 来说大,因为有些堆栈溢出的问题导致报错也不一样,而且根据以前的使用经验,所以开始并没有一味的想着增大线程栈空间。

后来考虑了一下,对于驱动操作来说,都是基于STM32L051芯片,这部分应该差距不大,还有一个最能的原因是打印函数,我们以前就说过打印函数很占用内存空间,rt_kprintf 是 RT-Thread 自己实现的,是不是因为这个打印函数占用空间大导致的呢? 这个目前只是猜想,后期有机会来研究一下!

回过头切换回 RT-Thread 中的 us 延时函数,也测试成功了。

2.4 RT-Thread nano打印浮点数

1、虽然软件包中心,有一个名为rt_vsnprintf_full的软件包,可以打印浮点数,但是我们使用的 nano 版本并不能安装软件包……

RT-Thread_rt_kprintf()打印浮点数(解决方法2:添加rt_vsnprintf_full)

2、同样 nano 版本无法使用标准libc库……,所以无法使用vsnprintf替换rt_vsnprintf的方式:

RT-thread rt_kprintf()函数格式化输出浮点数

3、如果做一些其他修改,使其可以支持标准C库调用,会额外占用 RAM 空间:

rt-thread printf打印信息(包含打印浮点型float)

综合来说看了一圈,好吧,认输了! 打印不出来,不玩了,本次测试不太顺利……

最后还是用土方法,简单应付一下,因为后期并不需要打印,打印只是为了测试:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

三、时刻关注占RAM大小

本文就添加了一个 I2C驱动, 但是上面我们经过多次测试修改,温湿度测试线程也用到了384个字节,如果不打印出来,应该会小很多,我们后面肯定会来调整工程的。

那么还是老样子,今天测试完成以后和以前占用空间的对比图上一下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

加了温湿度读取线程以后,程序运行时候需要占用 RAM的大小: 7248 字节,我们的芯片 RAM:8192字节。

结语

本文我们了解了 RT-Thread Studio添加自定义的.c .h文件的方法,然后成功的把 I2C驱动移植过来。

虽然一个简单的移植,缺被一个基本的问题困扰了许久,再次强调一次,在线程中使用打印函数,是很占用RAM空间的行为,以前在使用操作系统的时候就知道这个问题。

本次测试,我推断在使用RT-Thread自己的rt_kprintf函数会比 C库 printf 占用更多内存空间(有错误请指出),也算是一个小收获。

然后就是使用 RT-Thread nano打印浮点数,虽然我最终还是样子上打印出了浮点数= =!我没有研究出比较满意的方式,也算是一个小遗憾,不过话说话来,打印大多数是为了测试,正常的项目跑起来,也不需要打印这些。

没想到本次测试这么折腾,有点累= =! 还望小伙伴多多支持,多多指教!

好了,本文就到这,谢谢大家!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 移植
    +关注

    关注

    1

    文章

    367

    浏览量

    27854
  • I2C
    I2C
    +关注

    关注

    28

    文章

    1346

    浏览量

    120813
  • RT-Thread
    +关注

    关注

    31

    文章

    1148

    浏览量

    38867
收藏 人收藏

    评论

    相关推荐

    STM32L051上使用RT-Thread (一、新建项目)

    学完了 RT-Thread 内核基础,来使用 RT-Thread 实现一个小应用。 硬件平台:STM32L051C8 TCM310(Enocean无线芯片) 软件平台:RT-Th
    的头像 发表于 06-25 20:45 5689次阅读
    <b class='flag-5'>STM32L051</b>上使用<b class='flag-5'>RT</b>-Thread (一、新建项目)

    STM32L051上使用RT-Th (二、CubeMX配置)

    应用篇-在STM32L051上使用RT-Thread 第二篇,使用STM32CubeMX 进行对应外设配置,同时做一些简单测试。
    的头像 发表于 06-26 14:02 3909次阅读
    <b class='flag-5'>STM32L051</b>上使用<b class='flag-5'>RT</b>-Th (二、CubeMX配置)

    STM32L051上使用RT-Thread (四、串口通讯

    应用篇-在STM32L051上使用RT-Thread 第四篇,巧妙的使用信号量处理串口通讯
    的头像 发表于 06-28 10:59 4598次阅读
    <b class='flag-5'>STM32L051</b>上使用<b class='flag-5'>RT</b>-Thread (四、串口<b class='flag-5'>通讯</b>)

    STM32L051上使用RT-Thread (五、完结篇)

    应用篇-在STM32L051上使用RT-Thread 第五篇,也是本次应用的完结篇。
    的头像 发表于 06-29 10:34 3376次阅读
    <b class='flag-5'>STM32L051</b>上使用<b class='flag-5'>RT</b>-Thread (五、完结篇)

    stm32l051 hal库如何使用硬件i2c从机?

    stm32l051 hal库如何使用硬件i2c从机,有没有相关参考程序。现在调试过程中一直进入AF错误,是什么原因导致的?
    发表于 03-27 08:24

    最简单的总线通讯I2C通讯总线的原理原来这么好懂

    通讯I2C
    安泰仪器维修
    发布于 :2024年01月02日 11:16:31

    基于STM32L051的可穿戴设备字库显示设计

    `12832OLED点阵STM32L051,显示屏0.91寸128*32OLED,LCD驱动芯片是SSD1306,字库显示采用高通GT24L24A2Y字库芯片,字库芯片主要用于实现OLED界面
    发表于 08-30 15:55

    请问STM32L051和071系列,哪款芯片比较常用?采购供货考虑

    目前在选型一款STM32L0系列芯片,请问STM32L051和071系列,哪款芯片比较常用?还有,STM32L051C8,071CB,071CZ大概量产价格?采购供货考虑。谢谢。
    发表于 11-26 08:55

    请问stm32f051 i2c需要外接上拉电阻吗?

    stm32f051i2c需要外接上拉电阻吗,直接用内部拉行不行,还有库中的I2C_Init函数中有这么一句/* Enable I2Cx
    发表于 03-12 07:14

    总结STM32L051的STOP模式

    本文总结下STM32L051的STOP模式,通过外部中断「按键、串口」进行唤醒。
    发表于 08-13 09:36

    怎样去使用STM32L051单片机

    怎样去使用STM32L051单片机?Period每隔多久执行一次?Timeout第一次什么时候执行?
    发表于 09-23 08:21

    求大佬分享STM32L051使用HAL库操作实例

    求大佬分享STM32L051使用HAL库操作实例
    发表于 11-26 06:47

    【原创精选】RT-Thread征文精选技术文章合集

    I2C通讯STM32L051使用RT-Thread (四、串口通讯
    发表于 07-26 14:56

    STM32L051进入停止模式时如何关闭IWDG?

    当我使用STM32L051时,它的iwdg和停止功能,进入停止模式后,iwdg也在工作,我想在停止时关闭iwdg,但我在FLASH_OPTR寄存器中没有找到“IWDG_STOP”的这一点,所以我不知道该怎么做,因为我在 STM8L051
    发表于 01-13 07:38

    【RTT征文精选】画板子、敲代码、玩RTOS、搞Linux,大家一起“秀”!

    //STM32L051上使用RT-Thread(一、新建项目)STM32L051上使用RT-Th(二、CubeMX配置)STM32L051
    的头像 发表于 08-25 09:56 425次阅读
    【RTT征文精选】画板子、敲代码、玩RTOS、搞Linux,大家一起“秀”!