从TI代码中学习编程规范!!!
其实了解弄懂系统时钟系统还是相当重要的,下面简单总结一下应用的要点。
1.首先明确两个问题,要让一个系统工作,必须具备两个重要条件,一是向这个系统供电,一般采用开关电源模块。另一个是作为整个系统运行的心脏CPU,让它跑起来还需不断地给它提供有规律的时钟脉冲。
今天的主题是深度总结一下时钟这部分:
从两个角度结合来思考:
1,从硬件方面来看,我们一般通过外部晶振作30MHz为分析的起点,外部晶振通过与片内的振荡器OSC和基于锁相环PLL倍频逻辑的时钟模块来为CPU提供时钟脉冲CLKIIN。
目前DSP集成的片上锁相环PLL模块,主要作用是通过软件实时地配置片上外设时钟,提高系统的灵活性和可靠性。(这种设计的好处我们暂时不讨论!!!)
TI例程--在系统初始化函数的主函数中调用PLL函数,InitPll(0xA);赋值计算,传入参数10就是10倍频啦。
void InitPll(Uint16 val)
{
volatile Uint16 iVol;
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{
EALLOW;
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
DisableDog();
for(iVol= 0; iVol< ( (131072/2)/12 ); iVol++)
{
}
}
这样经过计算,经过软件处理倍频后的时钟,送入DSP中的CPU的时钟信号--SYSCLKOUT系统时钟就是取的最大时钟150MHz!!!,接着再分发给各个外设。但是外设又分为高速外设时钟与低速外设时钟,请特别注意这两个概念只是相对的。它们分别对应两个寄存器:高速外设时钟预定标寄存器HISPCP(取值范围是0~7)以及低速外调时钟预定标寄存器。在实际中这两位我们是需要通过软件设置的!可以参考下面一段代码加以理解,需要用到的外设我们需要使能其操作,不需要用到的可以不设置!需要在外设时钟控制寄存器PCLKCR中进行相应的设置,具体可参考下面这段设置代码。这段代码也可以包含在系统初始化程序当中!!!
void InitPeripheralClocks(void)
{
EALLOW;
// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
SysCtrlRegs.HISPCP.all = 0x0001; 70MHZ
SysCtrlRegs.LOSPCP.all = 0x0002; 37.5MHz
// Peripheral clock enables set for the selected peripherals.
SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=1;
SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1;
SysCtrlRegs.PCLKCR.bit.SCIBENCLK=1;
SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=1;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;
SysCtrlRegs.PCLKCR.bit.ECANENCLK=1;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=1;
EDIS;
}这段代码已形成模块化了,实际中我们要修改高速预定标寄存器还是低速的,都可在初始化程序只外加一条语句进行操作
如下: InitSysCtrl();
// HISPCP prescale register settings, normally it will be set to default values
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.HISPCP.all = 0x0000; // SYSCLKOUT/1
这一句设定了高速时钟HSPCLK=150MHz!!!
EDIS; // This is needed to disable write to EALLOW protected registers
接下来就到具体的外设了,我们要设置的话,一般单独分模块设置啦!这点很重要,是编程的规范!!!
接下来讨论为EV模块中的通用定时器TI设定计数时钟,主要设置是在定时器控制寄存器TxCON中的TPS2~TPS0:输入时钟预定标和TCLKS1~TCLKS0时钟源的来源,此处我们选择的是来源于00,内部时钟(例如HSPCLK);01外部时钟(例如TCLKIN);10,保留;11,QEP电路(这个我们在做速度测量QEP电路时可能会用到),这两部分设置好啦的话,则定时器的时钟也就确定啦!接着还有一个问题就是计数模式的选择,提供了四种计数模式可以在TxCON寄存器中的TMODE1~TMODE0这两位进行设置选择!!!
以上设置好了之后,则相应的TIPR周期寄存器的值也就可以计算出来了!T1PR=7500!!!
接下来可以设置死区寄存器设定一个死区时间DBTCONx【8~11】位设定死区周期值m,DBTCON[2~4]位的死区定时器预定标因子x/p,定时器时钟周期为t,,则死区时间tBD=m*p*t.
#define DBTCON_INIT_STATE ( DBT_VAL_15 + \ 改变这一位,对应的就是15
EDBT3_EN + \
EDBT2_EN + \
EDBT1_EN + \这三位不变改的时候!这也是一种操作技巧!
DBTPS_X1 ) 预定标P=32,改变这一位啦
这样通过计数我所设置的死区时间是3.2微秒!
总结:总而言之,我们要从最初的晶振源获得我们需要的时钟周期,我们只需要配置一系列相关的寄存器中的时钟预定标因子所在的那些位就可算出我们想要的时钟周期。