DSP2812程序执行过程

开始程序,从main()开始运行

Step1:执行语句InitSysCtrl();

初始化系统控制模块:包括PLL, WatchDog, enable Peripheral Control. 这些模块的初始化在DSP281x_SysCtrl.c文件中。

让我们来看看这个初始化系统函数的内容,看看它具体是怎么实现的。

void InitSysCtrl(void)
{DisableDog();//禁止看门狗InitPll(0x8);//设置系统时钟=XCLKIN*8/2InitPeripheralClocks();    //设置外设时钟DINT;                        // 关闭总中断IER = 0x0000;               // 关闭外设中断IFR = 0x0000;               // 清中断标志    InitPieCtrl();            //初始化PIE控制寄存器InitPieVectTable();        //使能PIE向量表
} 

这个函数中可以看出:

1、禁止看门狗DisableDog();

来看一下禁止看门狗的步骤(这个内容书上应该很多了,这里想要一根线式的抓住DSP编程的脉络,所以在这里赘述一下)。  先是写看门狗控制寄存器SysCtrlRegs.WDCR= 0x0068(要开EALLOW)

来看一下WDCR写0x0068的含义(建议像我一样的初学者也来边查寄存器手册边学习),WDCR是一个16位的寄存器,其中15-8位是保留的。给它写0x0068将这些位进行了设置:

WDFLAG=0:手册上说这一位是看门狗复位状态标志位。如果该位置位,表示一个看门狗复位(WDRST)产生了复位条件。如果为0,则是一个外部器件加电复位条件。

WDDIS=1:使看门狗模块无效。

WDCHK(位5-3)=101:只能写101,写其它值核立即复位。

WDPS(2-0)=000:配置看门狗计数器的时钟。写000(或001)时WDCLK=OSSCCLK/512/1。

2、接着设置系统时钟InitPll(0x8);

同样来看一下设置系统时钟的步骤(这个函数带一个参数)。

让我把这个函数帖在这里

 1 void InitPll(Uint16 val)
 2 {
 3    volatile Uint16 iVol;
 4
 5    if (SysCtrlRegs.PLLCR.bit.DIV != val)
 6    {
 7
 8       EALLOW;
 9       SysCtrlRegs.PLLCR.bit.DIV = val;
10       EDIS;
11
12       for(iVol= 0; iVol<4096; iVol++);
13    }
14 }

InitPll(0x8)

意思是说将PLLCR写0x8。通过查寄存器表,PLLCR的15-4位是保留的。将3-0位写1000的意思是CLKIN=(OSCCLK*8.0)/2。

程序里for(iVol= 0; iVol<4096; iVol++);语句的意思是PLL的设置须要一定的时间,这里写这句来确保PLL顺利启动。

3、设置外设时钟InitPeripheralClocks();首先设置分频时钟

   SysCtrlRegs.HISPCP.all = 0x0001;//设置高速时钟 2分频SysCtrlRegs.LOSPCP.all = 0x0002;//设置低速时钟 4分频

然后设置外设时钟PCLKCR,PCLKCR的15位是保留的,按位定义将EVAENCLK EVBENCLK,SCIAENCLK,SCIBENCLK,MCBSPENCLK,SPIENCLK,ECANENCLK,ADCENCLK位全部置1,表示使能这些外设时钟,这些外设有的用的是高速时钟,有的用的是低速时钟。

4、关闭总中断。

5、关闭外设中断。

6、清中断标志。

7、初始化PIE控制寄存器InitPieCtrl();

