近日工作中又涉及到了DSP28335的应用,看来TI的芯片还是得到了公司领导的认可,也直接丢了一份DSP28335的FOC程序给我理解。以前读书阶段较为简单的接触过一段时间,对DSP28335的基础功能部分有了一些浅显了解,现在工作中要实际开始用了,开始发现之前学习的程度还是不够,因此要更加深入的探究一遍。可能非常基础,希望大家也不要见笑,人真是年龄越大忘东西越快。

系统初始化

首先从系统的初始化开始,系统初始化主要是系统时钟、看门狗等功能模块的基础配置,TI官方配置的系统初始化函数如下:

void InitSysCtrl(void)
{// Disable the watchdogDisableDog();// Initialize the PLL control: PLLCR and DIVSEL// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.hInitPll(DSP28_PLLCR,DSP28_DIVSEL);// Initialize the peripheral clocksInitPeripheralClocks();
}

上面代码主要由3个子函数构成,分别为 DisableDog();、InitPll(DSP28_PLLCR,DSP28_DIVSEL);、 InitPeripheralClocks();这三个子函数的功能我们也来一一分析。

看门狗配置函数DisableDog()

首先是开门狗初始化函数DisableDog(),函数代码如下:

void DisableDog(void)
{EALLOW;SysCtrlRegs.WDCR= 0x0068;EDIS;
}

代码解释:

1、EALLOW /EDIS 打开/关闭状态寄存器保护EALLOW/EDIS 是DSP为了防止杂散代码或指针破坏关键寄存器的状态宏定义指令,关键寄存器包括ePWM、Flash、器件仿真寄存器、FLASH寄存器、CSM寄存器、PIE矢量表、系统控制寄存器、GPIOMux寄存器等,这些寄存器的状态决定DSP是否稳定运行,因此需要修改之前应用EALLOW打开保护,修改完后必须用EDIS关闭。

2、配置SysCtrlRegs.WDCR寄存器为0x0068。关闭看门狗,也可以戏称为把狗杀了,好残忍,看门狗实际作用就是防止CPU跑飞或者其他故障导致系统出现不可挽回的故障,如果一段时间收不到CPU稳定运行的信号就会复位CPU,从而保证CPU的稳定性。打开WDCR寄存器表可知,寄存器后8位起到实际作用,0x0068 = 0110 1000 ,第7位置0看门狗不满足复位条件,第6位置1禁止看门狗模块,第5~3位写101强制写,第2~0位写000配置看门狗时钟。关键为第6位置1禁止看门狗模块。

锁相环初始化函数 InitPll(DSP28_PLLCR,DSP28_DIVSEL)

其次是锁相环初始化函数,DSP中锁相环函数主要是用在时钟的分频上,将晶振产生的震荡进行分频和倍频操作,是整个芯片心脏——时钟能够起作用的关键之处,因此必须在程序开头对其进行配置。其代码如下:

void InitPll(Uint16 val, Uint16 divsel)
{// Make sure the PLL is not running in limp mode  确保PLL没有运行在故障状态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 在PLLCR可以从更改前,DIVSEL必须为0// 0x0000. It is set to 0 by an external reset XRSn 通过外部重置XRSn将其设置为0// This puts us in 1/4if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;EDIS;}// Change the PLLCR  更改PLLCRif (SysCtrlRegs.PLLCR.bit.DIV != val){EALLOW;// Before setting PLLCR turn off missing clock detect logic 在设置PLLCR之前,关闭缺失时钟检测逻辑SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;SysCtrlRegs.PLLCR.bit.DIV = val;EDIS;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 如果切换至1/2if((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  如果切换至 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/1if(divsel == 3){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;DELAY_US(50L);SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;EDIS;}
}void InitPll(Uint16 val, Uint16 divsel)
{// Make sure the PLL is not running in limp modeif (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/4if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;EDIS;}// Change the PLLCRif (SysCtrlRegs.PLLCR.bit.DIV != val){EALLOW;// Before setting PLLCR turn off missing clock detect logicSysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;SysCtrlRegs.PLLCR.bit.DIV = val;EDIS;DisableDog();while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1){// Uncomment to service the watchdog// ServiceDog();}EALLOW;SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;EDIS;}// If switching to 1/2if((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/1if(divsel == 3){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;DELAY_US(50L);SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;EDIS;}

代码解释:

1、if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0),检测外部时钟是否存在,保证在外部时钟正常的情况下运行系统。

2、  if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0),如果8~7位不等于0,则强制置为0。

3、if (SysCtrlRegs.PLLCR.bit.DIV != val),如果锁相环控制寄存器PLLCR的3~0位不等于10实现10倍频,则使得锁相环状态寄存器MCLKOFF标志位为1,并强制置锁相环控制寄存器PLLCR的3~0位等于10。并且锁定锁相环,然后打开时钟丢失检测功能。

