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