发 帖  
原厂入驻New

[经验] DSP学习之路,DSP从入门到精通全集下载

2020-9-4 10:58:42  158 DSP
分享
2
开始学习DSP,中间各种烦事,学习了有半个月的时间,然后就被各种杂事中断了,暑假开始,继续DSP之旅。

在日志里面记录了,通过CCS6如何创建工程,别笑,那时候,创建一个新工程我用了两天,跟着一些书籍进行配置,最后竟然还是会出错,然后就借助网上的大神的帖子,顺利创建新工程,刚又看了下写那篇日志的时间,是4/5,这之间我都做了些什么那??????一直心心念着学习DSP,现在发现自己脑袋里空空如也,没有为之付出很多时间、精力,外在原因有,重要的是自己内在的原因,有时候,一件事情,你可以坚持一天、一周,一个月,但是,慢慢地你的热度就会下降,最后完全抛到脑后,说的就是我自己。有些事情不是一蹴而就的,需要一步一个脚印向前走,目标一点点地靠近自己,最终目标会如期而至,不用着急,慢慢来,每天进步一点点。
开篇
时钟在一个系统中的作用真可谓是心脏之于人,重要性不必说,一个系统若是时钟就不稳定,那这个系统几乎谈不上可靠,故还是从时钟系统学起。
111455vdnbnj5j7xf5jmmq.png.thumb.png
dsp的时钟源可以来自外部无源晶振,还可以通过有源晶振产生时钟信号作为输入。一般用30M有源晶振作为外部时钟源,一般是30M的时钟通过PLL10倍频到300M,然后再2分频产生150M的系统时钟
这个PLL配置过程参考官方手册,以及官方给出了时钟配置的程序,直接进行调用就行。
112033o83ptrppr1r7ytp1.png.thumb.png
例程就是参考这个步骤来写的,有一点不是太明白的是,最后倍频结束后,分频的时候,当分频为1时,要先进行2分频,然后再进行不分频????
官方例程如下:
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)                                          //分频部分先设定为4分频,在PLLCR改变之前,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;                                                                 //改变PLL倍频系数时,要把丢失时钟检测关闭
        SysCtrlRegs.PLLCR.bit.DIV = val;
        EDIS;

        //
        // Optional: Wait for PLL to lock.                                                                        //在对时钟分频时,要保证PLL已经入锁
        // During this time the CPU will switch to OSCCLK/2 until                                      //pLL稳定之前,内核时钟为OSCCLK/2 =15M
        // the PLL is stable.  Once the PLL is stable the CPU will
        // switch to the new PLL value.                                                                         //PLL一旦稳定下来,内核时钟转变为新的值
        //
        // This time-to-lock is monitored by a PLL lock counter.
        //
        // Code is not required to sit and wait for the PLL to lock.                                    //代码不需要等待PLL入锁,但是,如何代码在做一些关键的事情时,需要正确的时钟
        // 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)            //等待PLL入锁
        {
            //
            // 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;
    }

    //
    // NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
    // 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)                                          //??????????????????????不明白为什么要这样来,不是直接赋成3就行了,,求解,我看网上有说是为了防止两个
    {                                                            //分频器同时分频出现错误,可是这样先分成2分频,再分成1分频就行了??????不是太懂,还望大神指点
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
        DELAY_US(50L);
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
        EDIS;
    }
}

红色部分是我的一些理解。

通过以上的配置,就可以得到一个稳定可靠的系统时钟了。为了保证这个时钟时时刻刻稳定可靠,就要对他进行时时刻刻地监控
113200druen7o43uv9dlln.png.thumb.png
正常情况下,OSCCLOCK counter(7位)对OSCCLOCK进行计数,VCOCLOCK counter(13位)对VCOCLOCK进行计数,当OSCCLOCK counter计数器溢出时,自动对VCOCLOCK counter清零,正常时,OSCCLOCK counter计数器不会溢出
非正常时(OSCCLOCK时钟丢失时)PLL会进入limp - mode模式并会有一个低频时钟产生,VCOCLOCK counter计数器对该低频时钟进行计数,溢出时将产生一个复位信号对CPU、外设等复位,并将PLLSTS[MCLKCLR]位置1,当检测到PLLSTS[MCLKCLR]位为1时,表明系统时钟工作在limp mode模式下。需要检查硬件是否有问题,通过向PLLSTS[MCLKCLR]写1,对该位清零,并时钟电路复位,再次上电观察PLLSTS[MCLKCLR]位,重复该过程,直到正常。

考虑到一些外设有可能会需要时钟,DSP专门引出了一个时钟XCLCKOUT为其所用
161158q3zs07gztlsxn0tm.png.thumb.png
默认情况下,是将XCLKOUT设置为系统时钟的四分频37.5M,也可以自己设置,最大不超过系统时钟SYSCLKOUT。

这之上的配置过后就可以得到保证系统时时刻刻稳定的时钟了!TI公司又将这个系统时钟分为低速时钟和高速时钟,分别分给不同的外设,之前学习过TI得msp430,这和430里面的架构感觉完全一致,这样可以降低功耗。
145245e2ozzbgooakffgf7.png.thumb.png
为不同的外设提供相应的时钟,低速的外设给你高速的时钟也只能是浪费,并且还有可能速度太快,你跟不上;高速外设提供低速时钟,只能拖后腿,故合适才是最重要的。中庸之道
当有些外设不用的时候,可以将其关闭,以降低功耗,InitSysCtrl()函数中,InitPeripheralClocks()该函数对外设时钟进行初始化,即将一些不必要的外设时钟关闭,以降低功耗。
DSP从入门到精通全集.rar (3.95 MB, 下载次数: 21)

yg_311 2020-9-4 13:43:18
好资料,谢谢分享
回复

举报

全英文版的啊,有没有中文版本啊
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
关闭

站长推荐 上一条 /9 下一条

快速回复 返回顶部 返回列表