McuStudioMcuStudio
指南
开发者
组件
API
  • 版本发布
指南
开发者
组件
API
  • 版本发布
    • 组件
    • 模板
    • 基础组件
    • 容器组件
    • 芯片组件
    • 时钟树组件

时钟树组件

时钟树组件是一个可视化的图形编辑器,用于配置芯片内部的时钟网络。每个时钟树版本保存为一个 UI 配置文件,位于 ips/_CLOCK/ui/{系列}/ 目录下。

文件结构

ips/_CLOCK/ui/{系列}/
├── ui.cjs        # 时钟树图形布局(节点和连线)
└── data.cjs      # 时钟数据函数(挂载到 RCU 外设)

时钟树节点类型

时钟树中的每个节点是一个 cell,通过 shape: 'vue-shape' 渲染,核心数据定义在 _data 属性中。

时钟源(type: 'text')

显示固定的时钟源,如内部振荡器、外部晶振:

{
  shape: 'vue-shape',
  _data: {
    id: 'IRC8M',           // 唯一标识,通过 $clock['IRC8M'] 引用
    type: 'text',          // 只读文本类型
    label: 'IRC8M',        // 显示标签
    inclk: '8000000',      // 输入频率 (Hz)
    outclk: '',            // 输出频率
    outmin: '8000000',     // 最小输出频率
    outmax: '8000000',     // 最大输出频率
    disabled: true,        // 是否禁用(内部振荡器通常不可关闭)
    value: '8000000'       // 当前值
  }
}

常用时钟源:

ID说明典型频率
IRC8M内部 8MHz RC 振荡器8 MHz
HXTAL外部高速晶振4-16 MHz
LXTAL外部低速晶振32.768 kHz
IRC40K内部 40kHz RC 振荡器40 kHz

分频器(type: 'select')

对输入时钟进行分频,用户可选择分频系数:

{
  _data: {
    id: 'HXTAL_DIV',
    type: 'select',
    label: 'HXTAL/DIV',
    inclk: "@get: $clock['HXTAL'].outclk",         // 输入时钟引用
    outclk: '@get: $parent.inclk/parseInt($parent.selected.label.replace("/1",""))',  // 输出计算
    disabled: "@get: $clock['HXTAL'].disabled",     // 联动禁用
    value: '1',
    options: [
      { label: '/1', value: '1' },
      { label: '/2', value: '2' }
    ]
  }
}
属性说明
inclk输入时钟,通过 @get: 引用其他节点的 outclk
outclk输出时钟,通过 @get: 计算表达式
disabled联动禁用条件
options分频选项列表

多路选择器(type: 'mux')

从多个时钟源中选择一路输出:

{
  _data: {
    id: 'PLLSEL',          // PLL 时钟源选择
    type: 'mux',
    label: 'PLLSEL',
    value: 'value',
    options: [
      {
        label: '0',
        value: '0',
        inclk: "@get: $clock['IRC8M_DIV2'].outclk"  // 选项 0:内部时钟 /2
      },
      {
        label: '1',
        value: '1',
        inclk: "@get: $clock['HXTAL_DIV'].outclk",   // 选项 1:外部时钟分频
        disabled: "@get: $clock['HXTAL'].disabled"
      }
    ]
  }
}

每个选项的 inclk 定义该通道的输入时钟。mux 的输出时钟为当前选中选项的 inclk。

PLL 倍频器(type: 'select')

{
  _data: {
    id: 'PLLMF',
    type: 'select',
    label: 'PLLMF',
    inclk: "@get: $clock['PLLSEL'].outclk",
    outclk: "@get: $parent.inclk * parseFloat($parent.selected.label.replace('x', ''))",
    options: [
      { label: 'x2',  value: '0' },
      { label: 'x3',  value: '1' },
      { label: 'x9',  value: '7' },
      { label: 'x16', value: '14' }
    ]
  }
}

时钟树连线

节点之间通过 shape: 'edge' 的 cell 连接:

{
  shape: 'edge',
  source: {
    cell: 'b933ecea-...',    // 源节点 ID
    port: 'd4d43fb8-...'     // 源端口 ID
  },
  target: {
    cell: 'e2a881d3-...',    // 目标节点 ID
    port: '3cf1f689-...'     // 目标端口 ID
  }
}

总线预分频器

系统时钟经过 AHB、APB1、APB2 预分频器分配到各外设总线:

节点 ID说明连接
AHBPSCAHB 预分频器SYSCLK → HCLK
APB1PSCAPB1 预分频器(低速外设)HCLK → PCLK1
APB2PSCAPB2 预分频器(高速外设)HCLK → PCLK2

data.cjs — 时钟数据函数

data.cjs 将时钟树的输出挂载到 RCU 外设,供其他外设查询时钟频率:

// 状态查询
RCU.pll_enabled = () => $clock.SYSSEL.value === 'pll'
RCU.hse_enabled = () => RCU.HSE.value !== 'disable'
RCU.lse_enabled = () => RCU.LSE.value !== 'disable'

// 频率查询
RCU.clock_hse = () => $clock.HXTAL.outclk     // HSE 频率
RCU.clock_hsi = () => $clock.IRC8M.outclk     // HSI 频率

// 外设时钟查询 — 根据外设名返回其总线时钟
RCU.get_ip_clock = (per) => {
  if (per.includes('TIM')) {
    // TIM1-6 用 CK_TIMER_GROUP1x, TIM0,7-10 用 CK_TIMER_GROUP2x
    const num = per.replace('TIM', '')
    if (['1','2','3','4','5','6','11','12','13'].includes(num))
      return $clock.CK_TIMER_GROUP1x.outclk
    if (['0','7','8','9','10'].includes(num))
      return $clock.CK_TIMER_GROUP2x.outclk
  }
  if (per.includes('ADC')) return $clock.CK_ADCx.outclk
  if (per.includes('SPI') || per.includes('I2S')) return $clock.CK_PCLK2.outclk
  if (per.includes('CAN') || per.includes('UART') || per.includes('USART'))
    return $clock.CK_PCLK1.outclk
  return 0
}

通过 @get: 引用时钟

在 ui.cjs 的 _data 中,使用 @get: 表达式动态引用时钟值:

// 引用 HXTAL 的输出频率
inclk: "@get: $clock['HXTAL'].outclk"

// 引用 PLLSEL 选中选项的输出频率  
outclk: "@get: $clock['PLLSEL'].outclk"

// 计算 PLL 倍频输出
outclk: "@get: $parent.inclk * parseInt($parent.selected.label.replace('x', ''))"

// 联动禁用:HXTAL 禁用时,HXTAL_DIV 也禁用
disabled: "@get: $clock['HXTAL'].disabled"
Prev
芯片组件