void InitPieCtrl(void)
{DINT;    //禁止CPU级中断
PieCtrlRegs.PIECRTL.bit.ENPIE = 0;//屏蔽PIE中断向量表//清除所有PIEIER寄存器PieCtrlRegs.PIEIER1.all = 0;PieCtrlRegs.PIEIER2.all = 0;PieCtrlRegs.PIEIER3.all = 0;    PieCtrlRegs.PIEIER4.all = 0;PieCtrlRegs.PIEIER5.all = 0;PieCtrlRegs.PIEIER6.all = 0;PieCtrlRegs.PIEIER7.all = 0;PieCtrlRegs.PIEIER8.all = 0;PieCtrlRegs.PIEIER9.all = 0;PieCtrlRegs.PIEIER10.all = 0;PieCtrlRegs.PIEIER11.all = 0;PieCtrlRegs.PIEIER12.all = 0;// 清除所有PIEIFR寄存器PieCtrlRegs.PIEIFR1.all = 0;PieCtrlRegs.PIEIFR2.all = 0;PieCtrlRegs.PIEIFR3.all = 0;    PieCtrlRegs.PIEIFR4.all = 0;PieCtrlRegs.PIEIFR5.all = 0;PieCtrlRegs.PIEIFR6.all = 0;PieCtrlRegs.PIEIFR7.all = 0;PieCtrlRegs.PIEIFR8.all = 0;PieCtrlRegs.PIEIFR9.all = 0;PieCtrlRegs.PIEIFR10.all = 0;PieCtrlRegs.PIEIFR11.all = 0;PieCtrlRegs.PIEIFR12.all = 0;
}    

ENPIE这PIE中断扩展寄存器里的PIECTRL(中断控制寄存器)里的最后一位,它的意思是从PIE块中取回向量使能。该位置0,PIE无效。

总之,4,5,6,7步貌似就是关闭一切中断(外部中断,CPU中断,PIE中断),清除一切中断标志。这样做的目的应该就是使系统初始化到一种已知的状态。便于我们以后操作。

8、使能PIE向量表InitPieVectTable();

