STM32F103C8T6移植RT-Thread,江科大OLED驱动

STM32F103C8T6移植RT-Thread,江科大OLED驱动

前言

学习完江科大所有STM32教程以及OLED模块后发现评论区很多同学呼吁出实时操作系统的教程。不过看目前江科大只更新到CAN总线,所以估计一时半会还出不完,刚好最近玩RT-thread,因此将自己移植的过程以及程序开源给大家一起学习。(PS:本教程只是让大家能够尽可能的上手,每个RTT函数实现十分建议大家到官方文档中心学习)https://www.rt-thread.org/document/site/#/

移植前准备

1.RT-thread官网下载rtt-stdio,对初学者来说这是一个非常好的上手rtt的工具,当逐渐熟练之后可以试着用Env,这里的链接直达rtt-stdio下载地址。rtt-stdio downlo
2.江科大官网下载OLED驱动。江科大OELD驱动

移植RT-Thread_nano

跟着rtt官方文档安装好rtt-stdio之后创建新工程
在这里插入图片描述


这里回答一下为什么选择nano而不选择标准版
1.nano简洁,与 RT-Thread 完整版不同的是,Nano 不含 Scons 构建系统,不需要 Kconfig 以及 Env 配置工具,也去除了完整版特有的 device 框架和组件,仅是一个纯净的内核。我认为初学者学习操作系统首先学的是操作系统的内核,比如任务调度,内存管理,线程通讯,当这些能够熟练精通后加上丰富多样的设备框架和组件方能如虎添翼

2.nano与freertos很相似并且我认为更符合中文初学者,很多文档以及资料nano都是中文并且很容易理解,对初学者来说易上手才是最重要的,nano看似简单但是绝不简陋

3.Finsh组件
nano唯一能加上的组件,也是我认为和freertos最与众不同的地方,有了这个组件,我们就能直观的看到nano的反馈,也能看到线程的当前状态(最重要的是,当rtt出现在窗口的时候,是能感到非常有成就感的)
在这里插入图片描述

工程创建完成

在这里插入图片描述


生成工程后点击RT-Thread Setting
在这里插入图片描述

正常finsh是灰色的,我们将它点亮就行,点亮后保存(快捷键ctrl+s)
在这里插入图片描述

然后等待它生成代码,生成完毕后,nano加上finsh组件已经移植好了,接下来打开串口窗口
在这里插入图片描述

串口端口选择自己电脑与stm32对于的com,波特率就使用默认的115200

观察窗口,大家可能和我一样是没有我上述所说的
在这里插入图片描述

不用担心,这时候按一下Tab键
在这里插入图片描述

再输入version
在这里插入图片描述

到这一步,恭喜大家成功将nano移植到stm32中啦

大家可能发现我的命令中多了两个任务分别是:oled_task_sample和oled_TIGA_taks,这就是接下来的任务:
创建一个OLED显示的任务,并将这个任务添加到命令行中,当我们输入这个任务命令,stm32就开始执行任务
在这里插入图片描述
在这里插入图片描述

我们将从江科大官网下载的文件放到一个文件夹
在这里插入图片描述

大家再创建一个rt-task用于存放任务函数,避免main文件过于臃肿
接下来最重要的就是在oled.c文件中添加引脚初始化函数

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOB_CLK_ENABLE();

  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);

  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

记得头文件声明

我的头文件添加了一个TIGA图画,大家也可以添加在头文件里面,因为后续的任务函数需要调用这个图像

