RT-Thread Studio开发 新手入门

文章目录

  • 前言
  • 一、RT-Thread Studio 与 STM32CubeMX 下载安装
  • 二、新建工程
  • 三、点亮LED灯
  • 四、按键中断
  • 五、串口通信
  • 六、OLED显示


前言

软件开发环境:RT-Thread Studio、STM32CubeMX
硬件:STM32F407ZGT6

一、RT-Thread Studio 与 STM32CubeMX 下载安装

RT-Thread Studio 主要包括工程创建和管理,代码编辑,SDK管理,RT-Thread配置,构建配置,调试配置,程序下载和调试等功能,结合图形化配置系统以及软件包和组件资源,减少重复工作,提高开发效率。一站式的 RT-Thread 开发工具,通过简单易用的图形化配置系统以及丰富的软件包和组件资源,让物联网开发变得简单和高效。

STM32CubeMX是一种图形工具,通过分步过程可以非常轻松地配置STM32微控制器和微处理器,以及为Arm® Cortex®-M内核或面向Arm® Cortex®-A内核的特定Linux®设备树生成相应的初始化C代码

RT-Thread官网:https://www.rt-thread.org/studio.html
STM32CubeMX官网:https://www.st.com/zh/development-tools/stm32cubemx.html
在这里插入图片描述
在这里插入图片描述

默认安装即可。

二、新建工程

①进入RT-Thread Studio,左上角 文件–>新建–>RT-Thread项目
在这里插入图片描述

②填入工程信息并选择相应型号
在这里插入图片描述

③打开新建工程,双击RT-Thread Settings,在“组件和服务层”中单击ulog日志,随后再进行保存设置、编辑
在这里插入图片描述

④编译后可发现工程报错,双击错误可定位到具体位置,知为switch语句出现问题,屏蔽即可,不影响使用,然后重新编译
在这里插入图片描述

该段yiswitch代码是一个在串口初始化过程中处理流控制选项的代码片段。代码中的 switch 语句根据配置结构体 cfg 中的流控制选项 flowcontrol 的值进行判断,并根据不同的选项设置对应的串口硬件流控制模式。

流控制是一种在数据传输过程中进行流量控制的技术,用于协调发送方和接收方之间的数据传输速率,以避免数据丢失或溢出。在串口通信中,常见的流控制选项包括无流控制、硬件流控制(如 CTS/RTS)和软件流控制(如 XON/XOFF)。

⑤重新编译后,无警告报错,则 开始下载程序到单片机
在这里插入图片描述

⑥下载成功,观察main.c函数,可知为串口打印功能

在这里插入图片描述

⑦打开串口,测试代码
在这里插入图片描述

至此新建工程完成!

三、点亮LED灯

首先可以直接复制上节的工程,在其基础上进行修改,具体操作为:选中工程,Crtl+C → Ctrl+V, 然后修改项目名即可
在这里插入图片描述

①观察电路图
在这里插入图片描述

②获取led引脚编号

GET_PIN(port, pin);     

这里为 GET_PIN(F, 2)

③设置引脚模式

void rt_pin_mode(rt_base_t pin, rt_base_t mode);   

这里为 rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);

④设置引脚电平

void rt_pin_write(rt_base_t pin, rt_base_t value);     

由上图知为上拉,即低电平点亮,所以这里为 rt_pin_write(LED0_PIN, PIN_LOW);

综上,代码如下:

#include <rtthread.h>
#include <rtdbg.h>
#include <board.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG#define LED0_PIN    GET_PIN(F, 2)int main(void)
{/* set LED0 pin mode to output */rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);while (1){rt_pin_write(LED0_PIN, PIN_HIGH);rt_thread_mdelay(500);rt_pin_write(LED0_PIN, PIN_LOW);rt_thread_mdelay(500);}return RT_EOK;
}

这里分析一下较陌生的头文件和宏定义 :

#include <rtthread.h>:包含了 RT-Thread 实时操作系统的头文件。RT-Thread 是一个开源的实时操作系统,适用于嵌入式系统和物联网设备。

#include <rtdbg.h>:包含了 RT-Thread 调试宏的头文件。该头文件提供了一些用于调试和日志输出的宏定义和函数。

#include <board.h>:包含了与硬件板级支持相关的头文件。该头文件通常包含了与硬件平台相关的宏定义、函数声明和硬件初始化代码等

#define DBG_TAG "main":定义了一个名为 DBG_TAG 的宏,将其值设置为字符串 “main”。在后续的调试输出中,可以使用该宏来标记输出的日志标签。