void InitPieVectTable(void)
{int16    i;Uint32 *Source = (void *) &PieVectTableInit;Uint32 *Dest = (void *) &PieVectTable;EALLOW;    for(i=0; i < 128; i++)*Dest++ = *Source++;    EDIS;// 使能中断向量表PieCtrlRegs.PIECRTL.bit.ENPIE = 1;    }

值得注意的是,如果DSP芯片复位,在没有初始化PIE前,换句话说还没有将ENPIE设为1时,使用的是BROM向量。因此,在DSP复位和程序引导完成之后,用户必须对PIE向量表进行初始化,然后由应用程序使能PIE向量表,这样CPU响应中断时,就从PIE中断向量表中所指出的位置上取出中断向量,即取出中断服务子程序的地址。

这就是这两条语句的意思。

Uint32 *Source = (void *) &PieVectTableInit;
Uint32 *Dest = (void *) &PieVectTable;

 

中断向量表的地址是2*16位的,也就是32位地址。

----初始化系统模块就是这些内容。

Step2:初始化GPIO。设置GPIO到它的默认状态只须要一条语句(函数)InitGpio();本例跳过这个设置,因为用不到GPIO作为实时I/O口。

而只须要用到它的多功能引脚GPAMUX和GPBMUX作为PWM输出引脚(将GPAMUX和GPBMUX都写0x00FF即可,受EALLOW保护)。

Step3:清除所有中断并初始化PIE向量表。这个过程怎么来来回回两次了,不知道这个函数写的是不是有问题,明天再看。

Step4:执行init_eva(),init_evb()函数,也就是输出PWM波。

void init_eva()
{// EVA Configure T1PWM, T2PWM, PWM1-PWM6
// Initalize the timers// Initalize EVA Timer1 EvaRegs.T1PR = 0xFFFF;       // Timer1 periodEvaRegs.T1CMPR = 0x3C00;     // Timer1 compareEvaRegs.T1CNT = 0x0000;      // Timer1 counter// TMODE = continuous up/down// Timer enable// Timer compare enableEvaRegs.T1CON.all = 0x1042;   // Initalize EVA Timer2 EvaRegs.T2PR = 0x0FFF;       // Timer2 periodEvaRegs.T2CMPR = 0x03C0;     // Timer2 compareEvaRegs.T2CNT = 0x0000;      // Timer2 counter// TMODE = continuous up/down// Timer enable// Timer compare enableEvaRegs.T2CON.all = 0x1042;   // Setup T1PWM and T2PWM// Drive T1/T2 PWM by compare logicEvaRegs.GPTCONA.bit.TCMPOE = 1;// Polarity of GP Timer 1 Compare = Active lowEvaRegs.GPTCONA.bit.T1PIN = 1;// Polarity of GP Timer 2 Compare = Active highEvaRegs.GPTCONA.bit.T2PIN = 2;// Enable compare for PWM1-PWM6EvaRegs.CMPR1 = 0x0C00;EvaRegs.CMPR2 = 0x3C00;EvaRegs.CMPR3 = 0xFC00;// Compare action control.  Action that takes place// on a cmpare event// output pin 1 CMPR1 - active high// output pin 2 CMPR1 - active low// output pin 3 CMPR2 - active high// output pin 4 CMPR2 - active low// output pin 5 CMPR3 - active high// output pin 6 CMPR3 - active lowEvaRegs.ACTRA.all = 0x0666;EvaRegs.DBTCONA.all = 0x0000; // Disable deadbandEvaRegs.COMCONA.all = 0xA600;} 

1、T1PR定时器1周期寄存器写初值0xFFFF;T1CMPR定时器1计数的比较值设有0x03C0;T1CNT定时器1当前计数值设为0x0000;这三步称为初始化EVA Timer1。

2、通用定时器1控制寄存器T1CON=0x1042:将TMODE1、T2SWT1、TECMPR这三位置为1。

其中TMODE1~TMODE0=10,表示计数器工作在连续增模式。T2SWT1写1表示使用T1CON的使能位。TECMPR写1使能定时器1的比较操作。

3、接着初始化EVA的Timer2,然后设置T2CON=0x1042,注意,Timer2使用的是T1CON的使能位。

4、EvaRegs.GPTCONA.bit.TCMPOE = 1;使能定时器比较输出。T1PIN = 1定时器1比较输出低有效,T2PIN定时器2比较输出高有效。

5、使能PWM1~PWM6,三条语句:

EvaRegs.CMPR1 = 0x0C00;
EvaRegs.CMPR2 = 0x3C00;
EvaRegs.CMPR3 = 0xFC00;

——没查到这三个寄存器赋值的意思 - -!

6、EvaRegs.ACTRA.all = 0x0666;设置比较输出引脚6,4,2低有效,5,3,1高有效。

DBTCONA死区定时器控制寄存器写0x0000,不使能死区控制。

COMCONA比较控制寄存器A写0xA600,使能比较操作,14~13位写01表示当T3CNT=0或T3CNT=T3PR(下溢或周期匹配)时,比较器寄存器CMPRx重载。12位为0,表示禁止空间向量PWM模式。

11~10位01,当T3CNT=0或T3CNT=T3PR(即下溢或周期匹配)时控制寄存器重载。9位设为1,全比较输出,PWM1~6由相应的比较逻辑驱动。

——init_evb()与init_eva()的设置步骤相同。

总结:

posted on 2014-03-31 21:37 ii沙漠 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/shamoof/p/3636896.html

DSP2812程序执行过程相关推荐

  1. MFC程序执行过程剖析

    一 MFC程序执行过程剖析 1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用 ...

  2. 菜鸟学习笔记:Java基础篇3(面向对象思想、程序执行过程内存分析、面向对象重要概念)

    菜鸟学习笔记:Java面向对象篇上 Java面向对象的思想 Java程序执行过程内存分析 Java垃圾回收机制 构造方法 方法重载(overload) static关键字 this关键字 Java面向 ...

  3. 操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法

    操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测 ...

  4. Python源码学习笔记:Python程序执行过程与字节码

    Python程序执行过程与字节码 注:本篇是根据教程学习记录的笔记,部分内容与教程是相同的,因为转载需要填链接,但是没有,所以填的原创,如果侵权会直接删除. 问题: 我们每天都要编写一些Python程 ...

  5. 【操作系统】程序执行过程

    本章主要介绍程序执行过程中操作系统.CPU都干了什么 运行前 程序在运行前,只是在硬盘上待着,此时就是一堆二进制代码而已,没有任何作用. 程序只有进入了内存才能运行,但是要进入内存,则需要服从操作系统 ...

  6. C语言是从什么位置开始执行程序,c程序执行过程是从哪开始到哪里结束的

    c程序执行过程是从哪开始到哪里结束的 发布时间:2020-08-26 09:17:28 来源:亿速云 阅读:366 作者:小新 这篇文章主要介绍了c程序执行过程是从哪开始到哪里结束的,具有一定借鉴价值 ...

  7. Java语言是编译型语言还是解释型语言?(Java程序执行过程)

    Java语言是编译型语言还是解释型语言? 我们都知道,编程语言从程序执行过程分,分为编译型语言和解释性语言 什么是编译型语言和解释型语言? Java语言看似是编译型的,因为Java程序代码的确是需要经 ...

  8. Python语言是编译型语言还是解释型语言?(Python程序执行过程)

    Python语言是编译型语言还是解释型语言? 我们都知道,编程语言从程序执行过程分,分为编译型语言和解释性语言 什么是编译型语言和解释型语言? Python是一种解释型语言 Python程序源码不需要 ...

  9. python\java\c\解释性语言\编译性语言 程序执行过程

    c时纯粹的编译性语言,执行过程如下图: 可以看出c是通过预处理器.编译器.汇编器和链接器生成可执行的二进制目标文件,然后直接运行(编译性语言的本质).  Java和python是解释性语言,但并不是纯 ...

最新文章

  1. 域、代理服务、防病毒服务器、WEB/FTP、打印服务器、路由交换、文件服务器
  2. 关于Ubuntu运行级别、开机启动脚本的说明
  3. Scala自动隐式转换
  4. 工作63:await和anync
  5. python三大库_Python 经典库汇总(3)
  6. [Erlang 0020]网页游戏分线到不分线
  7. Android Framework - 学习启动篇
  8. 汉字时钟屏保软件/汉字时钟电脑屏幕保护下载/汉字时钟屏保/windows屏保
  9. Node.js使用jszip实现文件夹操作
  10. 计算机统计硕士排名,卡内基梅隆大学硕士统计学专业排名务必稳重的去看
  11. java idisposable_IDisposable实现 - 'if (disposing)'应该怎么做
  12. 服务器显示初始化失败怎么回事,服务器初始化失败
  13. linux命令一个减号,linux shell环境减号-的用途
  14. 魔兽争霸平台显示服务器地址错误,发现(魔兽争霸出现错误的解决方法)
  15. java泡泡屏保,js 模拟气泡屏保效果代码
  16. OROCOS之KDL(1)—— Linux环境搭建篇
  17. c语言sub函数是什么,用$Super$$和$Sub$$对函数进行重定义
  18. python中怎么画一个机器猫_如何用Python画一只机器猫?
  19. python获取当前进程pid_Python获取系统所有进程PID及进程名称的方法示例
  20. 【PMP】PMBOK 笔记 第7章 项目成本管理

热门文章

  1. 【Linux】一步一步学Linux——which命令(45)
  2. Android开发文章推荐
  3. html怎么给框格加背景图,怎么给word 2013表格添加漂亮的背景图片
  4. 微信小程序 下拉刷新页面时的加载状态
  5. 《Linux内核设计与实现》读书笔记(十二)- 内存管理
  6. 2049 : 压死骆驼的最后一根稻草 (规律)
  7. html3D效果可以在手机打开吗,手机怎么打开HTML
  8. GitFlow 工作流和Code Review教程
  9. [NOTE] XVWA靶场练习笔记
  10. 二维数组数组名的使用