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初始化的代码如下(来自官方例程,主要对其注释分析和讲解)。
void InitPll(unsigned short div, unsigned short divsel)
{
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
{
asm(" ESTOP0");
}
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
EDIS;
}
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
SysCtrlRegs.PLLCR.bit.DIV = div;
EDIS;
DisableDog();
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
{
}
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
EDIS;
}
if((divsel == 1)||(divsel == 2))
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
EDIS;
}
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官方例程,注释是个人理解。
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
// XCLKOUT = XTIMCLK/2
XintfRegs.XINTCNF2.bit.CLKMODE = 1
// Enable XCLKOUT
XintfRegs.XINTCNF2.bit.CLKOFF = 0
// 给所选用外设使能外设时钟
// 如果不使用某外设模块,禁用它的时钟以省电
// 下面代码要根据自己使用的外设模块进行相应的修改
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1
// *重要提醒*
// ADC_cal()函数, 可以从TI保留的OTP中复制ADC校验值,并将校验值赋值给ADCREFSEL和ADCOFFTRIM寄存器,该过程在BOOT ROM中自动地完成
//如果在调试过程中,BOOT ROM代码旁路未使用,那么必须显示调用下面 ADC_cal()函数(推荐显示调用)
//在调用 ADC_cal()前,必须使能ADC时钟
// 有关ADC更多的信息参见设备数据手册
ADC_cal()
//本例中使能了所有片内外设模块时钟
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1
SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1
SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1
SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1
SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1
SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1
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程序如下:
#ifndef DSP2833x_SYS_CTRL_H
#define DSP2833x_SYS_CTRL_H
#ifdef __cplusplus
extern "C" {
#endif
struct PLLSTS_BITS {
Uint16 PLLLOCKS:1;
Uint16 rsvd1:1;
Uint16 PLLOFF:1;
Uint16 MCLKSTS:1;
Uint16 MCLKCLR:1;
Uint16 OSCOFF:1;
Uint16 MCLKOFF:1;
Uint16 DIVSEL:2;
Uint16 rsvd2:7;
};
union PLLSTS_REG {
Uint16 all;
struct PLLSTS_BITS bit;
};
struct HISPCP_BITS {
Uint16 HSPCLK:3;
Uint16 rsvd1:13;
};
union HISPCP_REG {
Uint16 all;
struct HISPCP_BITS bit;
};
struct LOSPCP_BITS {
Uint16 LSPCLK:3;
Uint16 rsvd1:13;
};
union LOSPCP_REG {
Uint16 all;
struct LOSPCP_BITS bit;
};
struct PCLKCR0_BITS {
Uint16 rsvd1:2;
Uint16 TBCLKSYNC:1;
Uint16 ADCENCLK:1;
Uint16 I2CAENCLK:1;
Uint16 SCICENCLK:1;
Uint16 rsvd2:2;
Uint16 SPIAENCLK:1;
Uint16 rsvd3:1;
Uint16 SCIAENCLK:1;
Uint16 SCIBENCLK:1;
Uint16 MCBSPAENCLK:1;
Uint16 MCBSPBENCLK:1;
Uint16 ECANAENCLK:1;
Uint16 ECANBENCLK:1;
};
union PCLKCR0_REG {
Uint16 all;
struct PCLKCR0_BITS bit;
};
struct PCLKCR1_BITS {
Uint16 EPWM1ENCLK:1;
Uint16 EPWM2ENCLK:1;
Uint16 EPWM3ENCLK:1;
Uint16 EPWM4ENCLK:1;
Uint16 EPWM5ENCLK:1;
Uint16 EPWM6ENCLK:1;
Uint16 rsvd1:2;
Uint16 ECAP1ENCLK:1;
Uint16 ECAP2ENCLK:1;
Uint16 ECAP3ENCLK:1;
Uint16 ECAP4ENCLK:1;
Uint16 ECAP5ENCLK:1;
Uint16 ECAP6ENCLK:1;
Uint16 EQEP1ENCLK:1;
Uint16 EQEP2ENCLK:1;
};
union PCLKCR1_REG {
Uint16 all;
struct PCLKCR1_BITS bit;
};
struct PCLKCR3_BITS {
Uint16 rsvd1:8;
Uint16 CPUTIMER0ENCLK:1;
Uint16 CPUTIMER1ENCLK:1;
Uint16 CPUTIMER2ENCLK:1;
Uint16 DMAENCLK:1;
Uint16 XINTFENCLK:1;
Uint16 GPIOINENCLK:1;
Uint16 rsvd2:2;
};
union PCLKCR3_REG {
Uint16 all;
struct PCLKCR3_BITS bit;
};
struct PLLCR_BITS {
Uint16 DIV:4;
Uint16 rsvd1:12;
};
union PLLCR_REG {
Uint16 all;
struct PLLCR_BITS bit;
};
struct LPMCR0_BITS {
Uint16 LPM:2;
Uint16 QUALSTDBY:6;
Uint16 rsvd1:7;
Uint16 WDINTE:1;
};
union LPMCR0_REG {
Uint16 all;
struct LPMCR0_BITS bit;
};
struct MAPCNF_BITS {
Uint16 MAPEPWM:1;
Uint16 rsvd1:15;
};
union MAPCNF_REG {
Uint16 all;
struct MAPCNF_BITS bit;
};
struct SYS_CTRL_REGS {
Uint16 rsvd1;
union PLLSTS_REG PLLSTS;
Uint16 rsvd2[8];
union HISPCP_REG HISPCP;
union LOSPCP_REG LOSPCP;
union PCLKCR0_REG PCLKCR0;
union PCLKCR1_REG PCLKCR1;
union LPMCR0_REG LPMCR0;
Uint16 rsvd3;
union PCLKCR3_REG PCLKCR3;
union PLLCR_REG PLLCR;
Uint16 SCSR;
Uint16 WDCNTR;
Uint16 rsvd4;
Uint16 WDKEY;
Uint16 rsvd5[3];
Uint16 WDCR;
Uint16 rsvd6[4];
union MAPCNF_REG MAPCNF;
Uint16 rsvd7[1];
};
struct CSMSCR_BITS {
Uint16 SECURE:1;
Uint16 rsvd1:14;
Uint16 FORCESEC:1;
};
union CSMSCR_REG {
Uint16 all;
struct CSMSCR_BITS bit;
};
struct CSM_REGS {
Uint16 KEY0;
Uint16 KEY1;
Uint16 KEY2;
Uint16 KEY3;
Uint16 KEY4;
Uint16 KEY5;
Uint16 KEY6;
Uint16 KEY7;
Uint16 rsvd1;
Uint16 rsvd2;
Uint16 rsvd3;
Uint16 rsvd4;
Uint16 rsvd5;
Uint16 rsvd6;
Uint16 rsvd7;
union CSMSCR_REG CSMSCR;
};
struct CSM_PWL {
Uint16 PSWD0;
Uint16 PSWD1;
Uint16 PSWD2;
Uint16 PSWD3;
Uint16 PSWD4;
Uint16 PSWD5;
Uint16 PSWD6;
Uint16 PSWD7;
};
#define FLASH_SLEEP 0x0000;
#define FLASH_STANDBY 0x0001;
#define FLASH_ACTIVE 0x0003;
struct FOPT_BITS {
Uint16 ENPIPE:1;
Uint16 rsvd:15;
};
union FOPT_REG {
Uint16 all;
struct FOPT_BITS bit;
};
struct FPWR_BITS {
Uint16 PWR:2;
Uint16 rsvd:14;
};
union FPWR_REG {
Uint16 all;
struct FPWR_BITS bit;
};
struct FSTATUS_BITS {
Uint16 PWRS:2;
Uint16 STDBYWAITS:1;
Uint16 ACTIVEWAITS:1;
Uint16 rsvd1:4;
Uint16 V3STAT:1;
Uint16 rsvd2:7;
};
union FSTATUS_REG {
Uint16 all;
struct FSTATUS_BITS bit;
};
struct FSTDBYWAIT_BITS {
Uint16 STDBYWAIT:9;
Uint16 rsvd:7;
};
union FSTDBYWAIT_REG {
Uint16 all;
struct FSTDBYWAIT_BITS bit;
};
struct FACTIVEWAIT_BITS {
Uint16 ACTIVEWAIT:9;
Uint16 rsvd:7;
};
union FACTIVEWAIT_REG {
Uint16 all;
struct FACTIVEWAIT_BITS bit;
};
struct FBANKWAIT_BITS {
Uint16 RANDWAIT:4;
Uint16 rsvd1:4;
Uint16 PAGEWAIT:4;
Uint16 rsvd2:4;
};
union FBANKWAIT_REG {
Uint16 all;
struct FBANKWAIT_BITS bit;
};
struct FOTPWAIT_BITS {
Uint16 OTPWAIT:5;
Uint16 rsvd:11;
};
union FOTPWAIT_REG {
Uint16 all;
struct FOTPWAIT_BITS bit;
};
struct FLASH_REGS {
union FOPT_REG FOPT;
Uint16 rsvd1;
union FPWR_REG FPWR;
union FSTATUS_REG FSTATUS;
union FSTDBYWAIT_REG FSTDBYWAIT;
union FACTIVEWAIT_REG FACTIVEWAIT;
union FBANKWAIT_REG FBANKWAIT;
union FOTPWAIT_REG FOTPWAIT;
};
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
官网例程文件DSP2833x_SysCtrl.c程序如下:
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#pragma CODE_SECTION(InitFlash, "ramfuncs");
void InitSysCtrl(void)
{
DisableDog();
InitPll(DSP28_PLLCR,DSP28_DIVSEL);
InitPeripheralClocks();
}
void InitFlash(void)
{
EALLOW;
FlashRegs.FOPT.bit.ENPIPE = 1;
#if CPU_FRQ_150MHZ
FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;
FlashRegs.FBANKWAIT.bit.RANDWAIT = 5;
FlashRegs.FOTPWAIT.bit.OTPWAIT = 8;
#endif
#if CPU_FRQ_100MHZ
FlashRegs.FBANKWAIT.bit.PAGEWAIT = 3;
FlashRegs.FBANKWAIT.bit.RANDWAIT = 3;
FlashRegs.FOTPWAIT.bit.OTPWAIT = 5;
#endif
FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
EDIS;
asm(" RPT #7 || NOP");
}
void ServiceDog(void)
{
EALLOW;
SysCtrlRegs.WDKEY = 0x0055;
SysCtrlRegs.WDKEY = 0x00AA;
EDIS;
}
void DisableDog(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x006F;
EDIS;
}
void EnableDog(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x00aF;
EDIS;
}
void InitPll(Uint16 val, Uint16 divsel)
{