#define DBG_LVL DBG_LOG:定义了一个名为 DBG_LVL 的宏,将其值设置为 DBG_LOG。该宏用于设置调试输出的级别,这里设置为输出所有级别的日志信息。

return RT_EOK:RT_EOK通常被定义为值为0的宏,表示操作成功完成。

四、按键中断

①观察电路图知都为上拉,默认高电平。
在这里插入图片描述

②获取led引脚编号

#define KEY1_PIN    GET_PIN(F, 5)

③设置引脚模式

rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT_PULLUP)

④设置引脚中断回调函数

rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args);

其中 pin为引脚编号,mode为中断触发模式,hdr为中断回调函数,args为中断回调函数参数,不需要时设置为RT_NULL

这里为设置为下降沿模式,回调函数名为led_on rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_FALLING , led_on, RT_NULL);

⑤使能中断

rt_pin_irq_enable(KEY1_PIN, PIN_IRQ_ENABLE);

⑥编写中断回调函数

void led_on(void *args)
{rt_kprintf("turn on led!\n");rt_pin_write(LED0_PIN, PIN_LOW);
}

综上,代码如下:

#include <rtthread.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>#include <board.h>
#define LED0_PIN    GET_PIN(F, 2)
#define KEY1_PIN    GET_PIN(F, 5)
#define KEY2_PIN    GET_PIN(F, 6)void led_on(void *args);
void led_off(void *args);int main(void)
{rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT_PULLUP);rt_pin_mode(KEY2_PIN, PIN_MODE_INPUT_PULLUP);rt_pin_write(LED0_PIN, PIN_HIGH);rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_FALLING , led_on, RT_NULL);/* 绑定中断,下降沿模式,回调函数名为led_on */rt_pin_attach_irq(KEY2_PIN, PIN_IRQ_MODE_FALLING , led_off, RT_NULL);rt_pin_irq_enable(KEY1_PIN, PIN_IRQ_ENABLE);/* 使能中断 */rt_pin_irq_enable(KEY2_PIN, PIN_IRQ_ENABLE);return RT_EOK;
}/* 中断回调函数 */
void led_on(void *args)
{rt_kprintf("turn on led!\n");rt_pin_write(LED0_PIN, PIN_LOW);
}void led_off(void *args)
{rt_kprintf("turn off led!\n");rt_pin_write(LED0_PIN, PIN_HIGH);
}

五、串口通信

①在工程中,双击打开cubemx 进行相关配置
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

②关闭cubemx,回到RT-Thread Studio进行更新

在这里插入图片描述

③查找串口设备(一般情况下,注册到系统的串口设备名称为 uart0,uart1等)

static rt_device_t serial;                /* 串口设备句柄 */serial=rt_device_find(const char* name);

④定义串口配置参数

struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;   // 初始化配置参数 config.baud_rate = BAUD_RATE_115200;        //修改波特率为 115200
config.data_bits = DATA_BITS_8;           //数据位 8
config.stop_bits = STOP_BITS_1;           //停止位 1
config.bufsz     = 128;                   //修改缓冲区 buff size 为 128
config.parity    = PARITY_NONE;           //无奇偶校验位rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);    //控制串口设备。通过控制接口传入命令控制字,与控制参数

⑤打开串口设备

rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);     //以中断接收及轮询发送模式打开串口设备

⑥设置串口接收回调函数

rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size));   dev表示串口设备句柄,rx_ind表示回调函数指针

⑦串口发送/接收 函数

rt_device_write(serial, 0, str, (sizeof(str) - 1));   //serial表示串口设备句柄、0表示偏移量、str表示要发送的缓存区、(sizeof(str) - 1)表示发送的大小rt_device_read(serial, 0, &ch, 1)   //serial表示串口设备句柄、0表示偏移量、ch表示要接收的缓存区、1表示接收的大小

⑧编写串口接收回调函数

static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{return RT_EOK;
}

⑨定义信号量用于接收处理

static struct rt_semaphore rx_sem;       /* 用于接收消息的信号量 */rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);   /* 初始化信号量 */rt_sem_take(&rx_sem, RT_WAITING_FOREVER);    /* 阻塞等待接收信号量,等到信号量后再次读取数据 */rt_sem_release(&rx_sem);  /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */

综上,代码如下:

#include <rtthread.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <string.h>
#include <board.h>
#define LED0_PIN    GET_PIN(F, 2)#define SAMPLE_UART_NAME       "uart1"    /* 串口设备名称 */static rt_err_t uart_input(rt_device_t dev, rt_size_t size);    /* 接收数据回调函数 */
static rt_device_t serial;                /* 串口设备句柄 */
static struct rt_semaphore rx_sem;       /* 用于接收消息的信号量 */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置参数 */
char str[] = "hello RT-Thread!\r\n";
char ch;
int main(void)
{rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);rt_pin_write(LED0_PIN, PIN_HIGH);/* 初始化信号量 */rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);/* step1:查找串口设备 */serial = rt_device_find(SAMPLE_UART_NAME);/* step2:修改串口配置参数 */config.baud_rate = BAUD_RATE_115200;        //修改波特率为 115200config.data_bits = DATA_BITS_8;           //数据位 8config.stop_bits = STOP_BITS_1;           //停止位 1config.bufsz     = 128;                   //修改缓冲区 buff size 为 128config.parity    = PARITY_NONE;           //无奇偶校验位/* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);/* step4:打开串口设备。以中断接收及轮询发送模式打开串口设备 */rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);/* 设置接收回调函数 */rt_device_set_rx_indicate(serial, uart_input);/* 发送字符串 */rt_device_write(serial, 0, str, (sizeof(str) - 1));while (1){/* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */if(rt_device_read(serial, 0, &ch, 1) != 0){//rt_thread_mdelay(10);/* 阻塞等待接收信号量,等到信号量后再次读取数据 */rt_sem_take(&rx_sem, RT_WAITING_FOREVER);rt_kprintf("%c\n",ch);if(ch=='l')rt_pin_write(LED0_PIN, PIN_LOW);else if(ch=='e')rt_pin_write(LED0_PIN, PIN_HIGH);}}return RT_EOK;
}/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{/* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */rt_sem_release(&rx_sem);return RT_EOK;
}

六、OLED显示

①观察电路图
在这里插入图片描述

②进入RT-Thread Settings选中软件模拟I2C,单击开启并进入配置项
在这里插入图片描述
在这里插入图片描述

在软件包中,添加u8g2图形库,并进入配置项
在这里插入图片描述

③退出RT-Thread Settings,进入头文件board.h进行设置
在这里插入图片描述

④保存设置,回到main.c 直接调用u8g2的图形库API函数 即可驱动oled显示屏显示数据

  • 创建图形设备对象
u8g2_t u8g2; 
  • 初始化oled显示屏
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_rtthread);      参数分别为: 对象、旋转角度、消息回调函数的指针、显示回调函数的指针
  • 设置控制 OLED 显示屏的引脚
u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_CLOCK, GET_PIN(F,1));//选择CLK引脚
u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_DATA, GET_PIN(F,0));//选择SDA引脚
  • 初始化设备对象
u8g2_InitDisplay(&u8g2);
  • 退出省电模式(默认开启)
u8g2_SetPowerSave(&u8g2, 0);
  • 清屏
u8g2_ClearBuffer(&u8g2); 
  • 设置字体
u8g2_SetFont(&u8g2, u8g2_font_ncenB14_te);
  • 设置要显示的字符
u8g2_DrawStr(&u8g2, 1, 50, "Nie Dong");
  • 将绘制好的图像数据发送到显示设备进行显示
u8g2_SendBuffer(&u8g2);

综上,代码为:

#include <rtthread.h>#include <u8g2_port.h>
#include <rtdevice.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>#include <board.h>int main(void)
{u8g2_t u8g2;  //图形设备对象                                        对象         旋转角度         消息回调函数的指针             显示回调函数的指针u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_rtthread);u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_CLOCK, GET_PIN(F,1));//选择CLK引脚u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_DATA, GET_PIN(F,0));//选择SDA引脚u8g2_InitDisplay(&u8g2);   // 初始化设备对象u8g2_SetPowerSave(&u8g2, 0);   // 退出省电模式u8g2_ClearBuffer(&u8g2);         //清屏u8g2_SetFont(&u8g2, u8g2_font_ncenB14_te);   //字体u8g2_DrawStr(&u8g2, 1, 50, "Nie Dong");//输入要显示的字符u8g2_SendBuffer(&u8g2);   //将绘制好的图像数据发送到显示设备进行显示return RT_EOK;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/169753.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不同性别人群的股骨颈骨密度随年龄的变化趋势

增龄是发生骨质疏松的危险因素。因此&#xff0c;中老年人需要积极防范骨质疏松&#xff0c;以免发生骨折等不良事件。 为了探究不同性别人群的股骨颈骨密度随年龄的变化趋势&#xff0c;首先创建一个df&#xff0c;变量有id&#xff08;编号&#xff09;、age&#xff08;年龄…

蓝桥杯算法双周赛心得——被替换的身份证(分类讨论)

大家好&#xff0c;我是晴天学长&#xff0c;分类讨论一定要细节啊&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .被替换的身份证 2) .算法思路 假设一方获胜 1.接受数据 2.假设潜梦醒 无非就是&am…

Leetcode421. 数组中两个数的最大异或值

Every day a Leetcode 题目来源&#xff1a;421. 数组中两个数的最大异或值 解法1&#xff1a;贪心 位运算 初始化答案 ans 0。从最高位 high_bit 开始枚举 i&#xff0c;也就是 max⁡(nums) 的二进制长度减一。设 newAns ans 2i&#xff0c;看能否从数组 nums 中选两个…

[HXPCTF 2021]includer‘s revenge

文章目录 方法一前置知识Nginx 在后端 Fastcgi 响应过大产生临时文件竞争包含绕过include_once限制 解题过程 方法二前置知识Base64 Filter 宽松解析iconv filter 解题过程 方法一 NginxFastCGI临时文件 前置知识 Nginx 在后端 Fastcgi 响应过大产生临时文件 www-data用户在n…

Linux内核有什么之内存管理子系统有什么第六回 —— 小内存分配(4)

接前一篇文章&#xff1a;Linux内核有什么之内存管理子系统有什么第五回 —— 小内存分配&#xff08;3&#xff09; 本文内容参考&#xff1a; linux进程虚拟地址空间 《趣谈Linux操作系统 核心原理篇&#xff1a;第四部分 内存管理—— 刘超》 特此致谢&#xff01; 二、小…

C++ 模板保姆级详解——template<class T>(什么是模板?模板分哪几类?模板如何应用?)

目录 一、前言 二、 什么是C模板 &#x1f4a6;泛型编程的思想 &#x1f4a6;C模板的分类 三、函数模板 &#x1f4a6;函数模板概念 &#x1f4a6;函数模板格式 &#x1f4a6;函数模板的原理 &#x1f4a6;函数模板的实例化 &#x1f34e;隐式实例化 &#x1f349;显式实…

从0开始python学习-33.夹具@pytest.fixture(scope=““,params=““,autouse=““,ids=““,name=““)

目录 1. 创建夹具 1.1 pytest方式 1.2 unittest方式 2. 使用夹具 2.1 通过参数引用 2.2 通过函数引用 3. 参数详解 3.1 scope&#xff1a;作用域 3.2 params-参数化 3.3 autouseTrue表示自动使用&#xff0c;默认为False 3.4 ids&#xff1a;设置变量名 3.5 name&am…

电子学会2023年9月青少年软件编程(图形化)等级考试试卷(四级)真题,含答案解析

青少年软件编程(图形化)等级考试试卷(四级) 一、单选题(共10题,共30分) 1. 角色为一个紫色圆圈,运行程序后,舞台上的图案是?( )

机器学习——朴素贝叶斯

目录 一、贝叶斯方法 背景知识 贝叶斯公式 二、朴素贝叶斯原理 判别模型和生成模型 1&#xff0e;朴素贝叶斯法是典型的生成学习方法 2&#xff0e;朴素贝叶斯法的基本假设是条件独立性 3&#xff0e;朴素贝叶斯法利用贝叶斯定理与学到的联合概率模型进行分类预测 用于文…

Codeforces Round 908 (Div. 2)视频详解

Educational Codeforces Round 157 &#xff08;A--D&#xff09;视频详解 视频链接A题代码B题代码C题代码D题代码 视频链接 Codeforces Round 908 (Div. 2)视频详解 A题代码 #include<bits/stdc.h> #define endl \n #define deb(x) cout << #x << "…

Flink 基础 -- 尝试Flink

官网 文档 v1.18.0 下载 数据流上的状态计算(Stateful Computations over Data Streams) Apache Flink是一个框架和分布式处理引擎&#xff0c;用于无界和有界数据流的有状态计算。Flink被设计成可以在所有常见的集群环境中运行&#xff0c;以内存中的速度和任何规模执行计…

目标检测——Yolo系列(YOLOv1/2/v3/4/5/x/6/7/8)

目标检测概述 什么是目标检测&#xff1f; 滑动窗口&#xff08;Sliding Window&#xff09; 滑动窗口的效率问题和改进 滑动窗口的效率问题&#xff1a;计算成本很大 改进思路 1&#xff1a;使用启发式算法替换暴力遍历 例如 R-CNN&#xff0c;Fast R-CNN 中使用 Selectiv…