RT-Thread Studio开发 新手入门

news2024/11/19 15:35:58

文章目录

  • 前言
  • 一、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;        //修改波特率为 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;           //无奇偶校验位

    /* 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.coloradmin.cn/o/1199819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【图像处理:OpenCV-Python基础操作】

【图像处理&#xff1a;OpenCV-Python基础操作】 1 读取图像2 显示图像3 保存图像4 图像二值化、灰度图、彩色图&#xff0c;像素替换5 通道处理&#xff08;通道拆分、合并&#xff09;6 调整尺寸大小7 提取感兴趣区域、掩膜8 乘法、逻辑运算9 HSV色彩空间&#xff0c;获取特定…

哈希表之闭散列的实现

闭散列实现哈希表 在闭散列实现哈希表中&#xff0c;我们选择线性探测法来解决哈希冲突。在哈希表的简介部分&#xff0c;我们已经介绍过线性探测法啦&#xff01; 线性探测&#xff1a;从发生冲突的位置开始&#xff0c;依次向后探测&#xff0c;直到寻找到下一个空位置为止…

【Springboot】基于注解式开发Springboot-Vue3整合Mybatis-plus实现分页查询(二)——前端el-pagination实现

系列文章 【Springboot】基于注解式开发Springboot-Vue3整合Mybatis-plus实现分页查询—后端实现 文章目录 系列文章系统版本实现功能实现思路后端传入的数据格式前端el-table封装axois接口引入Element-plus的el-pagination分页组件Axois 获取后台数据 系统版本 后端&#xf…

Day58_《MySQL索引与性能优化》

文章目录 一、SQL执行顺序二、索引简介1、关于索引2、索引的类型Btree 索引Btree 索引 三、Explain简介四、Explain 详解1、id2、select_type3、table4、type5、possible_keys6、key7、key_len8、ref9、rows10、Extra11、小案例 五、索引优化1、单表索引优化2、两表索引优化3、…

Spring Boot 整合xxl-job实现分布式定时任务

xxl-job介绍 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 xxl是xxl-job的开发者大众点评的许雪里名称的拼音开头。 设计思想 将调度行为抽象形成“调度…

multilinear多项式承诺方案benchmark对比

1. 引言 前序博客有&#xff1a; Lasso、Jolt 以及 Lookup Singularity——Part 1Lasso、Jolt 以及 Lookup Singularity——Part 2深入了解LassoJolt Lasso lookup中&#xff0c;multilinear多项式承诺方案的高效性至关重要。 本文重点关注4种multilinear多项式承诺方案的实…

linux 不同用户不同jdk

0、 解压一个新版本的jdk 1、 检查root用户下的环境变量&#xff0c;是否配置了JAVA_HOME&#xff0c;基于这个变量再配置的PATH变量是实现切换的前提。 2、 创建新用户 adduser jdk11 passwd jfjfjfjfjfjfj123 3、 编辑改用下的 .bashrc 文件 执行命令进行编辑&#xff0…

【Nginx】深入浅出搞懂Nginx

Nginx是一款轻量级的Web服务器、反向代理服务器&#xff0c;由于它的内存占用少&#xff0c;启动极快&#xff0c;高并发能力强&#xff0c;在互联网项目中广泛应用。 反向代理服务器&#xff1f; 经常听人说到一些术语&#xff0c;如反向代理&#xff0c;那么什么是反向代理&a…

BGP基本配置实验

目录 一、实验拓扑 二、实验需求 三、实验步骤 1、IP地址配置 2、内部OSPF互通&#xff0c;配置OSPF协议 3、BGP建立邻居关系 4、R1和R5上把业务网段宣告进BGP 5、消除路由黑洞&#xff0c;在R2、R4上做路由引入 6、业务网段互通 一、实验拓扑 二、实验需求 1、按照图…

开发者测试2023省赛--UnrolledLinkedList测试用例

测试结果 官方提交结果 EclEmma PITest 被测文件UnrolledLinkedList.java /** This source code is placed in the public domain. This means you can use it* without any restrictions.*/package net.mooctest;import java.util.AbstractList; import java.util.Collectio…

担忧CentOS停服?KeyarchOS系统来支撑

担忧CentOS停服&#xff1f;KeyarchOS系统来支撑 近年发生的“微软黑屏门”、“微软操作系统停更”、“棱镜门”、“中兴华为”等安全事件&#xff0c;敲响了我国 IT 产业的警钟&#xff0c;建立由我国主导的 IT 产业生态尤为迫切。对此&#xff0c;我国信息技术应用创新行业乘…

数字媒体技术基础之:分辨率

分辨率 Resolution&#xff0c;中国大陆译为“分辨率”&#xff0c;中国香港地区、中国台湾地区分别译为“解像度”和“解析度”&#xff0c;泛指测量设备对细节的分辨能力。 ◆ ◆ ◆ 图像尺寸 在数字图像处理中&#xff0c;像素 Pixel是一个无具体物理尺寸的抽象单位。 一张…

序列化模块-json和pickle

一、json json是所有语言都通用的一种序列化格式 &#xff0c;只支持 列表、 字典、 字符串、 数字 &#xff0c; 字典的key必须是字符串 1、dumps、loods # 在内存中做数据转换 : # durps 数据类型 转成 字符串 序列化 # loods 字符串 转成 数据类型 反序…

基于STC12C5A60S2系列1T 8051单片机定时器/计数器应用

基于STC12C5A60S2系列1T 8051单片机定时器/计数器应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC12C5A60S2系列1T 8051单片机定时器/计数器介绍STC12C5A60S2系…

No179.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

C++算法:完美矩形

题目 给你一个数组 rectangles &#xff0c;其中 rectangles[i] [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) &#xff0c;右上顶点是 (ai, bi) 。 如果所有矩形一起精确覆盖了某个矩形区域&#xff0c;则返回 true &#xff1b;否则&#xf…

C语言基础篇3:函数

1 函数简介 C源程序是由函数组成的&#xff0c;一个程序往往由多个函数组成&#xff0c;函数是程序实现模块化变成的基本的单元&#xff0c;一般是为了完成某一个特定的功能&#xff0c;相当于其他语言中的子程序。一个较大程序的各项功能都是由各个子程序共同完成的&#xff0…

【Seata源码学习 】 AT模式 第一阶段 @GlobalTransaction的扫描

1. SeataAutoConfiguration 自动配置类的加载 基于SpringBoot的starter机制&#xff0c;在应用上下文启动时&#xff0c;会加载SeataAutoConfiguration自动配置类 # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfigurationio.seata.spring.boot.aut…

Zabbix SNMPv3

一、Snmpv3简述 SNMPv3是Simple Network Management Protocol version 3&#xff08;简单网络管理协议第三版&#xff09;的缩写。它是一种网络管理协议&#xff0c;用于监控和管理网络中的设备、系统和应用程序。 相对于之前的版本&#xff0c;SNMPv3具有更强的安全性和扩展…

NGINX三种虚拟主机的配置

基于IP的配置 首先在原本基础上增加两个IP地址 [rootlocalhost conf.d]# nmcli connection modify ens33 ipv4.addresses 192.168.38.140 [rootlocalhost conf.d]# nmcli connection modify ens33 ipv4.addresses 192.168.38.150 [rootlocalhost conf.d]# nmcli connection u…