[嵌入式embed]Keil5-STM32F103C8T6(江协科技)+移植RT-Thread v3.15模版 - 教程

0.为什么不用<<Keil 模拟器 STM32F103 上手指南>>?

Keil 模拟器 STM32F103 上手指南
在这里插入图片描述

官方例子RT-Thread Simulator 例程

是基于STM32F103ZF的,与STM32F103C8T6差异巨大,移植时间成本过高
可用来参考移植结构

在这里插入图片描述

1.江协资料(接线图+视频+相关资料下载)

视频-(3-2 LED流水灯和4-1 OLED显示屏)

[3-2] LED闪烁&LED流水灯&蜂鸣器

[4-1] OLED调试工具

示例程序-(3-2 LED流水灯和4-1 OLED显示屏)

在这里插入图片描述

接线图-(3-2 LED流水灯和4-1 OLED显示屏)

在这里插入图片描述
在这里插入图片描述

因为需要Serial串口+OLED显示,所以最终接线如图
在这里插入图片描述

资料下载

在这里插入图片描述

江协STM32资料下载

2.Keil5 安装 RT-Thread v3.15

在这里插入图片描述

基于 Keil MDK 移植 RT-Thread Nano

方法一:在 IDE 内安装

打开 MDK 软件,点击工具栏的 Pack Installer 图标:
在这里插入图片描述

点击右侧的 Pack,展开 Generic,可以找到 RealThread::RT-Thread,点击 Action 栏对应的 Install ,就可以在线安装 Nano Pack 了。另外,如果需要安装其他版本,则需要展开 RealThread::RT-Thread,进行选择,箭头所指代表已经安装的版本。

在这里插入图片描述

方法二:手动安装

我们也可以从官网下载安装文件,
RT-Thread Nano 离线安装包下载
双击文件进行安装:

3.江协科技:4-1 OLED显示屏 移植RT-Thread Nano

3.1复制4-1 OLED显示屏项目

在这里插入图片描述

重命名为1-Keil5-STM32F103C8T6

3.2打开项目并添加RT-Thread到项目

在 Manage Rum-Time Environment 里 “Software Component” 栏找到 RTOS,Variant 栏选择 RT-Thread,然后勾选 kernel,点击 “OK” 就添加 RT-Thread 内核到工程了。
在这里插入图片描述
在这里插入图片描述

3.3修改RT-Thread的文件

在这里插入图片描述

board.c
在这里插入图片描述

/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date           Author       Notes
* 2021-05-24                  the first version
*/
#include <rthw.h>
  #include <rtthread.h>
    #include "stm32f10x.h"
    #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    /*
    * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
    * the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
    */
    #define RT_HEAP_SIZE (15*1024)
    static rt_uint8_t rt_heap[RT_HEAP_SIZE];
    RT_WEAK void *rt_heap_begin_get(void)
    {
    return rt_heap;
    }
    RT_WEAK void *rt_heap_end_get(void)
    {
    return rt_heap + RT_HEAP_SIZE;
    }
    #endif
    void rt_os_tick_callback(void)
    {
    rt_interrupt_enter();
    rt_tick_increase();
    rt_interrupt_leave();
    }
    /**
    * This function will initial your board.
    */
    void rt_hw_board_init(void)
    {
    //#error "TODO 1: OS Tick Configuration."
    /*
    * TODO 1: OS Tick Configuration
    * Enable the hardware timer and call the rt_os_tick_callback function
    * periodically with the frequency RT_TICK_PER_SECOND.
    */
    // 配置SysTick定时器,产生1ms中断
    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    /* Call components board initial (use INIT_BOARD_EXPORT()) */
    #ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
    #endif
    #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
    #endif
    }
    #ifdef RT_USING_CONSOLE
    static int uart_init(void)
    {
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    /* 使能外设时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    /* 配置USART1 Tx (PA.9)为复用推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* 配置USART1 Rx (PA.10)为浮空输入 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* 配置USART1参数 */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx;
    /* 初始化USART1 */
    USART_Init(USART1, &USART_InitStructure);
    /* 使能USART1 */
    USART_Cmd(USART1, ENABLE);
    return 0;
    }
    INIT_BOARD_EXPORT(uart_init);
    void rt_hw_console_output(const char *str)
    {
    rt_size_t i = 0, size = 0;
    char a = '\r';
    size = rt_strlen(str);
    for (i = 0; i < size; i++)
    {
    /* 遇到'\n',需要先发送'\r' */
    if (*(str + i) == '\n')
    {
    /* 等待发送缓冲区为空 */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    USART_SendData(USART1, a);
    }
    /* 等待发送缓冲区为空 */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    USART_SendData(USART1, *(str + i));
    }
    }
    #endif