/*********************图像数据*/
const uint8_t TIGA[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0xC0, 0xC0, 0xF8, 0x1C, 0x07, 0xE3, 0x03, 0x0C, 0x98, 0x70, 0xC0, 0x80, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3C,
	0x06, 0x03, 0x00, 0x7F, 0xFF, 0x18, 0x47, 0x21, 0x0E, 0x0F, 0x12, 0xB8, 0xF8, 0x4F, 0x7F, 0xD8,
	0xF8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
	0x1E, 0x62, 0xE2, 0xB0, 0x7D, 0x61, 0x62, 0x22, 0x82, 0x82, 0xDB, 0x67, 0x33, 0x1C, 0x0F, 0x07,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
	0x18, 0x3C, 0xFE, 0xC6, 0xD1, 0xDF, 0x1E, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x40,
	0x80, 0x80, 0x00, 0x20, 0x80, 0x40, 0x60, 0xE0, 0x10, 0x10, 0x58, 0xF8, 0x38, 0x18, 0x08, 0x08,
	0x20, 0xF8, 0x0F, 0x01, 0x1B, 0x1F, 0x0D, 0x09, 0x99, 0x59, 0x20, 0x30, 0x1F, 0x1C, 0x88, 0x98,
	0xD8, 0xFC, 0xCC, 0xFC, 0xB8, 0xE8, 0xF8, 0x98, 0x90, 0x20, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xDC, 0x06, 0x06, 0x04, 0x07, 0x04,
	0x04, 0x04, 0x07, 0x07, 0x03, 0x47, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
	0x00, 0x00, 0x00, 0xFC, 0xF2, 0xB2, 0xF6, 0xF6, 0xF6, 0xF2, 0xF2, 0xF4, 0xE6, 0xF6, 0xF4, 0xF4,
	0xF6, 0xE6, 0xE4, 0x64, 0xE4, 0xFC, 0xB8, 0x00, 0x20, 0x04, 0x0C, 0x00, 0x03, 0x23, 0x40, 0x40,
	0x0A, 0xC9, 0xA9, 0xC1, 0xC0, 0xB0, 0x7E, 0x7F, 0x06, 0x79, 0xF9, 0x04, 0x00, 0x9F, 0x3F, 0x1C,
	0x00, 0xE1, 0x7C, 0x06, 0x21, 0xB8, 0xFC, 0x3F, 0xFC, 0xC0, 0x80, 0x01, 0x02, 0x04, 0x00, 0x00,
	0xF8, 0xFF, 0x3E, 0xFF, 0xBF, 0xCE, 0xFC, 0xDF, 0xF9, 0xF8, 0xF8, 0x7C, 0x7C, 0x7E, 0x7F, 0x3F,
	0x3F, 0x9F, 0xCF, 0xC7, 0xB1, 0xE3, 0xFF, 0x7D, 0xFC, 0x9F, 0x52, 0x9C, 0x3D, 0x7E, 0xC8, 0x00,
	0x00, 0x0C, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x20, 0xCE, 0xCF, 0xCF,
	0xCF, 0xCF, 0x7E, 0xF8, 0xF8, 0x60, 0x20, 0x60, 0x60, 0x66, 0x6F, 0x6D, 0x6D, 0x4D, 0x47, 0x0D,
	0x60, 0x20, 0x0A, 0x7F, 0x03, 0x02, 0xFF, 0xFF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
	0xBF, 0xBF, 0xFF, 0xA2, 0xE6, 0xE7, 0x03, 0x00, 0x0C, 0x02, 0x01, 0x01, 0x00, 0x03, 0x01, 0x12,
	0x07, 0x01, 0x19, 0x19, 0x09, 0x01, 0x03, 0x03, 0x03, 0x19, 0x19, 0x09, 0x01, 0xD9, 0xC9, 0x6B,
	0x73, 0x38, 0x1C, 0x8E, 0x87, 0xC3, 0x61, 0x17, 0x0F, 0x07, 0x3B, 0xFE, 0x0E, 0x0F, 0x0E, 0x0E,
	0x1C, 0x33, 0x66, 0xCC, 0xE7, 0xE7, 0x68, 0x25, 0x18, 0x0C, 0x0C, 0x46, 0x5C, 0x76, 0x82, 0x1A,
	0x71, 0xF0, 0xD8, 0xE4, 0x7C, 0x1F, 0x07, 0x0C, 0x18, 0x33, 0x70, 0xC0, 0x00, 0x80, 0xC0, 0x63,
	0x7E, 0x38, 0x60, 0xFE, 0x3B, 0x6B, 0x6B, 0x3B, 0x6A, 0x7B, 0x39, 0x1C, 0x3D, 0x04, 0x05, 0x9D,
	0xBD, 0x9C, 0xC6, 0x42, 0xC0, 0xC0, 0xDE, 0xDE, 0xDA, 0xDE, 0xDA, 0x1A, 0x1E, 0x1A, 0x0E, 0xFF,
	0x00, 0x00, 0x1F, 0xFF, 0xEC, 0xED, 0xFF, 0xDF, 0x3F, 0xBF, 0xFF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF,
	0xE7, 0x07, 0x07, 0x04, 0x67, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x3E, 0xC3,
	0xD3, 0xCB, 0xE2, 0xC6, 0xC2, 0xC2, 0x22, 0x1A, 0xCE, 0x62, 0x20, 0x84, 0xC3, 0x61, 0x70, 0xBB,
	0xFC, 0xFC, 0xE6, 0x07, 0x07, 0x07, 0x07, 0x46, 0xF4, 0x06, 0x04, 0x06, 0xC9, 0x00, 0xE4, 0x88,
	0x10, 0x20, 0x40, 0x80, 0x81, 0x00, 0x80, 0x60, 0x30, 0x18, 0x08, 0xC4, 0xE2, 0x01, 0x00, 0x9A,
	0xBF, 0xFF, 0xEB, 0xE3, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0x60, 0xC0, 0xC7, 0xBF, 0x04, 0xE0,
	0x80, 0x00, 0x00, 0x01, 0x07, 0xBC, 0xF0, 0x00, 0x80, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xC3,
	0xC2, 0x93, 0x03, 0x02, 0x23, 0x3B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x78, 0x78, 0x78, 0x00, 0x7F,
	0x00, 0x00, 0xFE, 0xF9, 0xFB, 0x7B, 0x6F, 0xEB, 0xEB, 0x7B, 0xFF, 0xFF, 0xF3, 0xB2, 0x32, 0xB6,
	0xFD, 0xFC, 0x87, 0x03, 0xFB, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFE, 0xC1,
	0x33, 0x9D, 0x9C, 0xF8, 0xF8, 0xFC, 0xF6, 0xB3, 0x13, 0x98, 0xFC, 0xFF, 0xBA, 0xFB, 0xFB, 0xB9,
	0xF9, 0xFB, 0xEE, 0x00, 0x00, 0xF0, 0x00, 0x06, 0xFF, 0x80, 0x10, 0x02, 0x00, 0x8C, 0x9F, 0x84,
	0x04, 0x05, 0x05, 0x05, 0x0D, 0x3F, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0xEF, 0xEC, 0x00, 0x00,
	0x7F, 0xFF, 0xBE, 0xDE, 0x1F, 0x1F, 0x00, 0x01, 0xFE, 0x32, 0xFE, 0xFE, 0x26, 0xFC, 0xDA, 0xFA,
	0xFF, 0xF8, 0xE8, 0xD8, 0x78, 0x78, 0xFF, 0x3F, 0x01, 0x21, 0x01, 0x01, 0x01, 0x27, 0x07, 0x07,
	0x27, 0x0F, 0x0F, 0x0F, 0x2F, 0x3F, 0x2F, 0x27, 0x3B, 0x2F, 0x2F, 0x39, 0x0F, 0x0E, 0xD8, 0x2F,
	/* (128 X 64 )*/

};

