RT1020 时钟

本文详细解析了clock文件中CLOCK_SetMux函数的工作原理,该函数用于设定CCM寄存器,实现特定MUX模块的时钟源选择。通过具体实例展示了如何配置PLL1时钟作为AHB_CLK_BOOT时钟,涉及CBCMR和CBCDR寄存器的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.clock 文件 函数分析

/*!
 * @brief Set CCM MUX node to certain value. 为CCM 寄存器赋值
 *
 * @param mux  指定设定设置的MUX 模块
 * @param value  用于为选设定的模块选择时钟编号.
 */
static inline void CLOCK_SetMux(clock_mux_t mux, uint32_t value)
{
    uint32_t busyShift;
    volatile uint32_t CBCMR_value;

    busyShift               = CCM_TUPLE_BUSY_SHIFT(mux);//0x20
    CCM_TUPLE_REG(CCM, mux) = (CCM_TUPLE_REG(CCM, mux) & (~CCM_TUPLE_MASK(mux))) |
                              (((uint32_t)((value) << CCM_TUPLE_SHIFT(mux))) & CCM_TUPLE_MASK(mux));
    CBCMR_value = CCM->CBCMR;
    assert(busyShift <= CCM_NO_BUSY_WAIT);

    /* 时钟转换是否需要握手 */
    if (CCM_NO_BUSY_WAIT != busyShift)
    {
        /* Wait until CCM internal handshake finish. */
        while (CCM->CDHIPR & (1U << busyShift))
        {
        }
    }
}

例:不考虑时钟分频,PLL1 的时钟要经过两个MUX 模块CBCMR[PRE_PERIPH_CLK_SEL] 和 CBCDR[PERIPH_CLK_SEL] 才能作为 AHB_CLK_BOOT 时钟

  (1) CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);

    kCLOCK_PrePeriphMux  = CCM_TUPLE(CBCMR_OFFSET,   //0x18 寄存地址器偏移 (400F_C000h + 0x18)
                                                CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT, //CBCMR 位18
                                                CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK,// 0xC0000U
                                                CCM_NO_BUSY_WAIT), /*!< pre-periph mux name  0x20U 无需握手 */

>选择的模块为 kCLOCK_PrePeriphMux 如下图红色框所示模块,

>设置此模块的寄存器为 CBCMR[19-18]  且值为3 即选择PLL6如图2 所示 。

(2) CLOCK_SetMux(kCLOCK_PeriphMux, 0);

    kCLOCK_PeriphMux  = CCM_TUPLE(CBCDR_OFFSET, //0x14 寄存地址器偏移 (400F_C000h + 0x14)
                                          CCM_CBCDR_PERIPH_CLK_SEL_SHIFT, // CBCDR  位25
                                          CCM_CBCDR_PERIPH_CLK_SEL_MASK, // 0x2000000U
                                          CCM_CDHIPR_PERIPH_CLK_SEL_BUSY_SHIFT), /*!< periph mux name CDHIPR[5]*/

>选择的模块为 kCLOCK_PeriphMux如下图第二个红色框所示模块,

>设置此模块的寄存器为 CBCDR[25]  且值为0 即选择PLL6如图3 所示 。

                                                          图1

                                                        图2

                                                     图3 

### RT-Thread Studio 时钟配置使用教程 在RT-Thread Studio中,时钟配置通常涉及硬件时钟源的选择以及软件层面的时间管理。以下是关于如何在RT-Thread Studio中进行时钟相关配置的具体说明。 #### 硬件时钟源的选择 当使用STM32系列芯片时,可以通过STM32CubeMX工具来设置系统时钟源。如果目标板具有外部晶振,则可以选择外部时钟作为系统时钟源;如果没有外部晶振,则可以选用内部RC振荡器作为时钟源[^4]。这种选择不会显著影响最终的结果,但在精度和稳定性方面可能有所不同。 #### 软件时间管理 在RT-Thread操作系统下,时间管理是一个重要的组成部分。通过调用`rt_tick_get()`函数可以获得当前的滴答数,而滴答频率则由宏定义`RT_TICK_PER_SECOND`决定,默认情况下为1000Hz,即每毫秒产生一次中断[^1]。开发者可以根据实际需求调整该值以满足特定应用场景下的计时精度要求。 #### 创建与运行桌面mini网络时钟项目实例 为了更好地理解上述理论知识,在实践中构建一个简单的桌面mini网络时钟应用会很有帮助。按照官方文档指导完成基本环境搭建后,可参照具体案例学习如何利用RTOS特性实现同步更新显示时间等功能[^2]。此过程中需要注意确保安装目录不含特殊字符以免引发潜在错误。 ```c // 示例代码片段展示定时器回调处理程序部分逻辑结构 void timer_callback(void *parameter){ static int count = 0; rt_kprintf("Timer callback called %d times.\n", ++count); } int main(){ struct rt_timer* mytimer; /* 初始化 */ mytimer = rt_timer_create("myt", timer_callback, RT_NULL, 500, // 延迟周期(ms) RT_TIMER_FLAG_PERIODIC); if(mytimer != RT_NULL){ rt_timer_start(mytimer); } while(1){ rt_thread_mdelay(1000); } return 0; } ``` 以上代码展示了如何创建并启动一个周期性的软定时器,这有助于模拟实时刷新屏幕上的时间信息场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值