rtconfig.h

/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
// <<< Use Configuration Wizard in Context Menu >>>
  // <h>Basic Configuration
    // <o>Maximal level of thread priority <8-256>
      //  <i>Default: 32
        #define RT_THREAD_PRIORITY_MAX  32
        // <o>OS tick per second
          //  <i>Default: 1000   (1ms)
            #define RT_TICK_PER_SECOND  1000
            // <o>Alignment size for CPU architecture data access
              //  <i>Default: 4
                #define RT_ALIGN_SIZE   4
                // <o>the max length of object name<2-16>
                  //  <i>Default: 8
                    #define RT_NAME_MAX    8
                    // <c1>Using RT-Thread components initialization
                      //  <i>Using RT-Thread components initialization
                        #define RT_USING_COMPONENTS_INIT
                        // </c>
                          #define RT_USING_USER_MAIN
                          // <o>the stack size of main thread<1-4086>
                            //  <i>Default: 512
                              #define RT_MAIN_THREAD_STACK_SIZE     256
                              // </h>
                                // <h>Debug Configuration
                                  // <c1>enable kernel debug configuration
                                    //  <i>Default: enable kernel debug configuration
                                      //#define RT_DEBUG
                                      // </c>
                                        // <o>enable components initialization debug configuration<0-1>
                                          //  <i>Default: 0
                                            #define RT_DEBUG_INIT 0
                                            // <c1>thread stack over flow detect
                                              //  <i> Diable Thread stack over flow detect
                                                //#define RT_USING_OVERFLOW_CHECK
                                                // </c>
                                                  // </h>
                                                    // <h>Hook Configuration
                                                      // <c1>using hook
                                                        //  <i>using hook
                                                          //#define RT_USING_HOOK
                                                          // </c>
                                                            // <c1>using idle hook
                                                              //  <i>using idle hook
                                                                //#define RT_USING_IDLE_HOOK
                                                                // </c>
                                                                  // </h>
                                                                    // <e>Software timers Configuration
                                                                      // <i> Enables user timers
                                                                        #define RT_USING_TIMER_SOFT         0
                                                                        #if RT_USING_TIMER_SOFT == 0
                                                                        #undef RT_USING_TIMER_SOFT
                                                                        #endif
                                                                        // <o>The priority level of timer thread <0-31>
                                                                          //  <i>Default: 4
                                                                            #define RT_TIMER_THREAD_PRIO        4
                                                                            // <o>The stack size of timer thread <0-8192>
                                                                              //  <i>Default: 512
                                                                                #define RT_TIMER_THREAD_STACK_SIZE  512
                                                                                // </e>
                                                                                  // <h>IPC(Inter-process communication) Configuration
                                                                                    // <c1>Using Semaphore
                                                                                      //  <i>Using Semaphore
                                                                                        #define RT_USING_SEMAPHORE
                                                                                        // </c>
                                                                                          // <c1>Using Mutex
                                                                                            //  <i>Using Mutex
                                                                                              //#define RT_USING_MUTEX
                                                                                              // </c>
                                                                                                // <c1>Using Event
                                                                                                  //  <i>Using Event
                                                                                                    //#define RT_USING_EVENT
                                                                                                    // </c>
                                                                                                      // <c1>Using MailBox
                                                                                                        //  <i>Using MailBox
                                                                                                          #define RT_USING_MAILBOX
                                                                                                          // </c>
                                                                                                            // <c1>Using Message Queue
                                                                                                              //  <i>Using Message Queue
                                                                                                                //#define RT_USING_MESSAGEQUEUE
                                                                                                                // </c>
                                                                                                                  // </h>
                                                                                                                    // <h>Memory Management Configuration
                                                                                                                      // <c1>Memory Pool Management
                                                                                                                        //  <i>Memory Pool Management
                                                                                                                          //#define RT_USING_MEMPOOL
                                                                                                                          // </c>
                                                                                                                            // <c1>Dynamic Heap Management(Algorithm: small memory )
                                                                                                                              //  <i>Dynamic Heap Management
                                                                                                                                #define RT_USING_HEAP
                                                                                                                                #define RT_USING_SMALL_MEM
                                                                                                                                // </c>
                                                                                                                                  // <c1>using tiny size of memory
                                                                                                                                    //  <i>using tiny size of memory
                                                                                                                                      //#define RT_USING_TINY_SIZE
                                                                                                                                      // </c>
                                                                                                                                        // </h>
                                                                                                                                          // <h>Console Configuration
                                                                                                                                            // <c1>Using console
                                                                                                                                              //  <i>Using console
                                                                                                                                                #define RT_USING_CONSOLE
                                                                                                                                                // </c>
                                                                                                                                                  // <o>the buffer size of console <1-1024>
                                                                                                                                                    //  <i>the buffer size of console
                                                                                                                                                      //  <i>Default: 128  (128Byte)
                                                                                                                                                        #define RT_CONSOLEBUF_SIZE          256
                                                                                                                                                        // </h>
                                                                                                                                                          // <h>FinSH Configuration
                                                                                                                                                            // <c1>include finsh config
                                                                                                                                                              //  <i>Select this choice if you using FinSH
                                                                                                                                                                //#include "finsh_config.h"
                                                                                                                                                                // </c>
                                                                                                                                                                  // </h>
                                                                                                                                                                    // <h>Device Configuration
                                                                                                                                                                      // <c1>using device framework
                                                                                                                                                                        //  <i>using device framework
                                                                                                                                                                          //#define RT_USING_DEVICE
                                                                                                                                                                          // </c>
                                                                                                                                                                            // </h>
                                                                                                                                                                              // <<< end of configuration section >>>
                                                                                                                                                                                #endif
