[TOC]

RT-Thread Stdio实战系列-流水灯实战

一、初始准备

1.硬件平台

使用正点原子STM32F4探索者

IMG_20210207_234256

2.软件平台

RT-Thread Stdio软件平台

STM32CubeProgrammer下载平台

二、操作步骤

1.RTT环境生成

  • 新建RTT项目

新建RTT控件如下

选择基于芯片的项目,填写工程名字,芯片类型,控制台串口和下载器,控制台串口我使用的串口一,连接电脑方便调试

工程新建后左边的项目资源管理器会显示我们的工程,我们把他展开

  • 新建程序文件

新建一个myapp文件夹,建立一个led_flash.c和.h文件,建立后如下

2.RTT程序编写

  • 程序源码

创建之后分别写入头文件和.c文件的代码如下

led_flash.h的代码

1
2
3
4
5
6
#ifndef __LED_FLASH_H__
#define __LED_FLASH_H__

static int led_init(void);
static void led_entry(void *prg);
#endif

led_flash.c的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "led_flash.h"
//RTT 操作系统头文件和设备管理
#include <rtthread.h>
#include <rtdevice.h>
//调用包
#include <stdlib.h>

/* PIN脚编号,查看驱动文件drv_gpio.c确定 */
#define LED0_PIN 89
#define LED1_PIN 90

static void led_entry(void *prg)
{
/* 设置PIN脚模式为输出 */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);

while (1)
{
rt_pin_write(LED0_PIN, PIN_LOW);
rt_pin_write(LED1_PIN, PIN_HIGH);

rt_thread_mdelay(1000);

/* 拉高PIN脚 */
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_pin_write(LED1_PIN, PIN_LOW);

rt_thread_mdelay(1000);
}
}

static int led_init(void)
{
rt_thread_t tid;
rt_err_t ret = RT_EOK;

tid = rt_thread_create("led",
led_entry,
RT_NULL,
512,
10,
20);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
ret = RT_ERROR;
}

return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(led_init,led_init);
  • 代码分析

头文件代码简单理解,不用多说,c语言基本格式

.c文件逻辑如下,我们点亮LED是对IO口进行操作,在RTT里面,IO口的在drv_gpio.c内定义为引脚,我们在drv_gpio.c里面找到对应引脚,在探索者开发板上引脚对应如下

drv_gpio.c找到的对应IO如下,对应的89和90引脚

我们先宏定义这两个引脚:

1
2
3
/* PIN脚编号,查看驱动文件drv_gpio.c确定 */
#define LED0_PIN 89
#define LED1_PIN 90

然后建立一个RTT线程初始化函数,建立流水灯线程的初始化,并在初始化完成后启动该线程,led线程初始化代码如下,采用的动态线程建立方式,判断建立成功后启动线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static int led_init(void)
{
rt_thread_t tid;
rt_err_t ret = RT_EOK;

//创建动态线程
tid = rt_thread_create("led",
led_entry,
RT_NULL,
512,
10,
20);

if (tid != RT_NULL)
{
//建立成功则启动
rt_thread_startup(tid);
}
else
{
//建立失败则返回错误值
ret = RT_ERROR;
}

return ret;
}

线程中的led_entry对应的是LED流水灯的实体函数,编写如下,先初始化两个IO口,在在主循环使用IO口调用API,实现流水灯效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void led_entry(void *prg)
{
/* 设置PIN脚模式为输出 */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);

while (1)
{
rt_pin_write(LED0_PIN, PIN_LOW);
rt_pin_write(LED1_PIN, PIN_HIGH);

rt_thread_mdelay(1000);

/* 拉高PIN脚 */
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_pin_write(LED1_PIN, PIN_LOW);

rt_thread_mdelay(1000);
}
}

程序主体编写完成,我们只需要调用led_init函数,线程就能执行,这里有两个方式,一是通过MSH启动。二是在main函数里面调用led_init直接启动(注意我这里使用的是静态函数,需要在主函数里面调用需要定义成全局函数),我使用的是MSH方式,即把函数添加到注册表内,代码如下

1
2
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(led_init,led_init);

3.程序下载,观察现象

代码编写完成,点击小锤子编译

编译完成,选择ST-LINK下载程序

打开端口,选择主机和电脑连接的串口

在msh输入help,出现注册的命令,可以看到led_init,我门输入led_init,则流水灯线程启动,开发板可以看到现象

流水灯现象

1612940166430

三、工程源码

github:源码链接

wechat