接下来我们到任务函数

#include <rtthread.h>
#include <drv_oled.h>

#define THREAD_PRIORITY         15
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        10
ALIGN(RT_ALIGN_SIZE)
static char oled_task_stack[256];
static char TIGA_task_stack[256];
static struct rt_thread oled_task;
static struct rt_thread TIGA_task;
static void oled_task_entry(void *param)
{
    rt_uint16_t i = 0;
    while(1)
    {
        OLED_ShowNum(0, 0, i, 5, OLED_8X16);
        OLED_Update();
        rt_kprintf("task running count:%d\n",i);
        i++;
        rt_thread_mdelay(1000);
    }
}

/* 线程示例 */
int oled_task_sample(void)
{

    /* 初始化线程 2,名称是 thread2,入口是 thread2_entry */
    rt_thread_init(&oled_task,
                   "oled_task",
                   oled_task_entry,
                   RT_NULL,
                   &oled_task_stack[0],
                   sizeof(oled_task_stack),
                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
    rt_thread_startup(&oled_task);

    return 0;
}


static void TIGA_task_entry(void *param)
{
    while(1)
    {
        OLED_ShowImage(0, 0, 127, 63, TIGA);
        OLED_Update();
        rt_thread_mdelay(500);
        OLED_Clear();
        OLED_Update();
        rt_thread_mdelay(500);
    }
}

/* 线程示例 */
int oled_TIGA_task(void)
{

    /* 初始化线程 2,名称是 thread2,入口是 thread2_entry */
    rt_thread_init(&TIGA_task,
                   "TIGA_task",
                   TIGA_task_entry,
                   RT_NULL,
                   &TIGA_task_stack[0],
                   sizeof(TIGA_task_stack),
                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
    rt_thread_startup(&TIGA_task);

    return 0;
}



/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(oled_task_sample, oled_task);
MSH_CMD_EXPORT(oled_TIGA_task, TIGA_task);

有两点需要注意的地方

1.上述函数涉及到任务的创建(设置优先级,栈空间,时间片,句柄,任务命名)
任务入口函数
任务启动函数
这三个函数具体说明请大家自行到官网文档中心学习,文档写的非常详尽
2.任务导出命令

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(oled_task_sample, oled_task);
MSH_CMD_EXPORT(oled_TIGA_task, TIGA_task);

接下来我们到main函数

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-05-08     RT-Thread    first version
 */

#include <rtthread.h>

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

#include "drv_oled.h"

int main(void)
{
    OLED_Init();
    //LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq()); 打印时钟频率
    while (1)
    {
        //LOG_D("Hello RT-Thread!");
        rt_thread_mdelay(10000);
    }

    return RT_EOK;
}

记得将添加的文件夹添加到工程路径

在这里插入图片描述

点击项目,再点击属性
在这里插入图片描述

最后点击应用并关闭

至此,所有步骤都完成了,接下来编译并写入到芯片
在这里插入图片描述

串口窗口
ps:命令行可以通过tab进行补全,比如输入ol,再按下tab,非常方便省事
在这里插入图片描述

此刻大家应该能看到oled有个迪迦不断闪烁
说明任务启动成功

这个时候我们再开启oled_task_sample任务,这时候我们会发现两个任务同时运行
在这里插入图片描述

屏幕也相对应出现现象
看上去单片机在同时执行两个任务,其实单片机同一时间只能执行一个任务,为什么我们看着像同时执行两个任务呢?

关键就是任务调度,也是操作系统的核心之一,每个任务都有对应的优先级,优先级高的先运行,等优先级高的任务阻塞或者主动释放使用权的时候,低优先级的任务就能执行

那怎么让高优先级的任务阻塞或者主动释放使用权呢?

答案是延时函数

rt—thread提供了多个延时函数,在任务中调用延时函数时会让当前任务挂起,释放使用权,让别的任务运行,由于单片机的运行速度非常快,在我们看来就好像单片机在多线程执行任务

希望大家能够将官方的文档仔细阅读学习,这篇文章只是让大家体验国产操作系统的魅力以及初步上手实时操作系统

最后

给大家留个悬念,当我们两个任务同时开启的时候,会发现屏幕显示并不那么完美,有时候会出现乱码的情况,大家可以思考一下为什么

当然也有解决办法,这就是下一章,信号量的使用

  • 55
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值