Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
HC32F4
RT-Thread Nano
国产MCU移植
HC32F460基于Keil MDK 移植 RT-Thread Nano
发布于 2021-08-12 19:45:51 浏览:3646
订阅该版
[tocm] ## 软件 根据厂家demo重新新建工程,工程中包含了gpio、usart。 ## 硬件: ### gpio ```c /* GREEN_LED Port/Pin definition */ #define GREEN_LED_PORT (PortE) #define GREEN_LED_PIN (Pin00) /* RED_LED Port/Pin definition */ #define RED_LED_PORT (PortE) #define RED_LED_PIN (Pin01) ``` usart4 ``` /* USART RX Port/Pin definition */ #define USART_RX_PORT (PortC) #define USART_RX_PIN (Pin07) #define USART_RX_FUNC (Func_Usart4_Rx) /* USART TX Port/Pin definition */ #define USART_TX_PORT (PortC) #define USART_TX_PIN (Pin06) #define USART_TX_FUNC (Func_Usart4_Tx) ``` ## _添加 RT-Thread Nano 到工程_ 在 Manage Rum-Time Environment 内打开 RTOS 栏,勾选 kernal,点击 OK 后就将 RT-Thread 内核加入到工程中了。 ![QQ截图20210812114523.png](https://oss-club.rt-thread.org/uploads/20210812/6587258a9c9461e4ca807a82c849de0b.png) ## _适配 RT-Thread Nano_ ### 中断与异常处理 需要删除工程里中断服务例程文件 hc32f460_interrupts.c中异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,避免在编译时产生重复定义。 ![微信截图_20210812134247.png](https://oss-club.rt-thread.org/uploads/20210812/5e57b66cd80c780e545b74a6177d8354.png) ### 系统时钟配置 需要在 board.c 中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os tick 的配置 (为操作系统提供心跳 / 节拍)。 ```c void SysTick_Handler(void) { rt_os_tick_callback(); } ```` `void rt_hw_board_init(void)`函数中调用系统时钟 ```c SysClkConfig(); //系统时钟初始化 SysTick_Init(RT_TICK_PER_SECOND); //OS Tick 频率配置 ``` `void SysClkConfig(void)`所在文件`system_hc32f460.c` ```c void SysClkConfig(void) { stc_clk_sysclk_cfg_t stcSysClkCfg; //系统时钟 stc_clk_xtal_cfg_t stcXtalCfg; //晶振配置 stc_clk_mpll_cfg_t stcMpllCfg; //PLL stc_sram_config_t stcSramConfig; MEM_ZERO_STRUCT(stcSysClkCfg); MEM_ZERO_STRUCT(stcXtalCfg); MEM_ZERO_STRUCT(stcMpllCfg); /* Set bus clk div. 分频 */ stcSysClkCfg.enHclkDiv = ClkSysclkDiv1; // 100MHz stcSysClkCfg.enExclkDiv = ClkSysclkDiv2; // 50MHz stcSysClkCfg.enPclk0Div = ClkSysclkDiv1; // 100MHz stcSysClkCfg.enPclk1Div = ClkSysclkDiv2; // 50MHz stcSysClkCfg.enPclk2Div = ClkSysclkDiv4; // 25MHz stcSysClkCfg.enPclk3Div = ClkSysclkDiv4; // 25MHz stcSysClkCfg.enPclk4Div = ClkSysclkDiv2; // 50MHz CLK_SysClkConfig(&stcSysClkCfg);//时钟分频 /* Switch system clock source to MPLL. */ /* Use Xtal as MPLL source. */ stcXtalCfg.enMode = ClkXtalModeOsc;//XTAL模式选择位 stcXtalCfg.enDrv = ClkXtalLowDrv;/*XTAL驱动能力选择 stcXtalCfg.enFastStartup = Enable;/*XTAL超高速驱动允许 CLK_XtalConfig(&stcXtalCfg);//CMU XTAL 配置寄存器 CLK_XtalCmd(Enable);//开启CMU XTAL while(Set != CLK_GetFlagStatus(ClkFlagXTALRdy)) { ; } /* MPLL config. */ stcMpllCfg.pllmDiv = 1ul;//MPLL输入时钟分频系数 stcMpllCfg.plln =50ul;//MPLL倍频系数 stcMpllCfg.PllpDiv = 4ul; stcMpllCfg.PllqDiv = 4ul; stcMpllCfg.PllrDiv = 4ul; CLK_SetPllSource(ClkPllSrcXTAL);//时钟源选择 XTAL CLK_MpllConfig(&stcMpllCfg);//CMU MPLL 时钟分频配置 /* flash read wait cycle setting */ EFM_Unlock(); EFM_SetLatency(5ul); EFM_Lock(); /* sram init include read/write wait cycle setting */ stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx; stcSramConfig.enSramRC = SramCycle2; stcSramConfig.enSramWC = SramCycle2; stcSramConfig.enSramEccMode = EccMode3; stcSramConfig.enSramEccOp = SramNmi; stcSramConfig.enSramPyOp = SramNmi; SRAM_Init(&stcSramConfig); /* Enable MPLL. */ CLK_MpllCmd(Enable);//用于开始停止MPLL。0:MPLL动作开始 1:MPLL停止 /* Wait MPLL ready. */ while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy)) { ; } /* Switch system clock source to MPLL. */ CLK_SetSysClkSource(CLKSysSrcMPLL);//CMU 系统时钟源切换寄存器 } ``` `en_result_t SysTick_Init(uint32_t u32Freq)`所在文件`hc32f460_utility.c` ```c __WEAKDEF en_result_t SysTick_Init(uint32_t u32Freq) { en_result_t enRet = Error; if ((0UL != u32Freq) && (u32Freq <= 1000UL)) { m_u32TickStep = 1000UL / u32Freq; /* Configure the SysTick interrupt */ if (0UL == SysTick_Config(SystemCoreClock / u32Freq)) { enRet = Ok; } } return enRet; } ``` ### 内存堆初始化 系统内存堆的初始化在 board.c 中的 rt_hw_board_init() 函数中完成,内存堆功能是否使用取决于宏 RT_USING_HEAP 是否开启,RT-Thread Nano 默认不开启内存堆功能,这样可以保持一个较小的体积,不用为内存堆开辟空间。 开启系统 heap 将可以使用动态内存功能,如使用 rt_malloc、rt_free 以及各种系统动态创建对象的 API。若需要使用系统内存堆功能,则打开 RT_USING_HEAP 宏定义即可,此时内存堆初始化函数 rt_system_heap_init() 将被调用,如下所示: ![微信图片_20210812152921.png](https://oss-club.rt-thread.org/uploads/20210812/92f518784569dfa96ae0f2004078d6e2.png) ### 编写第一个应用 #### 1.使用rt_thread_mdelay()函数 移植RT-Thread Nano之前跑马灯使用厂家库函数 ![微信截图_20210812155454.png](https://oss-club.rt-thread.org/uploads/20210812/75257fa9400ac86a743d38d8e499bd62.png) 移植RT-Thread Nano之后跑马灯使用 ![微信截图_20210812155338.png](https://oss-club.rt-thread.org/uploads/20210812/a0f9c5acb90b1460c0446334c4d2a999.png) #### 2.建立线程 ![微信截图_20210812162440.png](https://oss-club.rt-thread.org/uploads/20210812/270b02881cfd5ff00e0861366f8aaa85.png) ## 在 Nano 上添加 UART 控制台 在 RT-Thread Nano 上添加 UART 控制台打印功能后,就可以在代码中使用 RT-Thread 提供的打印函数 rt_kprintf() 进行信息打印,从而获取自定义的打印信息,方便定位代码 bug 或者获取系统当前运行状态等。实现控制台打印(需要确认 rtconfig.h 中已使能 RT_USING_CONSOLE 宏定义),需要完成基本的硬件初始化,以及对接一个系统输出字符的函数。 #### 实现串口初始化 rtconfig.h中 Configuration Wizard->Console Configuration开启RT_USING_CONSOLE ![微信截图_20210812163833.png](https://oss-club.rt-thread.org/uploads/20210812/22838cbdb7357aad324ad3f9acb9432d.png) usart.c ```c int rt_Usart_Init(void) { uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \ PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4; const stc_usart_uart_init_t stcInitCfg = { UsartIntClkCkOutput, UsartClkDiv_1, UsartDataBits8, UsartDataLsbFirst, UsartOneStopBit, UsartParityNone, UsartSampleBit8, UsartStartBitFallEdge, UsartRtsEnable, }; /* Enable peripheral clock */ PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable); /* Initialize USART IO */ PORT_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC, Disable); PORT_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC, Disable); /* Initialize UART */ while(Ok != USART_UART_Init(USART_CH, &stcInitCfg)); /* Set baudrate */ while(Ok != USART_SetBaudrate(USART_CH, USART_BAUDRATE)); /*Enable RX && RX function*/ USART_FuncCmd(USART_CH, UsartRx, Enable); USART_FuncCmd(USART_CH, UsartTx, Enable); return 0; } INIT_BOARD_EXPORT(rt_Usart_Init); ``` #### 实现 rt_hw_console_output usart.c ```c 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') { while (Reset == USART_GetStatus(USART_CH, UsartTxEmpty)) {}; /* Warit Tx data register empty */ USART_SendData(USART_CH,(uint16_t)a); } while (Reset == USART_GetStatus(USART_CH, UsartTxEmpty)){}; /* Warit Tx data register empty */ USART_SendData(USART_CH,(*(str + i))); } } ``` RT_WEAK修饰函数 board.c中`rt_hw_console_output(const char *str)`,不然会报重定义。 ```c RT_WEAK void rt_hw_console_output(const char *str) { //#error "TODO 3: Output the string 'str' through the uart." } ``` #### 验证结果 ![微信截图_20210812180303.png](https://oss-club.rt-thread.org/uploads/20210812/aa62b55211c253c6abee72a2519f9989.png) ##在 Nano 上添加 FinSH 组件(实现命令输入) ####添加FinSH组件 点击 Manage Run-Environment,勾选 shell,这将自动把 FinSH 组件的源码到工程 ![微信截图_20210812180550.png](https://oss-club.rt-thread.org/uploads/20210812/28785289efc39b59133275d586b18a14.png) rtconfig.h中 Configuration Wizard->Console Configuration开启RT_USING_CONSOLE ![微信截图_20210812180817.png](https://oss-club.rt-thread.org/uploads/20210812/05acf62738d2621d7141ff121209f3e8.png) #### 实现`rt_hw_console_getchar(void)`函数 usart.c ```c char rt_hw_console_getchar(void) { int ch = -1; if (Set == USART_GetStatus(USART_CH, UsartRxNoEmpty)) { ch = USART_RecData(USART_CH); } return ch; } ``` #### 验证结果 ![finsh.gif](https://oss-club.rt-thread.org/uploads/20210812/d9cd45f2482b472bfbc1aa350759223b.gif) # HC32F460移植RT-Thread Nano结束
15
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
想当诸侯的小蚂蚁
这家伙很懒,什么也没写!
文章
7
回答
5
被采纳
0
关注TA
发私信
相关文章
1
求高手指点,RTThread下nanosleep()函数功能如何实现?在线等啊
2
RTT1.2.2在新塘Nano130KE3BN的移植中始终出现栈溢出的问题
3
官方能否出一个nano在mdk下移植finsh到stm32的教程
4
从裸机开始,创建一个RT-Thread Nano系统工程
5
Nano版如何启用shell
6
项目从RTT 2.x NANO移植到 RTT 3.x ENV 环境
7
nano 版本有没有集成到 IAR 中啊?
8
关于MDK5的RT-THREAD NANO中添加MSH组件的例程
9
rtt_nano版本,源代码在哪里下载啊?
10
RTT Nano 在keil 使用C++11 的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
812
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部