点击上方[物联网思考],点击关注,第一时间查看物联网精彩分享!
本文使用GD32F150C6T6 MCU,基本资源Flash:32KB,SRAM:6KB。
1、下载RT-Thread Nano的源码,如下:
https://www.rt-thread.org/page/download.html
2、在工程目录下添加RT-Thread文件夹,如下:
3、将下载的RT-Thread Nano的源码解压,然后拷贝到RT-Thread文件夹,如下:
4、将内核代码添加到工程中,如下:
5、将cpu相关代码添加到工程中,如下:
GD32F130属于ARM cortex m3内核的,使用keil开发的,
6、添加板级支持文件,如下:
board.c
文件中主要配置了系统的时钟,是内核定时器systick,默认1ms一次时钟节拍。
7、工程添加RTT相关头文件路径
8、编译、报错,”RTE_Components.h”文件找不到,如下:
屏蔽掉即可解决:
9、再次编译,报错,PendSV_Handler和HardFault_Handler重复定义:
可以看出这两个中断在context_rvds
和gd32f1x0_it
中重复定义,删除掉gd32f1x0_it
文件中的即可。
10、实现LED闪烁
(1)硬件初始化
代码语言:javascript复制void LedInit(void)
{
rcu_periph_clock_enable(RCU_GPIOF);
/* configure led GPIO port */
gpio_mode_set(GPIOF, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_6|GPIO_PIN_7);
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7);
}
(2)创建线程(任务)并启动
代码语言:javascript复制void LedThreadStart(void)
{
//线程创建,使用静态方式
rt_thread_init(&led_thread,
"led",
led_thread_entry,
RT_NULL,
&led_thread_stack[0],
sizeof(led_thread_stack),
RT_THREAD_PRIORITY_MAX - 1,
32);
/* 启动线程,开启调度 */
rt_thread_startup(&led_thread);
}
(3)线程主体,实现LED闪烁
代码语言:javascript复制void led_thread_entry(void *parameter)
{
while (1)
{
gpio_bit_reset(GPIOF, GPIO_PIN_6|GPIO_PIN_7);
rt_thread_delay(500); /* 延时500个tick */
gpio_bit_set(GPIOF, GPIO_PIN_6|GPIO_PIN_7);
rt_thread_delay(500); /* 延时500个tick */
}
}
(4)在系统初始化的时候调用LED初始化函数
代码语言:javascript复制void rt_hw_board_init()
{
/* System Clock Update */
SystemCoreClockUpdate();
extern void LedInit(void);
LedInit();
/* System Tick Configuration */
_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
}
(5)在面函数中调用LED线程创建、启动函数
代码语言:javascript复制int main(void)
{
LedThreadStart();
return 0;
}
11、实现串口打印输出
(1)在 rtconfig.h 中使能 RT_USING_CONSOLE 宏定义
(2)串口硬件初始化
代码语言:javascript复制void HandCommInit(void)
{
rcu_periph_clock_enable( RCU_GPIOA);
rcu_periph_clock_enable( RCU_USART1);
/* connect port to USARTx_Tx */
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);
/* connect port to USARTx_Rx */
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3);
/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_2);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ,GPIO_PIN_2);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_3);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ,GPIO_PIN_3);
/* USART configure */
usart_deinit(USART1);
usart_baudrate_set(USART1,115200U);
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
usart_receive_config(USART1, USART_RECEIVE_ENABLE);
usart_enable(USART1);
}
(3)实现系统控制台输出函数 系统中是以虚函数的形式给出的,用户重新实现即可:
代码语言:javascript复制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 )
{
if (*(str i) == 'n')
{
usart_data_transmit(USART1, (uint32_t )a);
while((usart_flag_get(USART1, USART_FLAG_TC) == RESET));
}
usart_data_transmit(USART1, (uint32_t)*(str i));
while((usart_flag_get(USART1, USART_FLAG_TC) == RESET));
}
}
(4)在系统初始化函数中,调用串口初始化函数
代码语言:javascript复制void rt_hw_board_init()
{
/* System Clock Update */
SystemCoreClockUpdate();
extern void LedInit(void);
LedInit(); extern void HandCommInit(void);
HandCommInit();
/* System Tick Configuration */
_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
}
12、移植 FinSH 组件(实现命令输入)
(1)工程添加FinSH 组件代码
(2)在rtconfig.h中包含#include “finsh_config.h”
(3)实现char rt_hw_console_getchar(void)函数 rt_hw_console_getchar系统以虚函数的形式给出,并且加了预编译报错信息,提示用户实现字符输入。
去掉原虚函数中的预编译报错信息,重新实现即可。
代码语言:javascript复制char rt_hw_console_getchar(void)
{
/* the initial value of ch must < 0 */
int ch = -1;
if (usart_flag_get(USART1, USART_FLAG_RBNE) != RESET)
{
ch = usart_data_receive(USART1);
}
else
{
rt_thread_mdelay(10);
}
return ch;
}
13、正确连接串口,使用串口终端打开,重启mcu,就会出现如下的打印信息:
输入help可以查看支持的命令,ps可以查看线程等。
篇幅限制,文中只列出了部分代码,如需完整工程,后台联系。
——————END——————