软件
依据厂家demo从新新建工程,工程中蕴含了gpio、usart。
硬件:
gpio
/ 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 内核退出到工程中了。
适配 RT-Thread Nano
中断与异样解决
须要删除工程里中断服务例程文件 hc32f460_interrupts.c中异样处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,防止在编译时产生反复定义。
零碎时钟配置
须要在 board.c 中实现 零碎时钟配置(为 MCU、外设提供工作时钟)与 os tick 的配置 (为操作系统提供心跳 / 节奏)。
void SysTick_Handler(void)
{
rt_os_tick_callback();
}
void rt_hw_board_init(void)函数中调用零碎时钟
SysClkConfig(); //零碎时钟初始化SysTick_Init(RT_TICK_PER_SECOND); //OS Tick 频率配置
void SysClkConfig(void)所在文件system_hc32f460.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; // 50MHzstcSysClkCfg.enPclk0Div = ClkSysclkDiv1; // 100MHzstcSysClkCfg.enPclk1Div = ClkSysclkDiv2; // 50MHzstcSysClkCfg.enPclk2Div = ClkSysclkDiv4; // 25MHzstcSysClkCfg.enPclk3Div = ClkSysclkDiv4; // 25MHzstcSysClkCfg.enPclk4Div = ClkSysclkDiv2; // 50MHzCLK_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);//时钟源抉择 XTALCLK_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
__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() 将被调用,如下所示:
编写第一个利用
1.应用rt_thread_mdelay()函数
移植RT-Thread Nano之前跑马灯应用厂家库函数
移植RT-Thread Nano之后跑马灯应用
2.建设线程
在 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
usart.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
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),不然会报重定义。
RT_WEAK void rt_hw_console_output(const char *str)
{
//#error "TODO 3: Output the string 'str' through the uart."
}
验证后果
在 Nano 上增加 FinSH 组件(实现命令输出)
增加FinSH组件
点击 Manage Run-Environment,勾选 shell,这将主动把 FinSH 组件的源码到工程
微信截图_20210812180550.png
rtconfig.h中 Configuration Wizard->Console Configuration开启RT_USING_CONSOLE
实现rt_hw_console_getchar(void)函数
usart.c
char rt_hw_console_getchar(void)
{
int ch = -1;if (Set == USART_GetStatus(USART_CH, UsartRxNoEmpty)){ ch = USART_RecData(USART_CH);}return ch;
}
验证后果
HC32F460移植RT-Thread Nano完结
近来芯片缺货大幕拉开,掀起新一轮国产代替浪潮。RT-Thread发动一场国产MCU移植奉献流动,邀请开发者们加入!
流动详情:国潮崛起!RT-Thread国产MCU移植奉献流动开启!