本帖最后由 _Prtemly 于 2025-6-7 10:07 编辑

1. 准备工作

1.1 硬件准备

  • 赛元LB2001触控滑条评估板一张。
  • 调试器(如J-Link、ST-Link等)
  • 必要的连接线缆,赛元LB2001触控滑条评估板预留J2排针就是SWD调试口,如图:

微信图片_2025-06-07_094739_558.jpg

我是用的是WCH-Link配置成DAP模式使用的,依次连接VCC、DIO、VSS、CLK四条线即可。

(注意:赛元LB2001触控滑条评估板J2调试口的丝印标反了,DIO和CLK需要交换,切记!)


1.2 软件准备
  • Keil MDK或IAR Embedded Workbench开发环境
       Keil MDK需要安装芯片支持包,下载地址:KEIL插件(ARM版)
  • RT-Thread Nano源码包(可从RT-Thread官网下载)

2. 创建基础工程

  • 在开发环境中创建一个新的工程,或者直接copy一份sdk的测试工程也可以。
  • 添加必要的lib库文件。

3. 添加RT-Thread Nano到工程

3.1 复制RT-Thread Nano文件

将RT-Thread Nano的以下目录复制到你的工程目录中:

<pre>rtthread-nano/
  • ├── include
  • ├── libcpu
  • ├── src
  • └── components</pre>
  • 复制代码

    3.2 添加文件到工程

    在开发环境中添加以下文件到工程:

    • rtthread-nano/src/*.c
    • rtthread-nano/libcpu/arm/cortex-m0/*.c

    3.3 包含头文件路径

    添加以下头文件路径到工程设置:

    • rtthread-nano/include
    • rtthread-nano/libcpu/arm/cortex-m0

    配置好的工程目录如下图:

    Snipaste_2025-06-07_09-48-41.png


    4. 配置RT-Thread Nano

    4.1 修改rtconfig.h创建或修改rtconfig.h文件,

    配置RT-Thread Nano的基本参数:

    <pre>// <h>Basic Configuration
  • // <o>Maximal level of thread priority <8-256>
  • //  <i>Default: 32
  • #define RT_THREAD_PRIORITY_MAX  8
  • // <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     512

  • // <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

  • // <c1>Dynamic Heap Management(Algorithm: small memory )
  • //  <i>Dynamic Heap Management
  • #define RT_USING_HEAP
  • #define RT_USING_SMALL_MEM

  • // <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          128
  • // </h></pre>
  • 复制代码

    4.2 板级硬件配置

    board.c中配置内存堆:

    #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
  • #ifdef __ICCARM__
  • // Use *.icf ram symbal, to avoid hardcode.
  • extern char __ICFEDIT_region_IRAM1_end__;
  • #define MCU_SRAM_END            &__ICFEDIT_region_IRAM1_end__
  • #else
  • // 根据自己的MCU不同修改
  • #define MCU_SRAM_SIZE           8
  • // 根据自己的MCU不同修改
  • #define MCU_SRAM_END            (SRAM_BASE + MCU_SRAM_SIZE * 1024)
  • #endif

  • #ifdef __ICCARM__
  • #pragma section="HEAP"
  • #define HEAP_BEGIN    (__segment_end("HEAP"))
  • #else
  • extern int Image$RW_IRAM1$ZI$Limit;
  • #define HEAP_BEGIN    (&Image$RW_IRAM1$ZI$Limit)
  • #endif
  • #define HEAP_END                MCU_SRAM_END

  • RT_WEAK void *rt_heap_begin_get(void)
  • {
  •     return (void*)HEAP_BEGIN;
  • }

  • RT_WEAK void *rt_heap_end_get(void)
  • {
  •     return (void *)HEAP_END;
  • }
  • #endif
  • 复制代码

    配置systick中断函数:

    void rt_os_tick_callback(void)
  • {
  •     rt_interrupt_enter();   
  •     rt_tick_increase();   
  •     rt_interrupt_leave();
  • }

  • void SysTick_IRQHandler(void)
  • {
  •     rt_os_tick_callback();
  • }

  • void rt_hw_board_init(void)
  • {
  •     extern uint32_t SystemCoreClock;
  •     extern void SystemClock_Config(void);

  •     SystemClock_Config();
  •     SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
  •     /*
  •      * 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.
  •      */

  •     /* 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
  • }
  • 复制代码

    配置日志串口初始化及日志输出函数

    因为uart0的默认端口同时也是SWD调试口,所以日志输出串口我们选择uart1,配置PA13和PA14分别为uart1的rx和tx,代码如下:

    #ifdef RT_USING_CONSOLE
  • #include "sc32f10xx.h"
  • #include "sc32f10xx_gpio.h"
  • #include "sc32f10xx_uart.h"

  • static int uart_init(void)
  • {
  •     // rx
  •     GPIO_InitTypeDef GPIOInit_Struct;
  •     GPIOInit_Struct.GPIO_Pin = GPIO_Pin_13;
  •     GPIOInit_Struct.GPIO_Mode = GPIO_Mode_IN_PU;
  •     GPIOInit_Struct.GPIO_DriveLevel = 0;
  •     GPIO_Init(GPIOA, &GPIOInit_Struct);

  •     // tx
  •     GPIOInit_Struct.GPIO_Pin = GPIO_Pin_14;
  •     GPIOInit_Struct.GPIO_Mode = GPIO_Mode_IN_PU;
  •     GPIOInit_Struct.GPIO_DriveLevel = 0;
  •     GPIO_Init(GPIOA, &GPIOInit_Struct);

  •     RCC_APB0Cmd(ENABLE);
  •     RCC_APB0PeriphClockCmd(RCC_APB0Periph_UART1, ENABLE);
  •     UART_InitTypeDef UART_InitStruct;
  •     UART_InitStruct.UART_ClockFrequency = 64000000;
  •     UART_InitStruct.UART_BaudRate = 115200;
  •     UART_InitStruct.UART_Mode = UART_Mode_10B;
  •     UART_Init(UART1, &UART_InitStruct);
  •     UART_ITConfig(UART1,UART_IT_EN,DISABLE);
  •     UART_DMACmd(UART1,UART_DMAReq_TX,DISABLE);
  •     UART_DMACmd(UART1,UART_DMAReq_RX,DISABLE);
  •     UART_PinRemapConfig(UART1,UART_PinRemap_Default);
  •     UART_TXCmd(UART1,ENABLE);
  •     UART_RXCmd(UART1,ENABLE);
  •     return 0;
  • }
  • INIT_BOARD_EXPORT(uart_init);

  • void rt_hw_console_output(const char *str)
  • {
  •     rt_enter_critical();
  •     while( *str != '\0')
  •     {
  •         if(*str == '\n')
  •         {
  •             UART1->UART_DATA = '\r';
  •             while(!(UART1->UART_STS & UART_STS_TXIF));
  •             UART1->UART_STS |= (uint16_t)UART_STS_TXIF;
  •         }
  •         UART1->UART_DATA = *str++;
  •         while(!(UART1->UART_STS & UART_STS_TXIF));
  •         UART1->UART_STS |= (uint16_t)UART_STS_TXIF;
  •     }
  •     rt_exit_critical();
  • }

  • #endif
  • 复制代码


    6. 配置MCU工作时钟

    SC32F10TC8芯片内部有PLL,我们启用它,配置最高工作频率64M,代码如下:

    void SystemClock_Config(void)
  • {       
  •         /*HIRC 40M*/
  •         RCC_Unlock(0xFF);
  •         RLL_Factor_TypeDef RLL_Factor_Struct;
  •         RLL_Factor_Struct.PLLM = 16; //PLLM=32/16=2MHz
  •         RLL_Factor_Struct.PLLN = 128; //PLLN=2*128=256MHz
  •         RLL_Factor_Struct.PLLP = 1;        //PLLP=PLLN/2^(1+1)=256/4=64MHz
  •         RCC_PLLConfig(RCC_PLLCLKSource_HIRC, &RLL_Factor_Struct);
  •         RCC_PLLCmd(ENABLE);
  •        
  •         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  •         {
  •                 uint32_t waiting = 1500;
  •                 while(waiting--);
  •                 RCC_Unlock(0xFF);
  •                 RCC_PLLRCmd(ENABLE);
  •         }
  •         RCC_PLLRCmd(ENABLE);
  •         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLRCLK);
  •         RCC_HCLKConfig(RCC_SYSCLK_Div1);
  •         SystemCoreClock = 64000000U;
  • }
  • 复制代码

    6. 创建示例应用

    6.1 修改main函数

    我们这里只开了一个点灯的任务:

    int main(void)
  • {
  •     rt_thread_t _task_serial = rt_thread_create("demo", task_led, RT_NULL, 1024, 0, 10);
  •    
  •     if(_task_serial != RT_NULL)
  •         rt_thread_startup(_task_serial);
  • }
  • 复制代码

    其中点灯任务使用了板载的TK25触摸按键下的LED灯,对应管脚为PB9,代码如下:

    void task_led(void *args)
  • {   

        GPIO_InitTypeDef GPIO_InitStructure;
  •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  •     GPIO_InitStructure.GPIO_DriveLevel = GPIO_DriveLevel_3;
  •     GPIO_Init(GPIOB, &GPIO_InitStructure);

  •     while(1)
  •     {
  •      GPIO_SetBits(GPIOB, GPIO_Pin_9);
  •      rt_kprintf("led on!\r\n");
  •      rt_thread_mdelay(1000);
  •      GPIO_ResetBits(GPIOB, GPIO_Pin_9);
  •      rt_kprintf("led off!\r\n");
  •      rt_thread_mdelay(1000);
  •     }
  • }
  • 复制代码

    7. 编译与调试

    • 编译工程,确保没有错误
    • 连接调试器,下载程序到目标板
    • 通过串口调试工具查看输出,确认RT-Thread正常运行

    Snipaste_2025-06-07_01-32-51.png

    同时可以观察板子上的LED灯以1秒的频次亮灭变化。