关于28335分频倍频程序问题
这是ti官网的一个例子片段void InitPll(Uint16 val, Uint16 divsel)
{
// Make sure the PLL is not running in limp mode
if (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/4
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
EDIS;
}
// Change the PLLCR
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{
EALLOW;
// Before setting PLLCR turn off missing clock detect logic
SysCtrlRegs.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 watchdog
DisableDog();
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
{
// Uncomment to service the watchdog
// ServiceDog();
}
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
EDIS;
}
// If switching to 1/2
if((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/1
if(divsel == 3)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
DELAY_US(50L);
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
EDIS;
}
}
从程序来看分频倍频由val divsel这两个变量决定,我在外部用30MHZ晶振,应选取10倍频,2分频,那这两个值需要在头文件分别定义为10和2,但是官方程序的头文件2833x_example.这样写的//#define DSP28_DIVSEL 0 // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL 1 // Disable /4 for SYSCKOUT
#define DSP28_DIVSEL 2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL 3 // Enable /1 for SYSCLKOUT
#define DSP28_PLLCR 10
//#define DSP28_PLLCR 9
//#define DSP28_PLLCR 8
//#define DSP28_PLLCR 7
//#define DSP28_PLLCR 6
//#define DSP28_PLLCR 5
//#define DSP28_PLLCR 4
//#define DSP28_PLLCR 3
//#define DSP28_PLLCR 2
//#define DSP28_PLLCR 1
//#define DSP28_PLLCR 0/
意思是让我们从中各选择一个,其它的宏定义删掉,但是程序中是val divsel这两个值对寄存器赋值,而不是DSP28_DIVSEL 和DSP28_PLLCR,我是否应该改成/#define divsel 2和#define val 10? 直接这么写就可以啦 不知道为什么搞那么麻烦
// Initalize PLL
SysCtrlRegs.PLLCR = 0x01;
// Wait for PLL to lock
for(i= 0; i< 5000; i++){}
// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
SysCtrlRegs.HISPCP.all = 0x0001;
SysCtrlRegs.LOSPCP.all = 0x0002; 对不起,可能是我表述有问题,我想用内置振荡器,30MHZ晶振是接在X1和X2之间的,究竟是对val divsel这两个值定义还是DSP28_DIVSEL 和DSP28_PLLCR定义? 本帖最后由 airwill 于 2014-5-5 14:59 编辑
意思是让我们从中各选择一个,其它的宏定义删掉, 这里完全正确.
但是程序中是val divsel这两个值对寄存器赋值,而不是DSP28_DIVSEL 和DSP28_PLLCR,我是否应该改成/#define divsel 2和#define val 10?
还是用 DSP28_DIVSEL 和DSP28_PLLCR,找找 InitPll(Uint16 val, Uint16 divsel) 是在哪里调用的,就知道了
DSP28_DIVSEL 和DSP28_PLLCR 作为变量传递给了 InitPll()了
知道了,谢谢。 看来是我太粗心了,没看到,从上文中找到了感谢大家无私帮助。
void InitSysCtrl(void)
{
// Disable the watchdog
DisableDog();
// Initialize the PLL control: PLLCR and DIVSEL
// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h
InitPll(DSP28_PLLCR,DSP28_DIVSEL);
// Initialize the peripheral clocks
InitPeripheralClocks();
}
这种宏定义方式会把所有可能的配置情况都定义出来,好处就是如果程序的配置发生更改,只需要调整宏的使用就可以了,程序配置改起来很方便,因为所有可能的配置计算都已经在前面就设计好了。
只要修改H文件中的宏定义使用,而且不用修改C文件里的函数。
在较大规模的软件设计中,这种方式是首选的。
想想几个人开发一个软件,你修改或调试别人的程序,要重新看手册、计算参数,找函数 感觉TI公司给的初始化代码很繁琐,有简单的吗?
页:
[1]