4、if((divsel == 1)||(divsel == 2)) 与 if(divsel == 3) ,配置锁相环的分频。通过查询头文件可以看到这两个值。证明系统默认的倍频数位10倍频,系统默认的分频数为2分频。

由于目前的生产工艺,晶振频率为30Mhz的晶振性能更优,配置外部晶振为30Mhz成为主流,因此选择的倍频数为10,分频数为2,30*10/2 = 150 Mhz ,这也是DSP28335主频为150M的由来。

3、初始化外设时钟函数InitPeripheralClocks();

在进行了外部晶振的倍频和分频后,芯片就要将自己的动力分配给各个外设,驱动各个外设进行工作,这个动力的分配就是初始化外设时钟函数的作用,函数代码如下:

void InitPeripheralClocks(void)
{EALLOW;// HISPCP/LOSPCP prescale register settings, normally it will be set to default valuesSysCtrlRegs.HISPCP.all = 0x0001;SysCtrlRegs.LOSPCP.all = 0x0002;// XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT// XTIMCLK = SYSCLKOUT/2XintfRegs.XINTCNF2.bit.XTIMCLK = 1;// XCLKOUT = XTIMCLK/2XintfRegs.XINTCNF2.bit.CLKMODE = 1;// Enable XCLKOUTXintfRegs.XINTCNF2.bit.CLKOFF = 0;// Peripheral clock enables set for the selected peripherals.
// If you are not using a peripheral leave the clock off
// to save on power.
//
// Note: not all peripherals are available on all 2833x derivates.
// Refer to the datasheet for your particular device.
//
// This function is not written to be an example of efficient code.SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;    // ADC// *IMPORTANT*// The ADC_cal function, which  copies the ADC calibration values from TI reserved// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the// Boot ROM. If the boot ROM code is bypassed during the debug process, the// following function MUST be called for the ADC to function according// to specification. The clocks to the ADC MUST be enabled before calling this// function.// See the device data manual and/or the ADC Reference// Manual for more information.ADC_cal();SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;   // I2CSysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-ASysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1;   // SCI-BSysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1;   // SCI-CSysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-ASysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-ASysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-BSysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1;    // eCAN-ASysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1;    // eCAN-BSysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // ePWM1SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;  // ePWM2SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;  // ePWM3SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;  // ePWM4SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1;  // ePWM5SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1;  // ePWM6// SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;   // Enable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1;  // eCAP3SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1;  // eCAP4SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1;  // eCAP5SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1;  // eCAP6SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;  // eCAP1SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1;  // eCAP2SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1;  // eQEP2SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;       // DMA ClockSysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;     // XTIMCLKSysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // GPIO input clockEDIS;
}

 代码解释:

1、SysCtrlRegs.HISPCP.all = 0x0001;  设置高速外设时钟分频 = sysclk / 2。


 2、SysCtrlRegs.LOSPCP.all = 0x0002;设置低速外设时钟低速外设时钟分频 = sysclk / 2,这里命名稍微有点出入,但是查询头文件后确实是这个功能。只不过换了一种方式表示。本来我以为我很细,但是发现是我很粗,错过前一句的命名风格,实际就是这么命名的。

3、XintfRegs.XINTCNF2.bit.XTIMCLK = 1;配置外部存储器的时钟为默认状态。

4、XintfRegs.XINTCNF2.bit.CLKMODE = 1;外设时钟频率控制位,并配置为默认。

5、SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1等; 外设时钟使能,这里的外设时钟控制寄存器PCLKCR0控制片上各种外设时钟的工作状态,使能或者禁止,也就是说这里控制着外设的各个时钟的关闭和开通。

小结:

通过这个系统初始化函数,我们能够得到几个关键的信息:

1、外部晶振为30Mhz,经过锁相环PLL的倍频和分频操作可以得到DSP28335的主频150Mhz。

2、在初始化函数中,能够选择打开或者关闭各个外设时钟,并且可以配置频率大小。

说实话,在梳理这个初始化程序的过程中,其实好多次想撤退,心里想着反正这些都是固定好的,也不会更改其中的参数,我为什么要花这么多时间去看这个呢,但是咬着牙看下来了。看完之后其实我觉得收获还是挺大的,特别是DSP的主频150Mhz是怎么来的这个点。说来惭愧,用了DSP好久,只知道主频是150Mhz,还真不知道是经过PLL分频又倍频来的,有不有用?我感觉其实还是有用的,我们对需要从事的工作有了更一份的了解,这就有用,也希望自己在日后的学习过程中,刨根究底,不偷懒不粗略,细不细?不够细啊!忍不忍得住,那必须忍得住啊。