3.4修改部分stm32的代码

在这里插入图片描述

stm32f10x_it.c

/**
******************************************************************************
* @file    Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c
* @author  MCD Application Team
* @version V3.5.0
* @date    08-April-2011
* @brief   Main Interrupt Service Routines.
*          This file provides template for all exceptions handler and
*          peripherals interrupt service routine.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */
  /* Includes ------------------------------------------------------------------*/
  #include "stm32f10x_it.h"
  #include <rthw.h>
    #include <rtthread.h>
      /* 函数声明 */
      void rt_os_tick_callback(void);
      /** @addtogroup STM32F10x_StdPeriph_Template
      * @{
      */
      /* Private typedef -----------------------------------------------------------*/
      /* Private define ------------------------------------------------------------*/
      /* Private macro -------------------------------------------------------------*/
      /* Private variables ---------------------------------------------------------*/
      /* Private function prototypes -----------------------------------------------*/
      /* Private functions ---------------------------------------------------------*/
      /******************************************************************************/
      /*            Cortex-M3 Processor Exceptions Handlers                         */
      /******************************************************************************/
      /**
      * @brief  This function handles NMI exception.
      * @param  None
      * @retval None
      */
      void NMI_Handler(void)
      {
      }
      /**
      * @brief  This function handles Hard Fault exception.
      * @param  None
      * @retval None
      */
      //void HardFault_Handler(void)
      //{
      //  /* Go to infinite loop when Hard Fault exception occurs */
      //  while (1)
      //  {
      //  }
      //}
      /**
      * @brief  This function handles Memory Manage exception.
      * @param  None
      * @retval None
      */
      void MemManage_Handler(void)
      {
      /* Go to infinite loop when Memory Manage exception occurs */
      while (1)
      {
      }
      }
      /**
      * @brief  This function handles Bus Fault exception.
      * @param  None
      * @retval None
      */
      void BusFault_Handler(void)
      {
      /* Go to infinite loop when Bus Fault exception occurs */
      while (1)
      {
      }
      }
      /**
      * @brief  This function handles Usage Fault exception.
      * @param  None
      * @retval None
      */
      void UsageFault_Handler(void)
      {
      /* Go to infinite loop when Usage Fault exception occurs */
      while (1)
      {
      }
      }
      /**
      * @brief  This function handles SVCall exception.
      * @param  None
      * @retval None
      */
      void SVC_Handler(void)
      {
      }
      /**
      * @brief  This function handles Debug Monitor exception.
      * @param  None
      * @retval None
      */
      void DebugMon_Handler(void)
      {
      }
      /**
      * @brief  This function handles PendSVC exception.
      * @param  None
      * @retval None
      */
      //void PendSV_Handler(void)
      //{
      //}
      /**
      * @brief  This function handles SysTick Handler.
      * @param  None
      * @retval None
      */
      void SysTick_Handler(void)
      {
      rt_os_tick_callback();
      }
      /******************************************************************************/
      /*                 STM32F10x Peripherals Interrupt Handlers                   */
      /*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
      /*  available peripheral interrupt handler's name please refer to the startup */
      /*  file (startup_stm32f10x_xx.s).                                            */
      /******************************************************************************/
      /**
      * @brief  This function handles PPP interrupt request.
      * @param  None
      * @retval None
      */
      /*void PPP_IRQHandler(void)
      {
      }*/
      /**
      * @}
      */
      /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

