TMS320F28335之系统时钟
来源:互联网 发布:手机连发软件 编辑:程序博客网 时间:2024/05/16 19:18
TMS320F28335时钟(1)
PLL作用就是对外部时钟进行倍频,降低产生高频时钟信号的成本。但是倍频配置的时候,需要在特定的条件下更改,因此需要检测PLL工作的各种状态信号,因此PLL有两个配置相关寄存器,PLL状态寄存器PLLSTS和PLL控制寄存器PLLCR。通过对状态寄存器PLLSTS的判断,可以判断PLL的工作状态,在特定的工作状态下,对PLL控制寄存器PLLCR进行配置,最后产生合适的时钟信号CLKIN输入给CPU,完成整个过程的倍频。本文详细介绍了PLL模块,并对初始化过程和初始化代码进行了分析。
1.OSC和PLL模块
OSC和PLL模块方框图如图1所示。
基于 PLL 的时钟模块提供两种操作模式:
• 晶振操作模式:允许使用一个外部晶振/谐振器来提供到器件的时基。
• 外部时钟源操作模式:允许旁通内部振荡器被,时钟由一个 X1 或者 XCLKIN 引脚上的外部时钟源输入生成。
三种输入时钟配置如图2、图3、图4所示
30MHz 外部石英晶振的典型技术规范如下:
• 基本模式、 并联谐振
• CL( 负载电容) =12pF
• CL1=CL2=24pF
• C并联=6pF
• ESR 范围 = 25 至 40Ω
2.基于 PLL 的时钟模块
TMS320F23885上有一个片载、基于PLL倍频器的时钟模块,它提供所有的时钟信号以及实现对低功耗模式的控制。
PLL作为DSP的时钟重要组成部分,它除了提高系统内部SYSCLKOUT的频率之外,还有一个重要的用途就是监视外部时钟是不是很好的为DSP内部提供系统时钟。
如果PLL处于使能状态,需要监视PPLSTS寄存器中的MCLKSTS位的状态。如果MCLKSTS被置位,则软件要采集恰当的措施保证系统不出现事故,该措施包括使系统停机、复位等。
与PLL配置相关的寄存器有两个:PLL状态寄存器PLLSTS和PLL控制寄存器PLLCR,两个寄存器具体的讲解参见第3节。
两个寄存器中最关键的位域分别为 2位的PLLSTS[DIVSEL]和4位的PLLCR[DIV]。
PLLSTS[DIVSEL]选择CPU时钟的分频系数(/4,/2,/1),PLLCR[DIV] 选择CPU时钟的倍频系数(*1,*2,……,*10)。
比如TMS320F23885最大工作时钟为150MHz,通常外部晶振频率为30MHz,先将30MHz进行10倍频变成300MHz,再对300MHz进行2分频得到150MHz的时钟。(官方例程里产生150MHz的方式)
PLL的设置如表1所示。
分频系数的选择如表2所示。
PLL可能的配置模式如表3所示。
注:
(1)默认情况下,分频系数为4
(2)在改变PLLCR[DIV]倍频系数前,必须满足两个条件:
•PLLSTS[DIVSEL]必须为0,而PLLSTS[DIVSEL]改变时,PLL必须完成锁定状态,即PLLSTS[PLLOCKS]必须为1
•DSP不能工作在limp mode下,即PLLSTS[MCLKSTS]必须为0
(3)一旦PLL稳定之后,会锁定在新的频率下工作,PLLSTS[PLLLOCKS] = 1,可以改变PLLSTS[DIVSEL]。
(4)在写入 PLLCR 寄存器之前, 安全装置模块(看门狗)应该被禁用。
(5)在 PLL 模块稳定后,重新启用安全装置模块(看门狗),重启的时间为 131072 个 OSCCLK 周期。
(6)在 PLL (VCOCLK) 的输出频率不超过300MHz 时候,选择输入时钟和 PLLCR[DIV] 位。
(7)当PLL激活时,即PLL不是旁路(PLLCR[DIV]!=0),必须需要分频器,即分频系数不能为1(PLLSTS[DIVSEL]!=3),这是因为确保反馈给内核的时钟具有正确的占空比。
(8)只有外部复位信号RST和安全装置(看门狗)产生复位信号时,PLLCR和PLLSTS才会复位到默认值,而调试器和Missing clock detect logic产生的复位信号不会使两者复位到默认值。
(9)PLLCR和PLLSTS是受ELLOW保护的。
特别注意:倍频时一定要分频,不倍频时才允许不分频。
3.PLL配置相关的寄存器
PLL控制寄存器PLLCR如表4所示。
PLL状态寄存器PLLSTS如表5所示。
PLLSTS各位的描述如表6所示
注:跛行模式(limp mode)系统出现问题的时候,控制逻辑能够根据对应的条件进行判断,安排另外的一套控制电平,使得必须控制的负载按照既定的逻辑运行。
4.PLL的初始化
PLL初始化流程图如图2所示。
根据流程图,大致可以描述PLL的初始化过程为:
(1)确保存在OSCCLK,系统能正常工作,即判断PLLSTS[MCLKSTS]==1?
(2)改变PLLCR[DIV]前,确保PLLSTS[DIVSEL]==0
(3)改变PLLCR[DIV]前,禁用主振荡器故障检测逻辑模块,即PLLCR[MCLKOFF]=1
(4)根据需要,改变PLLCR[DIV]
(5)判断PLL是否稳定锁定,即PLLSTS[PLLLOCKS]==1?
(6)使能主振荡器故障检测逻辑模块,即PLLCR[MCLKOFF]=0
(7)根据需要,改变PLLSTS[DIVSEL]
PLL初始化的代码如下(来自官方例程,主要对其注释分析和讲解)。
/* * 函数名称:InitPll * 函数输入:倍频参数val,分频参数divsel * val取值为0到10,表示倍频数;divsel取值0到4,0和1表示4分频,2表示2分频,3表示不分频 * 函数输出:无 * 函数调用:InitPll(10,2); * 先将外部时钟倍频10倍,在分频1/2,最后产生的时钟CLKIN输入CPU28x */void InitPll(unsigned short div, unsigned short divsel){ // 确保PLL不是工作在limp mode下,即有外部时钟进入PLL if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0) { //检测到无外部时钟,软件要采集恰当的措施保证系统不出现事故,该措施包括 //使系统停机、复位等 //用适合的函数替换下面一行 // SystemShutdown(); function. asm(" ESTOP0"); } // PLLCR从0x0000改变前,PLLSTS[DIVSEL]必须为0 // 外部RST复位信号会使PLLSTS[DIVSEL]复位 // 此时分频为1/4 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 0; EDIS; } // 前面条件都满足后,可以改变PLLCR[DIV] if (SysCtrlRegs.PLLCR.bit.DIV != val) { EALLOW; // 在设置PLLCR[DIV]前,要禁用主振荡器检测逻辑 //Missing clock detect logic SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1; SysCtrlRegs.PLLCR.bit.DIV = div; EDIS; //等待PLL稳定且处于锁定状态,即PLLSTS[LOCKS]置位 //等待稳定的时间可能略长,需要禁用看门狗或者循环喂狗 //屏蔽注释,禁用看门够 DisableDog(); while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) { //屏蔽注释,喂狗 // ServiceDog(); } EALLOW; SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0; EDIS; } // 如果需要分频1/2 if((divsel == 1)||(divsel == 2)) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel; EDIS; } //注意:下面代码只有在PLL是旁路或者关闭模式时,才可被执行,其他模式禁止。 //倍频时一定要分频,不倍频时才允许不分频 //如果需要切换分频到1/1 // * 首先从默认1/4分频切换到1/2分频,让电源稳定 // 稳定所需要的时间依赖于系统运行速度,此处延时50us只是作为一个特例 // * 稳定后,再切换到1/1 if(divsel == 3) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 2; DELAY_US(50L); SysCtrlRegs.PLLSTS.bit.DIVSEL = 3; EDIS; }}
5.本章小结
本章介绍OSC和PLL模块,阐述了二种外部时钟输入的操作模式,然后对外部时钟进行倍频分析,即PLL模块,对PLL模块的寄存器和操作进行了详细的分析,最后给出了PLL初始化代码并对代码进行了注释分析。对基本设置特别要强调的是PLL倍频时一定要分频,不倍频时才允许不分频。
TMS320F28335时钟(2)
TMS320F28335通过外部时钟信号、OSC和PLL产生倍频时钟信号CLKIN后,CLKIN经过CPU后产生时钟SYSCLKOUT(CLKIN和SYSCLKOUT频率是一样的),SYSCLKOUT给各个片内外设提供时钟信号。为了实现低功耗和提供高低频率时钟信号,需要把SYSCLKOUT进一步分频,本章主要讲解了对SYSCLKOUT分频产生低频时钟信号和高频时钟信号,完成外设时钟初始化的过程。
1.时钟系统
时钟系统结构如图1所示。
从图1可以看出,时钟CLKIN经过CPU后产生时钟SYSCLKOUT(CLKIN和SYSCLKOUT频率是一样的),SYSCLKOUT给各个片内外设提供时钟;除了SPI、SCI、McBSP模块使用低频时钟,ADC使用高频时钟外,其他外设模块都是采用SYSCLKOUT时钟。为了实现低功耗,必须对每个片内外设时钟进行开关控制;为了实现高低频率时钟,必须对SYSCLKOUT进行不同的分频处理,因此与外设时钟配置相关的寄存器主要有两类:外设时钟控制寄存器PCLKCR和高低频外设时钟分频寄存器SPCP。
第一类寄存器是外设时钟控制寄存器PCLKCR,它包括16位的PCLKCR0、PCLKCR1、PCLKCR3(不知道为什么跳过了PCLKCR2??),主要是控制使能和禁用外设时钟;
第二类寄存器是高低频外设时钟分频寄存器,它包括高频外设时钟分频寄存器16位的HISPCP(High-Speed Peripheral Clock Prescaler Register)和低频外设时钟分频寄存器16位的LOSPCP(Low-Speed Peripheral Clock Prescaler Register)
2.与外设时钟配置相关的寄存器
控制片内外设时钟开关的外设时钟控制寄存器PCLKCR0、PCLKCR1、PCLKCR3如表1、表2、表3所示。
从表1、表2、表3可以看出,默认情况下,除了3个CPU定时器和GPIO口输入采样时钟使能外,其他所有外设的时钟是禁用的。
**注:
- PCLKCR0、PCLKCR1、PCLKCR3均受ELLOW保护。
- 不使用某外设模块时,可以禁用该时钟模块的时钟以省电。 **
产生高低频外设时钟的分频寄存器HISPCP和LOSPCP分别如表4和表5所示。
两个寄存器具体位域描述分别如表6和表7所示。
从表4到表7可以看出,16位的高频外设时钟分频寄存器HISPCP和低频外设时钟分频寄存器LOSPCP都只用了低3位;两个寄存器都受ELLOW保护;分频计算方法:当分频系数为0,表示时钟等于SYSCLKOUT/1,当分频系数不为0时,CLK=SYSCLKOUT/(n×2)。
3.时钟输出
SYSCLKOUT可以按1、2、4分频从TMS320F28335的XCLKOUT引脚输出,SYSCLKOUT输出示意图如2所示。
从图2可以看出,上电或复位默认情况下,SYSCLK2分频产生XTIMCLK,XTIMCLK再通过2分频产生XCLKOUT时钟,该时钟信号通过引脚XCLKOUT输出,即默认情况下XCLKOUT=SYSCLK/4=OSCCLK/16,调试时可以观察该引脚的信号以判断设备是否在正确的时钟下工作。
注:
- XCLKOUT引脚上电或者复位默认情况下是激活状态的。
- XCLKOUT引脚没有上拉或者下拉电阻。
- 如果XCLKOUT引脚不使用时,可以通过XINTCNF2[CLKOFF]=1关闭。
- 默认情况下,XTIMCLK=SYSCLKOUT/2,它是外扩模块(外扩FLASH、SRAM等)的时钟
4.外设时钟初始化代码
此初始化代码主要来自TI官方例程,注释是个人理解。
/**函数名称:InitPeripheralClocks*输入参数:无*输出参数:无*函数功能:初始化外设时钟模块,主要包括产生高低速时钟、开关所需片内外设模块时*钟等*/void InitPeripheralClocks(void){ EALLOW;// 高低频外设时钟分频寄存器HISPCP/LOSPCP设置,正常情况下采用默认值,即高频时钟为SYSCLKOUT/2,低速时钟为SYSCLKOUT/4 SysCtrlRegs.HISPCP.all = 0x0001; SysCtrlRegs.LOSPCP.all = 0x0002;// 时钟输出引脚XCLKOUT设置,默认情况XCLKOUT = SYSCLKOUT/4 // XTIMCLK = SYSCLKOUT/2 XintfRegs.XINTCNF2.bit.XTIMCLK = 1;//extern interface clock<->XinfCLK // XCLKOUT = XTIMCLK/2 XintfRegs.XINTCNF2.bit.CLKMODE = 1; // Enable XCLKOUT XintfRegs.XINTCNF2.bit.CLKOFF = 0;// 给所选用外设使能外设时钟// 如果不使用某外设模块,禁用它的时钟以省电// 下面代码要根据自己使用的外设模块进行相应的修改 SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC // *重要提醒* // ADC_cal()函数, 可以从TI保留的OTP中复制ADC校验值,并将校验值赋值给ADCREFSEL和ADCOFFTRIM寄存器,该过程在BOOT ROM中自动地完成 //如果在调试过程中,BOOT ROM代码旁路未使用,那么必须显示调用下面 ADC_cal()函数(推荐显示调用) //在调用 ADC_cal()前,必须使能ADC时钟 // 有关ADC更多的信息参见设备数据手册 ADC_cal();//本例中使能了所有片内外设模块时钟 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 SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the 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 SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the 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 SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0 SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1 SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2 SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock EDIS;}
5.本章小结
本章主要讲解了对SYSCLKOUT分频产生低频时钟信号和高频时钟信号,完成外设时钟初始化的过程。
TMS320F28335时钟(3)
本章对整个TMS320F28335时钟系统做个简要的总结,是对前面凌乱讲解的补充和梳理,希望借此总结可以更全面更彻底的掌握TMS320F28335时钟系统。
1.时钟源
外部时钟信号或者外部晶振震荡信号,具体参见《TMS320F28335时钟1》。
2.时钟产生过程
外部时钟或者外部晶振给F28335提供时钟源OSCCLK,使能F28335片上PLL电路,PLL电路对时钟源信号进行倍频,产生时钟CLKIN(具体操作过程和代码详见《TMS320F28335时钟1》),CLKIN通过CPU产生时钟SYSCLKOUT,SYSCLKOUT经过分频可以产生低速时钟LOSPCLK和高速时钟HISPCLK,最后OSCCLK、CLKIN、SYSCLKOUT、LOSPCLK和HISPCLK给各个模块提供时钟(具体操作过程和代码详见《TMS320F28335时钟2》)。
3.需要时钟信号的片上外设
看门狗电路WatchDog,CPU定时器(3个32位定时器),1个I2C,2个eCAN总线控制器,SCI(3个异步串行通信控制器),SPI(1个4线制同步串口),McBSP(2个多通道缓冲型同步串口),6个PWM单元,6个事件捕捉单元,2个QEP正交编码脉冲,12位ADC(16通道)等。
4.片上外设按输入时钟分组
(1)OSCCLK组:看门狗电路
(2)CLKIN组:CPU
(3)SYSOUTCLK组:I2C、eCAN总线、PWM、eCAP、eQEP、CPU定时器
(4)低速组(LOSPCLK):SCI,SPI,McBSP
(5)高速组(HISPCLK):ADC
5.其他时钟
TMS320F2833x提供了时钟输出引脚和外扩接口,因此还有产生了两种时钟,即XCLKOUT和XTIMCLK。默认情况下,XCLKOUT=XTIMCLK/2=SYSCLKOUT/4=OSCCLK/16。特别要注意的是所有的外部扩展访问都是以内部XINTF的时钟XTIMCLK为参考的,所有外部接口的访问都是在XCLKOUT的上升沿开始(具体操作过程和代码详见《TMS320F28335时钟2》)。
TI官方头文件DSP2833x_SysCtrl.h程序如下:
// TI File $Revision: /main/5 $// Checkin $Date: May 12, 2008 09:34:58 $//###########################################################################//// FILE: DSP2833x_SysCtrl.h//// TITLE: DSP2833x Device 系统控制寄存器.////###########################################################################// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $// $Release Date: August 4, 2009 $//############################################################################ifndef DSP2833x_SYS_CTRL_H#define DSP2833x_SYS_CTRL_H#ifdef __cplusplusextern "C" {#endif//---------------------------------------------------------------------------// 系统控制个人注册定义://// PLL 状态寄存器位定义struct PLLSTS_BITS { // bits 描述 Uint16 PLLLOCKS:1; // 0 PLL锁状态 Uint16 rsvd1:1; // 1 保留 Uint16 PLLOFF:1; // 2 PLL关闭 Uint16 MCLKSTS:1; // 3 丢失时钟信号状态 Uint16 MCLKCLR:1; // 4 丢失时钟清除位 Uint16 OSCOFF:1; // 5 振荡器时钟关闭位 Uint16 MCLKOFF:1; // 6 丢失时钟检测关闭位 Uint16 DIVSEL:2; // 7 时钟分频选择 Uint16 rsvd2:7; // 15:7 保留};// PLL状态寄存器union PLLSTS_REG { Uint16 all; struct PLLSTS_BITS bit; // PLL 状态寄存器位定义};// 高速外设时钟预分频寄存器位定义:struct HISPCP_BITS { // bits 描述 Uint16 HSPCLK:3; // 2:0 SYSCLKOUT分频配置 Uint16 rsvd1:13; // 15:3 保留};// 高速外设时钟预分频寄存器union HISPCP_REG { Uint16 all; struct HISPCP_BITS bit; // 高速外设时钟预分频寄存器位定义};// 低速外设时钟预分频寄存器位定义:struct LOSPCP_BITS { // bits 描述 Uint16 LSPCLK:3; // 2:0 SYSCLKOUT分频配置 Uint16 rsvd1:13; // 15:3 保留};// 低速外设时钟预分频寄存器union LOSPCP_REG { Uint16 all; struct LOSPCP_BITS bit; // 低速外设时钟预分频寄存器位定义};// 外设时钟控制寄存器0定义:struct PCLKCR0_BITS { // bits 描述 Uint16 rsvd1:2; // 1:0 保留 Uint16 TBCLKSYNC:1; // 2 EWPM模块时基时钟同步使能 Uint16 ADCENCLK:1; // 3 ADC时钟使能 Uint16 I2CAENCLK:1; // 4 I2C时钟使能 Uint16 SCICENCLK:1; // 5 SCI-C时钟使能 Uint16 rsvd2:2; // 7:6 保留 Uint16 SPIAENCLK:1; // 8 SPI-A时钟使能 Uint16 rsvd3:1; // 9 保留 Uint16 SCIAENCLK:1; // 10 SCI-A时钟使能 Uint16 SCIBENCLK:1; // 11 SCI-B时钟使能 Uint16 MCBSPAENCLK:1; // 12 McBSP-A时钟使能 Uint16 MCBSPBENCLK:1; // 13 McBSP-B时钟使能 Uint16 ECANAENCLK:1; // 14 eCAN-A时钟使能 Uint16 ECANBENCLK:1; // 15 eCAN-B时钟使能};// 外设时钟控制寄存器0union PCLKCR0_REG { Uint16 all; struct PCLKCR0_BITS bit; // 外设时钟控制寄存器0定义};// 外设时钟控制寄存器1定义:struct PCLKCR1_BITS { // bits 描述 Uint16 EPWM1ENCLK:1; // 0 EPWM1时钟使能 Uint16 EPWM2ENCLK:1; // 1 EPWM2时钟使能 Uint16 EPWM3ENCLK:1; // 2 EPWM3时钟使能 Uint16 EPWM4ENCLK:1; // 3 EPWM4时钟使能 Uint16 EPWM5ENCLK:1; // 4 EPWM5时钟使能 Uint16 EPWM6ENCLK:1; // 5 EPWM6时钟使能 Uint16 rsvd1:2; // 7:6 保留 Uint16 ECAP1ENCLK:1; // 8 ECAP1时钟使能 Uint16 ECAP2ENCLK:1; // 9 ECAP2时钟使能 Uint16 ECAP3ENCLK:1; // 10 ECAP3时钟使能 Uint16 ECAP4ENCLK:1; // 11 ECAP4时钟使能 Uint16 ECAP5ENCLK:1; // 12 ECAP5时钟使能 Uint16 ECAP6ENCLK:1; // 13 ECAP6时钟使能 Uint16 EQEP1ENCLK:1; // 14 EQEP1时钟使能 Uint16 EQEP2ENCLK:1; // 15 EQEP2时钟使能};// 外设时钟控制寄存器1union PCLKCR1_REG { Uint16 all; struct PCLKCR1_BITS bit; // 外设时钟控制寄存器1定义};// 外设时钟控制寄存器3定义:struct PCLKCR3_BITS { // bits 描述 Uint16 rsvd1:8; // 7:0 保留 Uint16 CPUTIMER0ENCLK:1; // 8 CPU-Timer 0时钟使能 Uint16 CPUTIMER1ENCLK:1; // 9 CPU-Timer 1时钟使能 Uint16 CPUTIMER2ENCLK:1; // 10 CPU-Timer 2时钟使能 Uint16 DMAENCLK:1; // 11 DMA时钟使能 Uint16 XINTFENCLK:1; // 12 XINTF时钟使能 Uint16 GPIOINENCLK:1; // 13 GPIO时钟使能 Uint16 rsvd2:2; // 15:14 保留};// 外设时钟控制寄存器3union PCLKCR3_REG { Uint16 all; struct PCLKCR3_BITS bit; // 外设时钟控制寄存器3定义:};// PLL 锁相环控制寄存器位定义:struct PLLCR_BITS { // bits 描述 Uint16 DIV:4; // 3:0 PLL时钟倍频数 Uint16 rsvd1:12; // 15:4 保留};// PLL 锁相环控制寄存器union PLLCR_REG { Uint16 all; struct PLLCR_BITS bit; // PLL 锁相环控制寄存器位定义};// 低功耗模式控制寄存器位定义:struct LPMCR0_BITS { // bits 描述 Uint16 LPM:2; // 1:0 低功耗模式设置 Uint16 QUALSTDBY:6; // 7:2 STANDBY唤醒 Uint16 rsvd1:7; // 14:8 保留 Uint16 WDINTE:1; // 15 看门狗中断使能};// 低功耗模式控制寄存器union LPMCR0_REG { Uint16 all; struct LPMCR0_BITS bit; // 低功耗模式控制寄存器位定义};// 映射地址寄存器位定义:struct MAPCNF_BITS { // bits 描述 Uint16 MAPEPWM:1; // 0 映射地址使能 Uint16 rsvd1:15; // 15:1 保留};// 映射地址寄存器union MAPCNF_REG { Uint16 all; struct MAPCNF_BITS bit; // 映射地址寄存器位定义};//---------------------------------------------------------------------------// 系统控制寄存器文件://struct SYS_CTRL_REGS { Uint16 rsvd1; // 0 保留 union PLLSTS_REG PLLSTS; // 1 PLL状态寄存器 Uint16 rsvd2[8]; // 2-9 保留 union HISPCP_REG HISPCP; // 10: 高速外设时钟预分频寄存器 union LOSPCP_REG LOSPCP; // 11: 低速外设时钟预分频寄存器 union PCLKCR0_REG PCLKCR0; // 12: 外设时钟控制寄存器0 union PCLKCR1_REG PCLKCR1; // 13: 外设时钟控制寄存器1 union LPMCR0_REG LPMCR0; // 14: 低功耗模式控制寄存器 Uint16 rsvd3; // 15: 保留 union PCLKCR3_REG PCLKCR3; // 16: 外设时钟控制寄存器3 union PLLCR_REG PLLCR; // 17: PLL 锁相环控制寄存器 // No bit definitions are defined for SCSR because // a read-modify-write instruction can clear the WDOVERRIDE bit Uint16 SCSR; // 18: 系统控制与状态寄存器 Uint16 WDCNTR; // 19: 看门狗计数器寄存器 Uint16 rsvd4; // 20 保留 Uint16 WDKEY; // 21: 看门狗复位寄存器 Uint16 rsvd5[3]; // 22-24 保留 // No bit definitions are defined for WDCR because // the proper value must be written to the WDCHK field // whenever writing to this register. Uint16 WDCR; // 25: 看门狗控制寄存器 Uint16 rsvd6[4]; // 26-29 保留 union MAPCNF_REG MAPCNF; // 30: 映射地址寄存器 Uint16 rsvd7[1]; // 31 保留};/* --------------------------------------------------- *//* CSM 寄存器 *//* *//* ----------------------------------------------------*//* CSM 状态与控制寄存器位定义 */struct CSMSCR_BITS { // bit 描述 Uint16 SECURE:1; // 0 仅读位映射安全状态 Uint16 rsvd1:14; // 14-1 保留 Uint16 FORCESEC:1; // 15 清除KEY寄存器并保护芯片};/* CSM 状态与控制寄存器*/union CSMSCR_REG { Uint16 all; struct CSMSCR_BITS bit; //CSM 状态与控制寄存器位定义};/* CSM 寄存器文件*/struct CSM_REGS { Uint16 KEY0; // KEY reg bits 15-0 Uint16 KEY1; // KEY reg bits 31-16 Uint16 KEY2; // KEY reg bits 47-32 Uint16 KEY3; // KEY reg bits 63-48 Uint16 KEY4; // KEY reg bits 79-64 Uint16 KEY5; // KEY reg bits 95-80 Uint16 KEY6; // KEY reg bits 111-96 Uint16 KEY7; // KEY reg bits 127-112 Uint16 rsvd1; // 保留 Uint16 rsvd2; // 保留 Uint16 rsvd3; // 保? Uint16 rsvd4; // 保留 Uint16 rsvd5; // 保留 Uint16 rsvd6; // 保留 Uint16 rsvd7; // 保留 union CSMSCR_REG CSMSCR; // CSM 状态与控制寄存器位定义};/* 密码位置 */struct CSM_PWL { Uint16 PSWD0; // PSWD bits 15-0 Uint16 PSWD1; // PSWD bits 31-16 Uint16 PSWD2; // PSWD bits 47-32 Uint16 PSWD3; // PSWD bits 63-48 Uint16 PSWD4; // PSWD bits 79-64 Uint16 PSWD5; // PSWD bits 95-80 Uint16 PSWD6; // PSWD bits 111-96 Uint16 PSWD7; // PSWD bits 127-112};/* Flash 寄存器 */#define FLASH_SLEEP 0x0000;#define FLASH_STANDBY 0x0001;#define FLASH_ACTIVE 0x0003;/* Flash 选择寄存器位定义*/struct FOPT_BITS { // bit 描述 Uint16 ENPIPE:1; // 0 使能流水线模式 Uint16 rsvd:15; // 1-15 保留};/* Flash 选择寄存器*/union FOPT_REG { Uint16 all; struct FOPT_BITS bit; //Flash 选择寄存器位定义};/* Flash 功耗模式寄存器位定义 */struct FPWR_BITS { // bit 描述 Uint16 PWR:2; // 0-1 功耗模式位 Uint16 rsvd:14; // 2-15 保留};/* Flash 功耗模式寄存器*/union FPWR_REG { Uint16 all; struct FPWR_BITS bit; //Flash 功耗模式寄存器位定义};/* Flash 状态寄存器位定义 */struct FSTATUS_BITS { // bit 描述 Uint16 PWRS:2; // 0-1 功耗模式状态位 Uint16 STDBYWAITS:1; // 2 flash从睡眠模式到备用态计数状态 Uint16 ACTIVEWAITS:1; // 3 flash从备用模式到激活态计数状态 Uint16 rsvd1:4; // 4-7 保留 Uint16 V3STAT:1; // 8 flash电压状态锁存位 Uint16 rsvd2:7; // 9-15 保留};/* Flash 状态寄存器*/union FSTATUS_REG { Uint16 all; struct FSTATUS_BITS bit; //Flash 状态寄存器位定义 };/* Flash 备用等待寄存器位定义 */struct FSTDBYWAIT_BITS { // bit 描述 Uint16 STDBYWAIT:9; // 0-8 flash有睡眠到备用态的计数位 Uint16 rsvd:7; // 9-15 保留};/* Flash 备用等待寄存器*/union FSTDBYWAIT_REG { Uint16 all; struct FSTDBYWAIT_BITS bit; //Flash 备用等待寄存器位定义};/* Flash 备用到激活态等待寄存器位定义 */struct FACTIVEWAIT_BITS { // bit 描述 Uint16 ACTIVEWAIT:9; // 0-8 flash备用到激活态等待计数 Uint16 rsvd:7; // 9-15 保留};/* Flash 备用到激活态等待寄存器 */union FACTIVEWAIT_REG { Uint16 all; struct FACTIVEWAIT_BITS bit; //Flash 备用到激活态等待寄存器位定义 };/* flash页访问等待寄存器位定义 */struct FBANKWAIT_BITS { // bit 描述 Uint16 RANDWAIT:4; // 0-3 Flash 随机访问等待周期数 Uint16 rsvd1:4; // 4-7 保留 Uint16 PAGEWAIT:4; // 8-11 Flash 页访问等待周期数 Uint16 rsvd2:4; // 12-15 保留};/* flash页访问等待寄存器*/union FBANKWAIT_REG { Uint16 all; struct FBANKWAIT_BITS bit; //flash页访问等待寄存器位定义};/* OTP 等待状态寄存器位定义 */struct FOTPWAIT_BITS { // bit 描述 Uint16 OTPWAIT:5; // 0-4 OTP读等待状态位 Uint16 rsvd:11; // 5-15 保留};/* OTP 等待状态寄存器*/union FOTPWAIT_REG { Uint16 all; struct FOTPWAIT_BITS bit; //OTP 等待状态寄存器位定义};//flash寄存器struct FLASH_REGS { union FOPT_REG FOPT; // Flash 选择寄存器 Uint16 rsvd1; // 保留 union FPWR_REG FPWR; // Flash 功耗模式寄存器 union FSTATUS_REG FSTATUS; // Flash 状态寄存器 union FSTDBYWAIT_REG FSTDBYWAIT; // Flash 备用等待寄存器 union FACTIVEWAIT_REG FACTIVEWAIT; // Flash 备用到激活态等待寄存器 union FBANKWAIT_REG FBANKWAIT; // flash页访问等待寄存器 union FOTPWAIT_REG FOTPWAIT; // OTP 等待状态寄存器};//---------------------------------------------------------------------------// 系统控制外部引用和函数声明://extern volatile struct SYS_CTRL_REGS SysCtrlRegs;extern volatile struct CSM_REGS CsmRegs;extern volatile struct CSM_PWL CsmPwl;extern volatile struct FLASH_REGS FlashRegs;#ifdef __cplusplus}#endif /* extern "C" */#endif // end of DSP2833x_SYS_CTRL_H definition//===========================================================================// End of file.//===========================================================================
官网例程文件DSP2833x_SysCtrl.c程序如下:
// TI File $Revision: /main/8 $// Checkin $Date: April 15, 2009 09:54:05 $//###########################################################################//// FILE: DSP2833x_SysCtrl.c//// TITLE: DSP2833x Device S系统控制初始化和支持功能.//// DESCRIPTION://// 系统资源初始化的示例.////###########################################################################// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $// $Release Date: August 4, 2009 $//############################################################################include "DSP2833x_Device.h" // Headerfile Include File#include "DSP2833x_Examples.h" // Examples Include File//函数将从RAM运行需要分配给一个不同的部分。本节将被映射到一个使用链接器cmd文件加载并运行地址。#pragma CODE_SECTION(InitFlash, "ramfuncs");//---------------------------------------------------------------------------// InitSysCtrl://---------------------------------------------------------------------------// 该函数初始化系统控制寄存器到一个已知状态.// - 禁用看门狗// - 设置 PLLCR寄存器及适当的 SYSCLKOUT 频率// - 设置高/低外设时钟预分频寄存器// - 使能相应的外设时钟控制寄存器void InitSysCtrl(void) //初始化系统控制{ DisableDog(); //关闭看门狗 InitPll(DSP28_PLLCR,DSP28_DIVSEL); //初始化PLL控制 InitPeripheralClocks(); //初始化外设时钟}//---------------------------------------------------------------------------// 例子: InitFlash://---------------------------------------------------------------------------// 改函数初始化flash控制寄存器// 警告// This function MUST be executed out of RAM. Executing it// out of OTP/Flash will yield unpredictable resultsvoid InitFlash(void) //初始化flash{ EALLOW; FlashRegs.FOPT.bit.ENPIPE = 1; //使能flash流水线模式 // 警告 //Minimum waitstates required for the flash operating //at a given CPU rate must be characterized by TI. //Refer to the datasheet for the latest information.#if CPU_FRQ_150MHZ FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5; //Flash 页访问等待周期数 FlashRegs.FBANKWAIT.bit.RANDWAIT = 5; //Flash 随机访问等待周期数 FlashRegs.FOTPWAIT.bit.OTPWAIT = 8; //OTP读等待状态位#endif#if CPU_FRQ_100MHZ FlashRegs.FBANKWAIT.bit.PAGEWAIT = 3; //Flash 页访问等待周期数 FlashRegs.FBANKWAIT.bit.RANDWAIT = 3; //Flash 随机访问等待周期数 FlashRegs.FOTPWAIT.bit.OTPWAIT = 5; //OTP读等待状态位#endif // 警告 //这两个寄存器应该使用默认值 FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF; //flash有睡眠到备用态的计数位 FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF; //flash备用到激活态等待计数 EDIS; //Force a pipeline flush to ensure that the write to //the last register configured occurs before returning. asm(" RPT #7 || NOP");}//---------------------------------------------------------------------------// 例子: ServiceDog://---------------------------------------------------------------------------// 这个函数重置看门狗定时器.// 在应用程序中使用这个函数启用这个功能void ServiceDog(void){ EALLOW; SysCtrlRegs.WDKEY = 0x0055; //清零看门狗 SysCtrlRegs.WDKEY = 0x00AA; EDIS;}//---------------------------------------------------------------------------// Example: DisableDog://---------------------------------------------------------------------------// 这个函数禁止看门狗定时器.void DisableDog(void){ EALLOW; SysCtrlRegs.WDCR= 0x006F; //WDDIS=1禁止看门狗模块 EDIS;}//---------------------------------------------------------------------------// Example: EnableDog: //---------------------------------------------------------------------------// 这个函数使能看门狗定时器. void EnableDog(void){ EALLOW; SysCtrlRegs.WDCR= 0x00aF; //使能看门狗 EDIS;}//---------------------------------------------------------------------------// Example: InitPll: //---------------------------------------------------------------------------/* * 函数名称:InitPll * 函数输入:倍频参数val,分频参数divsel * val取值为0到10,表示倍频数;divsel取值0到4,0和1表示4分频,2表示2分频,3表示不分频 * 函数输出:无 * 函数调用:InitPll(10,2); * 先将外部时钟倍频10倍,在分频1/2,最后产生的时钟CLKIN输入CPU28x */void InitPll(Uint16 val, Uint16 divsel){ // 确保PLL不是工作在limp mode下,即有外部时钟进入PLL if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0) { //检测到无外部时钟,软件要采集恰当的措施保证系统不出现事故,该措施包括 //使系统停机、复位等 //用适合的函数替换下面一行 // SystemShutdown(); function. asm(" ESTOP0"); } // PLLCR从0x0000改变前,PLLSTS[DIVSEL]必须为0 // 外部RST复位信号会使PLLSTS[DIVSEL]复位 // 此时分频为1/4 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 0; EDIS; } // 前面条件都满足后,可以改变PLLCR[DIV] if (SysCtrlRegs.PLLCR.bit.DIV != val) { EALLOW; // 在设置PLLCR[DIV]前,要禁用主振荡器检测逻辑 SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1; SysCtrlRegs.PLLCR.bit.DIV = val; //设置倍频 EDIS; //等待锁相环进入在锁状态。 //在此期间CPU将切换到OSCCLK / 2。 //直到锁相环稳定。 //一旦锁相环稳定CPU切换到新的倍频值。 //这个锁定时间由锁相环计数器监视。 //等待这个切换完成。 //取消对看门狗的禁用 DisableDog(); while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)//已稳定 { // Uncomment to service the watchdog // ServiceDog(); } EALLOW; SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;//开启主振荡器检测逻辑 EDIS; } //如果需要分频1/2 if((divsel == 1)||(divsel == 2)) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel; //设置分频 EDIS; } //注意:下面代码只有在PLL是旁路或者关闭模式时,才可被执行,其他模式禁止。 //倍频时一定要分频,不倍频时才允许不分频 //如果需要切换分频到1/1 // * 首先从默认1/4分频切换到1/2分频,让电源稳定 // 稳定所需要的时间依赖于系统运行速度,此处延时50us只是作为一个特例 // * 稳定后,再切换到1/1 if(divsel == 3) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 2; DELAY_US(50L); SysCtrlRegs.PLLSTS.bit.DIVSEL = 3; EDIS; }}//--------------------------------------------------------------------------// 实例: InitPeripheralClocks://---------------------------------------------------------------------------// 改函数初始化时钟的外围模块.// 首先设置高/低外设时钟预分频寄存器// 第二个是启用外围时钟.// 降低功耗,将未使用的外设时钟禁止//// 注释: 如果一个外设的时钟不启用则你不能读写这个外围的寄存器void InitPeripheralClocks(void){ EALLOW; // HISPCP / LOSPCP预分频寄存器设置,通常它会被设置为默认值 SysCtrlRegs.HISPCP.all = 0x0001; // 75MHZ SysCtrlRegs.LOSPCP.all = 0x0001; // 75Mhz // 时钟输出引脚XCLKOUT设置,默认情况XCLKOUT = SYSCLKOUT/4 // xintf外部接口时钟 // XTIMCLK = SYSCLKOUT/2 XintfRegs.XINTCNF2.bit.XTIMCLK = 1; // XCLKOUT = XTIMCLK/2 XintfRegs.XINTCNF2.bit.CLKMODE = 1; // Enable XCLKOUT XintfRegs.XINTCNF2.bit.CLKOFF = 0; // 给所选用外设使能外设时钟 // 如果不使用某外设模块,禁用它的时钟以省电 // 下面代码要根据自己使用的外设模块进行相应的修改 SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; //ADC时钟使能 // *重要提醒* // ADC_cal()函数, 可以从TI保留的OTP中复制ADC校验值,并将校验值赋值给ADCREFSEL和ADCOFFTRIM寄存器,该过程在BOOT ROM中自动地完成 //如果在调试过程中,BOOT ROM代码旁路未使用,那么必须显示调用下面 ADC_cal()函数(推荐显示调用) //在调用 ADC_cal()前,必须使能ADC时钟 //有关ADC更多的信息参见设备数据手册 ADC_cal(); SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0; // I2C SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A 使能 SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 0; // SCI-B SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 0; // SCI-C SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A 使能 SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 0; // McBSP-A SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 0; // McBSP-B SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1; // eCAN-A 使能 SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 0; // eCAN-B 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 使能 SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // TBCLK时基时钟 ePWM 使能 SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 0; // eCAP3 SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 0; // eCAP4 SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 0; // eCAP5 SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 0; // eCAP6 SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 0; // eCAP1 SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 0; // eCAP2 SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 0; // eQEP1 SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 0; // eQEP2 SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0 使能 SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1 使能 SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2 使能 SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 0; // DMA Clock SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK 外扩接口时钟使能 SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO 输入时钟使能 EDIS;}//===========================================================================// End of file.//===========================================================================
参考资料
TMS320F28335时钟(1)
TMS320F28335时钟(2)
TMS320F28335时钟(3)
28335硬件教程-时钟系统
- TMS320F28335之系统时钟
- TMS320F28335之默认中断系统
- TMS320F28335项目开发记录7_28335之时钟
- TMS320F28335的时钟介绍
- TMS320F28335的时钟介绍
- TMS320F28335 时钟分析2
- TMS320F28335 时钟分析3
- TMS320F28335 时钟分析3
- TMS320F28335时钟(3) -----总结
- TMS320F28335项目开发记录9_28335之中断系统
- TMS320F28335之GPIO原理
- TMS320F28335之定时器
- TMS320F28335之外部接口
- OAL之系统时钟
- OAL之系统时钟
- STM32之系统时钟
- S3C6410之系统时钟
- STM32之系统时钟
- 『MySQL』索引类型 normal, unique, full text
- linux/shell每日学习笔记
- Fragment用法详细说明
- 学习java多线程的线程池
- Activity生命周期
- TMS320F28335之系统时钟
- 手把手教你做三级联动
- IOS设备兼容Ipv5/ipv6访问Ipv4服务器
- 软件架构
- 手把手教你做三级联动
- 维护篇(5.2)-07. 调整DHCP租约时间 ❀ 飞塔 (Fortinet) 防火墙
- Hint 强制使用索引有时失灵?
- CUDA 7.5 不支持GCC4.7及以上的版本
- Android Activity生命周期(二)