DSP28335学习——系统初始化相关推荐

  1. DSP28335学习之旅2-最小系统

    目录 1  什么是最小系统 2  JTAG下载电路 3  电源电路 4  boot电路 5  复位电路 6  晶振电路 1  什么是最小系统 最小系统又称最小应用系统,它是能够使DSP正常工作的最低电 ...

  2. 智源青年科学家候选人 | 张祥雨:挑战自动化深度学习系统

    4月16日,北京智源人工智能研究院发布"智源学者计划",宣布重点支持四类人才:智源科学家首席(CS).智源研究项目经理(PM).智源研究员(PI),以及智源青年科学家. 其中,智源 ...

  3. linux初始化进程ppid号,linux基础(十一)--系统初始化的简谈

    我们在深入学习linux之前呢首先要了解其的引导加载过程,这样我们就可以在判断一些在系统初始化过程的出现问题的来源,并及时做出处理. 这个过程大概分为[开机]--[BIOS](CMOS)--[grub ...

  4. linux基础(十一)--系统初始化的简谈

    我们在深入学习linux之前呢首先要了解其的引导加载过程,这样我们就可以在判断一些在系统初始化过程的出现问题的来源,并及时做出处理. 这个过程大概分为[开机]--[BIOS](CMOS)--[grub ...

  5. 糖尿病视网膜病变的深度学习系统笔记

    糖尿病视网膜病变的深度学习系统笔记 论文地址:A deep learning system for detecting diabetic retinopathy across the disease ...

  6. 从头开始写STM32F103C8T6驱动库(二)——编写系统初始化程序,配置时钟树

    系列文章目录 Github开源地址 从头开始写STM32F103C8T6驱动库(一)--STM32CubeMX创建并调整工程结构 从头开始写STM32F103C8T6驱动库(二)--编写系统初始化程序 ...

  7. Linux安装系统注意事项及系统初始化

      Linux安装系统注意事项 1.分区 学习用途: /boot:200M /swap :内存的1到2倍 /:根据需要分配大小,比如虚拟机下总空间是15G,那么可以分配8--10G跟/分区,如果是生产 ...

  8. 因特理臻深度学习系统培训教程

    因特理臻深度学习系统培训教程 系统一词来源于英文system的音译,即若干部分相互联系.相互作用,形成的具有某些功能的整体.因特理臻深度学习课程构成一个整体. 课程模块设计承前启后,环环相扣,以神经网 ...

  9. (三)DIM-SUM系统之系统初始化

    系统初始化 一.Makefile分析 二.head.S 1.fake_start 2.real_start 3.__prepare_jump_to_master 三.main.c 1.start_ma ...

  10. 【UCOSIII操作系统】系统初始化篇(1)系统初始化

    UCOSIII操作系统 UCOSIII操作系统--系统初始化篇(1)系统内部任务 系统初始化函数 UCOSIII默认有5个系统任务: 空闲任务 时钟节拍任务 统计任务 定时任务 中断服务管理任务 UC ...

最新文章

  1. Python程序设计题解【蓝桥杯官网题库】 DAY12-算法训练
  2. 2017c语言考核册答案,2017年最新C语言考题带答案
  3. 太赞了!华为《Linux中文手册》火了,完整版 PDF 开放下载!
  4. 数据库-优化-索引-索引的优化注意事项
  5. Enterprise Library系列文章目录
  6. amd显卡更新最新驱动鼠标顿卡的解决方法
  7. redis的5种数据结构和基本操作
  8. java生成流程图_java源代码转换为流程图
  9. UE4之python编程
  10. matlab内维尔差值,基于IGS精密星历的卫星位置内插方法比较
  11. mysql用户角色权限表的关系_用户、角色、权限表的关系(mysql)
  12. 猴子爬树php,爬树就像猴子一样顺溜的生肖女
  13. 适合中小企业的项目管理系统有哪些?
  14. 哪一个属于计算机外存储器,下边哪一个属于计算机的外存储器()
  15. oracle数据前面补0,Oracle 数字前面自动补0
  16. ALSA-ASOC音频驱动框架简述
  17. 苹果备忘录分享不了微信提示无法连接服务器,微信分享接口分享完成后在某些苹果设备上不能正常执行回调...
  18. 当深圳变成一座数字花园
  19. 出战卡不足_卡组攻略:关于3卡6卡或者12卡出战的分析
  20. 单片机控制LCD1602显示屏动态显示字符串

热门文章

  1. 为什么阿里不收购OFO小黄车,反而让滴滴抢了先机?
  2. 房地产软件信息化——CRM的“中海模式”穆利堂-movno1
  3. 三菱fx2n做从站的modbus通讯_三菱PLC编程多种电缆接线图,收藏向!
  4. 分布式SQL引擎-----------Inceptor(学习使用)
  5. mysql版本升级对数据的影响_MySQL升级
  6. Unicode 编码表下载
  7. 奎享添加自己字体_如何添加字体?系统字体的两种方法添加方法
  8. 语音聊天室 anyHouse 使用手册
  9. Android跑马灯的效果
  10. Cadence Orcad Capture属性窗口转置的方法图文教程