stm32f10x_it.h

/**
******************************************************************************
* @file    Project/STM32F10x_StdPeriph_Template/stm32f10x_it.h
* @author  MCD Application Team
* @version V3.5.0
* @date    08-April-2011
* @brief   This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */
  /* Define to prevent recursive inclusion -------------------------------------*/
  #ifndef __STM32F10x_IT_H
  #define __STM32F10x_IT_H
  #ifdef __cplusplus
  extern "C" {
  #endif 
  /* Includes ------------------------------------------------------------------*/
  #include "stm32f10x.h"
  /* Exported types ------------------------------------------------------------*/
  /* Exported constants --------------------------------------------------------*/
  /* Exported macro ------------------------------------------------------------*/
  /* Exported functions ------------------------------------------------------- */
  void NMI_Handler(void);
  //void HardFault_Handler(void);
  void MemManage_Handler(void);
  void BusFault_Handler(void);
  void UsageFault_Handler(void);
  void SVC_Handler(void);
  void DebugMon_Handler(void);
  //void PendSV_Handler(void);
  void SysTick_Handler(void);
  #ifdef __cplusplus
  }
  #endif
  #endif /* __STM32F10x_IT_H */
  /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

LED.c

#include "stm32f10x.h"                  // Device header
/**
* 函    数:LED初始化
* 参    数:无
* 返 回 值:无
*/
void LED_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);						//将PA1和PA2引脚初始化为推挽输出
/*设置GPIO初始化后的默认电平*/
GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);				//设置PA1和PA2引脚为高电平
}
/**
* 函    数:LED1开启
* 参    数:无
* 返 回 值:无
*/
void LED1_ON(void)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);		//设置PA1引脚为低电平
}
/**
* 函    数:LED1关闭
* 参    数:无
* 返 回 值:无
*/
void LED1_OFF(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_0);		//设置PA1引脚为高电平
}
/**
* 函    数:LED1状态翻转
* 参    数:无
* 返 回 值:无
*/
void LED1_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0) == 0)		//获取输出寄存器的状态,如果当前引脚输出低电平
{
GPIO_SetBits(GPIOA, GPIO_Pin_0);					//则设置PA1引脚为高电平
}
else													//否则,即当前引脚输出高电平
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);					//则设置PA1引脚为低电平
}
}
/**
* 函    数:LED2开启
* 参    数:无
* 返 回 值:无
*/
void LED2_ON(void)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);		//设置PA2引脚为低电平
}
/**
* 函    数:LED2关闭
* 参    数:无
* 返 回 值:无
*/
void LED2_OFF(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);		//设置PA2引脚为高电平
}
/**
* 函    数:LED2状态翻转
* 参    数:无
* 返 回 值:无
*/
void LED2_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)		//获取输出寄存器的状态,如果当前引脚输出低电平
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);               		//则设置PA2引脚为高电平
}
else                                               		//否则,即当前引脚输出高电平
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);             		//则设置PA2引脚为低电平
}
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "LED.h"
#include <rtthread.h>
  #include <rtdbg.h>
    rt_thread_t thread1;
    uint8_t flag;
    void thread1_entry(void *p){
    while(1){
    rt_kprintf("thread1 running\n");
    flag = !flag;
    if (flag){
    LED1_ON();
    LED2_OFF();
    OLED_ShowString(4, 1, "thread1 run");
    }else{
    LED1_OFF();
    LED2_ON();
    OLED_ShowString(3, 1, "thread1 run");
    }
    rt_thread_mdelay(500);
    }
    }
    int main(void)
    {
    /*模块初始化*/
    OLED_Init();		//OLED初始化
    LED_Init();
    thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 512, 15, 5);
    if (thread1 != RT_NULL){
    rt_thread_startup(thread1);
    rt_kprintf("thread1 create success\n");
    }else{
    rt_kprintf("thread1 create error\n");
    }
    }

4.查看效果

led闪烁+oled显示

在这里插入图片描述

串口serial输出

在这里插入图片描述

5.百度云

在这里插入图片描述
在这里插入图片描述

keil5+rt_thread离线安装包+串口工具+keil5_STM32F103C8T6_RT-Thread项目

posted @ 2025-11-11 21:30  ycfenxi  阅读(50)  评论(0)    收藏  举报