使用RT-Thread Studio + CubeMX开发项目(一):使用uart

摘要:本文将从一个简单的需求出发,利用 RT-Thread Studio + CubeMX 这两个工具,基于 RT-Thread 完成系统创建及开发,目的是为了记录开发过程,方便以后回顾。

需求描述:

使用 RT-Thread Studio 创建基于 STM32F103RET6 的工程,并 USART1 和 USART2 ,USART1 用于 msh 的输入/输出,USART2 用于其他业务。

第一步、使用RT-Thread Studio创建工程(RttDemo)

软件安装不做赘述请看官方文档:安装 RTT Studio

步骤:文件→新建→RT-Thread项目


注意:RTT Studio 生成的工程使用的是芯片内部HSI时钟,如需修改,请完善 drv_clk.c,将 drv_clk.c 文件中 system_clock_config(int target_freq_Mhz)函数中的内容,替换成我们用 CubeMX 生成的时钟初始化代码。

第二步、使用CubeMX配置工程(主要是配置时钟)

这里只简单说下,详细配置过程可以参考下文的链接,(需要注意的是生成代码的时候,不要勾选 “Generate peripheral initialization as a pair of".c/.h' files per peripheral” 选项):

  • 工程创建,注意创建路
  • RCC 设置
  • 时钟配置

第三步、修改项目默认时钟配置为 CubeMX 配置的时钟

在 CubeMX 生成项目中找到 main.c 文件,并使用 main.c 文件中的 SystemClock_Config(void) 函数内容替换掉RTT工程中 drv_clk.c 文件中的 system_clock_config(int target_freq_Mhz) 函数。

第四步、新增串口(USART2)

可参考官方文档,新增串口部分:

完整版 - RT-Thread 文档中心

在 RTT 项目 board.h 中添加对 USART2 的支持方法如下:

// 增加以下宏
#define BSP_USING_UART2
#define BSP_UART2_TX_PIN       "PA2"
#define BSP_UART2_RX_PIN       "PA3"

编译运行程序, PC 端连接 uart1,在 msh 中,输入 list_device 可以看到 uart2 设备。

msh >list_device
device           type         ref count
-------- -------------------- ----------
uart2    Character Device     0       
uart1    Character Device     2       
pin      Miscellaneous Device 0       
msh >

第五步、封装 USART2 并使用接口输出 “Hello RT-Thread!”

  • 创建文件

在 applications 目录下创建 service/uart 文件夹,并创建文件 SerialUart2.h 和 SerialUart2.c ,

SerialUart2.h 主要内容如下:

#ifndef _SERIAL_UART_2_H_
#define _SERIAL_UART_2_H_

#include <rtdevice.h>

rt_bool_t serial2_init();

rt_size_t serial2_write(const void *buffer, rt_size_t size);

rt_size_t serial2_read(void *buffer, rt_size_t size);

rt_bool_t serial2_change_baudrate(rt_uint32_t rate);

#endif //_SERIAL_UART_2_H_

SerialUart2.c 主要内容如下:

#include "SerialUart2.h"

/* log */
#define DBG_TAG    "SerialUart2"
#define DBG_LVL    DBG_LOG
#include <rtdbg.h>

/* uart */
#define UART_NAME       "uart2"
static rt_device_t serial;

struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

/* circle buffer */
#define TX_RING_BUFFER_LEN  100
#define RX_RING_BUFFER_LEN  100

/* line buffer */
#define TX_RING_BUFFER_LEN  100

static rt_err_t serial_rx_callback(rt_device_t dev, rt_size_t size)
{
    /* 更新超时检测时间 */
    return RT_EOK;
}

rt_bool_t serial2_init()
{
    rt_err_t ret = RT_EOK;

    serial = rt_device_find(UART_NAME);
    if (!serial)
    {
        LOG_D("find %s failed!\n", UART_NAME);
        return RT_FALSE;
    }

    ret = rt_device_set_rx_indicate(serial, serial_rx_callback);
    if(ret != RT_EOK)
    {
        LOG_D("uart2 set rx callback failed\r\n");
        return RT_FALSE;
    }

    ret = rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
    if(ret != RT_EOK)
    {
        LOG_D("control device failed\r\n");
        return RT_FALSE;
    }

    ret = rt_device_open(serial, RT_DEVICE_FLAG_INT_RX|RT_DEVICE_FLAG_INT_TX);
    if (ret != RT_EOK)
    {
        LOG_D("open device failed\r\n");
        return RT_FALSE;
    }

    return RT_TRUE;
}

rt_size_t serial2_write(const void *buffer, rt_size_t size)
{
    return rt_device_write(serial, 0, str, (sizeof(str) - 1));
}

rt_size_t serial2_read(void *buffer, rt_size_t size)
{
    return rt_device_read(serial, 0, buffer, size);
}

rt_bool_t serial2_change_baudrate(rt_uint32_t rate)
{
    rt_err_t ret = RT_EOK;
    struct serial_configure configtmp = config;

    /* 修改串口波特率 */
    configtmp.baud_rate = rate;

    ret = rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &configtmp);
    if(RT_EOK != ret)
    {
        LOG_D("open device failed\r\n");
        return RT_FALSE;
    }

    return RT_TRUE;
}

文件重建完成后,加入头文件路径:

在项目上点击右键,再点击属性出现下图中的窗口,在其中添加自己刚创建的路径,并点击“应用并关闭”;

  • 修改 main.c ,增加对 uart2 的测试代码:
#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#include "SerialUart2.h"

int main(void)
{
    int count = 1;

    serial2_init();

    while (count++)
    {
        LOG_D("Hello RT-Thread!");
        serial2_write("Hello RT-Thread!", sizeof("Hello RT-Thread!"));
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}
  • 编译代码。

第六步、测试

  • 使用 JLink 下载程序,并使用 TTL 转 USB 模块连接串口 2 到电脑,电脑上使用串口调试工具接收数据。
  • 查看 uart1 的输出信息如下,可以看 uart2 已经被使用一次。
msh >list_device[D/main] Hello RT-Thread!

device           type         ref count
-------- -------------------- ----------
uart2    Character Device     1       
uart1    Character Device     2       
pin      Miscellaneous Device 0