恶补DSP:1.F28335的时钟系统
在“微机世界”中,时钟系统就像城市的“中央发电厂”,负责给整个城市(DSP芯片)提供精准且稳定的时间节拍(时钟信号),让所有城市机构(寄存器、逻辑单元等)能有序协同工作。一旦时钟“发电厂”出现故障,城市的运转节奏就会紊乱,整个系统可能崩溃。
1. 时钟信号来源及接入方式
(1)外部时钟源(外部振荡器)
通过芯片的XCLKIN引脚或者复用的X1引脚输入外部时钟信号(外部电力公司)。城市直接引进电力,输入的电压等级不同,接入方式也有所区别。
具体接入方式:
-
3.3V外部时钟
将3.3V的时钟信号直接接入XCLKIN引脚,将X1接地,X2悬空,注意系统内部电压不能超过3.3V。城市接受来自标准高压电网的供电。 -
1.9V外部时钟
将1.9V的时钟信号接入X1引脚,XCLKIN接地,X2悬空,内部电压不能超过1.9V,即低压电力供应,适合更节能的运作方式。
(2)内部振荡器(晶体振荡器)
通过在X1和X2引脚之间连接一个晶体振荡器,内置电路产生稳定时钟信号。这是F28335最常用的方式,城市拥有自建的“发电厂”,独立产生基础电力。
2. 时钟信号的倍频与分频——PLL模块的作用
为什么需要PLL?
F28335最高工作主频为150MHz,但晶振只有30MHz,30MHz频率太低,直接使用无法满足高速DSP计算需求。PLL(Phase Locked Loop,锁相环)模块相当于“变压器+变速器”,将基础电力(时钟信号)变换成更高频率的电力,满足高性能需求。
时钟信号流向:
-
选择时钟源 —— “城市能源进口关口”与“本地发电厂”的选择
外部时钟或内部晶振产生的时钟信号,通过异或门选择后,成为OSCCLK信号(振荡器时钟信号)。也就是F28335这座城市需要一份稳定的电力供应(时钟信号),它可以选择:(1)进口电力(外部时钟):从外部大电网拿电力,可能是3.3V或者1.9V的不同规格电压;(2)本地发电厂(内部晶振):自己建了个发电厂(用晶体振荡器产生的电力),独立且稳定。“异或门”就像城市的电力进口关卡,负责判断和选择到底是从外部电网进口电力,还是从本地发电厂供电,经过选择后,统一形成城市的基础电力——OSCCLK(振荡器时钟信号)。
这就确保城市在需要时才能正常供电,避免浪费或损坏。
-
时钟使能控制—— “总配电室开关”
通过寄存器PLLSTS中的OSCOFF位控制振荡器是否输出时钟信号。选定基础电力(OSCCLK)后,是否允许这份电力进入城市的配电网,全由“总配电室”的主控开关控制。这个开关用寄存器中的 PLLSTS.OSCOFF位 来控制,相当于“电力总开关”。(1)当开关打开(OSCOFF=0),电力(时钟信号)可以进入后续的配电和转换系统; (2)当开关关闭(OSCOFF=1),电力被切断,城市内部暂时无电,系统暂停运行。
-
PLL倍频 —— “变压器厂”和“电网变速器”:倍数提升电力等级
PLL使能(PLLSTS寄存器PLLOFF位)后,OSCCLK信号进入PLL模块。通过寄存器PLLCTR设置倍频系数,最大可设置为10。例如,30MHz × 10 = 300MHz,成为VCOCLK信号(锁相环振荡器时钟信号)。城市的用电需求很大,30MHz的基础电力频率相当于低压供电,满足不了高端工业园区(CPU核心)高速运转的需求。
所以引入了这么一个关键的设备——PLL锁相环模块,就像城市电力系统中的“变压器厂”和“电网变速器”: (1)它把低压电(基础时钟信号30MHz)倍增为高压电(高频时钟信号)。 (2)通过控制面板(寄存器PLLCTR),可以设置“变压器”的倍率,最大可以放大10倍。 (3)例如,30MHz × 10 = 300MHz,就相当于把城市的电力变成了300MHz的高频电,满足工业园区高速运转的需求。 (4)此时的输出成为“VCOCLK”,也就是“变压器厂”输出的高频电力。
-
时钟分频 —— “稳压器”和“电网分流装置”:将超高频电力合理分配
因F28335最高主频150MHz,不能直接用300MHz。通过PLLSTS寄存器DIVSEL位设置分频系数,常用分频系数为2。最终CPU工作时钟CLKIN = 300MHz ÷ 2 = 150MHz。
虽然变压器厂输出了300MHz的高频电力,但城市的最高允许用电频率(CPU最大工作频率)是150MHz。
如果直接使用300MHz,可能导致城市设备损坏或过热。
此时,城市里还有一个关键设备——稳压器和电网分流装置(分频器):
(1)它把超高频电力合理降低一半,保证用电设备安全运行。
(2)分频比例通过控制面板(寄存器PLLSTS.DIVSEL位)设定,常用分频比为2。
(3)300MHz ÷ 2 = 150MHz,最终送入CPU核心使用,保证CPU在最高规格安全下运行。
具体代码分析:
F28335的时钟初始化函数如下:
void InitSysCtrl(void)
{// Disable the watchdogDisableDog();// Initialize the PLL control: PLLCR and DIVSEL// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.hInitPll(DSP28_PLLCR,DSP28_DIVSEL);// Initialize the peripheral clocksInitPeripheralClocks();
}
这个函数完成了城市(F28335)启动时最关键的三件事:
- 关闭看门狗(DisableDog)
- 启动并配置主发电厂(PLL倍频和分频设置)
- 打开城市内各个工厂和部门的电源阀门(外设时钟使能)
其中:
-
关闭看门狗就是城市刚开始供电时,要“禁用安全巡逻队”,防止巡逻队误判城市还没完全准备好而误动作断电或报警。这个操作是为了确保接下来调节电力系统不会被安全机制误判而被强制停机。
-
初始化PLL控制
- “启动并调节主变压器厂”(PLL)。“变压器厂”负责将基础电力(晶振频率)放大到符合城市高速运转要求的高频电力。
- 通过函数
InitPll(DSP28_PLLCR,DSP28_DIVSEL)
指定变压倍率和分频比例,确保主电网输出满足CPU和重要模块的运行频率需求。 - 期间会有变压器厂的自检和稳定过程,确保输出电压和频率稳定。
-
初始化外设时钟
- “打开城市内各个工厂、机关、通信中心的电源阀门”,为ADC实验室、通信中心、工业机械控制、计时调度等各个单位通电,让城市的各个功能模块都能正常开始工作。
- 这一步通过
InitPeripheralClocks()
函数完成,合理分配和使能各个模块的时钟,使城市整体功能协调启动。
每个函数的详细分析如下:
首先是InitPll(Uint16 val, Uint16 divsel)
函数,完整函数如下:
// PLL相关寄存器初始化函数
//---------------------------------------------------------------------------
// 此函数初始化PLLSTS[CLKINDIV]和PLLCR控制寄存器void InitPll(Uint16 val, Uint16 divsel)
{// Make sure the PLL is not running in limp modeif (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0){// Missing external clock has been detected// Replace this line with a call to an appropriate// SystemShutdown(); function.asm(" ESTOP0");}// DIVSEL MUST be 0 before PLLCR can be changed from// 0x0000. It is set to 0 by an external reset XRSn// This puts us in 1/4if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;EDIS;}// Change the PLLCRif (SysCtrlRegs.PLLCR.bit.DIV != val){EALLOW;// Before setting PLLCR turn off missing clock detect logicSysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;SysCtrlRegs.PLLCR.bit.DIV = val;EDIS;// Optional: Wait for PLL to lock.// During this time the CPU will switch to OSCCLK/2 until// the PLL is stable. Once the PLL is stable the CPU will// switch to the new PLL value.//// This time-to-lock is monitored by a PLL lock counter.//// Code is not required to sit and wait for the PLL to lock.// However, if the code does anything that is timing critical,// and requires the correct clock be locked, then it is best to// wait until this switching has completed.// Wait for the PLL lock bit to be set.// The watchdog should be disabled before this loop, or fed within// the loop via ServiceDog().// Uncomment to disable the watchdogDisableDog();while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1){// Uncomment to service the watchdog// ServiceDog();}EALLOW;SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;EDIS;}// If switching to 1/2if((divsel == 1)||(divsel == 2)){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;EDIS;}// If switching to 1/1// * First go to 1/2 and let the power settle// The time required will depend on the system, this is only an example// * Then switch to 1/1if(divsel == 3){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;DELAY_US(50L);SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;EDIS;}
}
逐行分析:
// 确保PLL没有进入limp模式(失去外部时钟信号保护模式)
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
{// 说明外部时钟丢失,需要系统安全处理// 这里直接用调试断点中断程序asm(" ESTOP0");
}
城市的“主电源监测系统”检测到外部电网(时钟源)断电,城市进入紧急保护模式(limp mode),为了避免城市设备损坏,马上拉闸断电(ESTOP0指令暂停CPU),等待人工干预。
// DIVSEL必须先设置为0才能修改PLLCR寄存器(倍频设置)
// 复位时DIVSEL是0,此时时钟分频为1/4,保证安全状态
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
{EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;EDIS;
}
像调整变压器厂(PLL)时,为了安全,先把配电网的分流装置(分频器DIVSEL)切换到最低档(1/4),避免变频过程中电力过载或设备损坏,然后才能安全调整变压器(PLLCR倍频系数)。EALLOW
/EDIS
是允许/禁止访问保护寄存器的指令,保证对关键寄存器的安全写操作。
// 如果PLL倍频值和当前不一样,则需要修改PLL倍频
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{EALLOW;// 修改倍频前关闭缺少时钟检测逻辑,避免误报警SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;// 设置PLL倍频系数SysCtrlRegs.PLLCR.bit.DIV = val;EDIS;
调整“变压器厂”的变压倍率前,先关闭“缺电报警系统”(MCLKOFF=1),避免变频瞬间被误判为时钟异常,安全执行变压操作。然后设置新的倍频系数,实现电力频率的放大。
// 下面是等待PLL锁定完成的操作:// CPU在PLL稳定之前,使用基础时钟信号(OSCCLK/2)保证运行// 等待PLL内部的锁相环检测确认频率稳定(PLLLOCKS位为1)// 在此期间可能需要喂狗,防止复位DisableDog(); // 关闭看门狗防止意外复位while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1){// 循环等待PLL锁定// ServiceDog(); // 若开看门狗则喂狗}EALLOW;// PLL已稳定,重新开启缺少时钟检测逻辑SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;EDIS;
}
- “变压器厂”开始变换电力频率后,需要一段时间来“稳定输出电流”(PLL锁定过程)。
- 在此期间,“城市暂时使用备用低频电力”(OSCCLK/2)维持基本运行。
- “看门狗”相当于“城市安全巡逻队”,需暂时关闭或定时喂养,避免误判城市“死火”。
- 等待“变压器厂输出稳定电力”信号(PLLLOCKS=1),确认频率稳定后才恢复正常运行。
- 最后重新打开“缺电报警系统”,恢复正常监控。
// 根据divsel的值调整系统时钟分频系数
if((divsel == 1)||(divsel == 2))
{EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;EDIS;
}
市政“配电网”的分流装置调整为1/1或1/2档,直接设置分频比,给CPU等设备分配合适频率的电力。
// 如果需要切换到最高频率分频1/1档
if(divsel == 3)
{EALLOW;// 先切到1/2档,给城市电力稳定时间(延时)SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;DELAY_US(50L); // 延时50微秒// 再切换到1/1档,满负荷运行SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;EDIS;
}
为了安全切换到最高档分频,不能直接跳过来。先让“配电网”逐步升档,从1/2档运行一段时间(50微秒),相当于给设备预热和电力稳定时间,防止电压骤升带来冲击。确认稳定后,再切换到1/1档,城市正式以最高频率的电力全速运行。
不妨再看看,完整函数如下:
void InitPeripheralClocks(void)
{EALLOW;// HISPCP/LOSPCP prescale register settings, normally it will be set to default valuesSysCtrlRegs.HISPCP.all = 0x0001;SysCtrlRegs.LOSPCP.all = 0x0002;//Lowspeedclock=SYSCLKOUT/4=150/4=37.5MHZ;// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT// XTIMCLK = SYSCLKOUT/2XintfRegs.XINTCNF2.bit.XTIMCLK = 1;// XCLKOUT = XTIMCLK/2XintfRegs.XINTCNF2.bit.CLKMODE = 1;// Enable XCLKOUTXintfRegs.XINTCNF2.bit.CLKOFF = 0;// Peripheral clock enables set for the selected peripherals.
// If you are not using a peripheral leave the clock off
// to save on power.
//
// Note: not all peripherals are available on all 2833x derivates.
// Refer to the datasheet for your particular device.
//
// This function is not written to be an example of efficient code.SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC// *IMPORTANT*// The ADC_cal function, which copies the ADC calibration values from TI reserved// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the// Boot ROM. If the boot ROM code is bypassed during the debug process, the// following function MUST be called for the ADC to function according// to specification. The clocks to the ADC MUST be enabled before calling this// function.// See the device data manual and/or the ADC Reference// Manual for more information.ADC_cal();SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2CSysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-ASysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-BSysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-CSysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-ASysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-ASysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-BSysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-ASysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-BSysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP3SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP4SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP5SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP2SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA ClockSysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLKSysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clockEDIS;
}
InitPeripheralClocks()
函数就是“城市电力系统”的配电调度中心,负责给城市内的各个部门(外设模块)打开电源阀门(时钟开关),让它们获得稳定的时钟电力,正常开展工作。
逐行分析如下:
EALLOW;
允许访问保护寄存器。相当于“进入电力调度控制室”,获得调节各配电阀门的权限。
SysCtrlRegs.HISPCP.all = 0x0001;
SysCtrlRegs.LOSPCP.all = 0x0002; // Lowspeedclock=SYSCLKOUT/4=150/4=37.5MHZ;
设置外设高速时钟预分频(HISPCP)和低速时钟预分频(LOSPCP)寄存器。
HISPCP和LOSPCP是“供电主干线上的变压器”,将主电厂送来的主时钟(150MHz)降压分流,供应给不同速度需求的部门。
LOSPCP=2
表示低速外设时钟是主时钟的1/4(150MHz/4=37.5MHz)。
这是合理的划分,保证低速外设不会因频率过高造成安全风险。
// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT
// XTIMCLK = SYSCLKOUT/2
XintfRegs.XINTCNF2.bit.XTIMCLK = 1;
// XCLKOUT = XTIMCLK/2
XintfRegs.XINTCNF2.bit.CLKMODE = 1;
// Enable XCLKOUT
XintfRegs.XINTCNF2.bit.CLKOFF = 0;
-
配置外部接口时钟(XCLKOUT)的分频和使能:
(1)XTIMCLK = SYSCLKOUT/2,XCLKOUT = XTIMCLK/2,最终XCLKOUT = SYSCLKOUT/4。使能XCLKOUT输出。 (2)外部接口时钟相当于“城市对外的工业园专线电力”,通过两级减压变电站(两级分频)降低主电压,保证接口设备安全供电。 (3)这里“打开外部工业园的专用电源阀门”(CLKOFF=0),保证接口外设有时钟“电力”。
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
-
给ADC模块打开时钟。“给城市里的实验室(ADC)送电”,有电才可以采集模拟信号。
// *IMPORTANT*
// The ADC_cal function, which copies the ADC calibration values from TI reserved
// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
// Boot ROM...
// ADC时钟必须打开,才能调用该校准函数
ADC_cal();
- 调用ADC校准函数,确保ADC模块工作精度。“实验室通电后,进行仪器的内部校准,确保测量准确。”
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-B
SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-C
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-A
SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-B
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-B
给各类通讯接口模块(I2C、SCI、SPI、McBSP、eCAN)开时钟。“给城市的各个通讯中心(电话局、邮局、数据中心)通电”,保持信息畅通无阻。
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
暂时关闭ePWM模块的时间基准时钟同步。“暂停城市内某些电厂的发电机同步工作”,准备做维护或配置。
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3
SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4
SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
打开6个增强型PWM模块的时钟。“给工业区的电动机械控制中心(PWM)供电”,保证机械设备按时工作。
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM
- 恢复ePWM时间基准时钟同步。“恢复各电厂发电机的同步运行”,保证电网稳定协调工作。
SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP3
SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP4
SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP5
SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP2
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2
为捕获单元(eCAP)和编码器接口(eQEP)模块开时钟。“给监测和计量部门(如传感器和编码器)供电”,保证城市能精准感知和测量运行状态。
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2
- 开启CPU定时器模块时钟。“启动城市的计时器和调度员,保证时间管理和任务调度正常”。
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock
SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock
- “启动高速物流系统(DMA)”,“打开外部接口电网”,“激活城市开关控制中心(GPIO)”,保证数据高速搬运、外部交互和开关控制正常运行。
EDIS;
禁止访问保护寄存器,退出修改权限。“离开电力调度控制室,锁定调度面板”,防止误操作。
所有时钟内容流程图如下所示。
链接:
通过网盘分享的文件:DSP时钟系统.png
链接: https://pan.baidu.com/s/1WZ0Y21tBy3H8r8vKcc2JjQ?pwd=qg2v 提取码: qg2v
该比喻的“世界观”也与之前的“微机世界”专栏文章差不多一致,如果需要的也可以看看前面的文章白话微机11:各种通信协议-CSDN博客