08级DSP控制技术复习

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

08级《DSP控制技术》复习题及参考答案(初稿)
1考试内容
以教材及其解答为主,并参考授课PPT和PMSM3-3程序
2考题题型
判断题、填空题、选择题、计算与编程题、软件设计题、简述题。

重点掌握片内外设寄存器的功能和设置及其初始化。

掌握系统控制初始化(包括PLL设置、系统时钟设置、屏蔽看门狗,高速和低速外设时钟设置);掌握GPIO的使用和ADC的使用;掌握事件管理器的使用尤其是对称与非对称PWM波形的产生步骤;掌握PIE中断机制及常用外设中断的设置。

了解SCI和SPI及XINTF。

了解DSPC语言的特点和关键字,了解寄存器和存储器的空间分配及CMD文件的编写。

掌握C/C++生成软件模块的方法。

掌握Q格式和标幺化方法,掌握DSP硬件设计中电平转换、PWM驱动隔离等方法,了解无刷直流电动机和永磁同步电动机的原理和控制方法,掌握直流电机的DSP实现。

掌握应用系统软硬件调试的增量式方法。

掌握根据控制框图分解软件模块的方法和用软件模块构建系统的方法。

一DSP概述
1-1 DSP芯片有什么特点?DSP按数据格式分为哪两类?
计算机控制技术要求处理器的速度越来越高,体积越来越小,DSP的发展正好能满足这一发展的要求。

因为,传统的其它处理器都有不同的缺陷。

MCU的速度较慢;CPU体积较大,功耗较高;嵌入式CPU的成本较高。

DSP的发展,使得在许多速度要求较高,算法较复杂的场合,取代MCU或其它处理器,而成本有可能更低。

与MCU相比:速度比MCU快,主频较高;适合于数据处理,数据处理的指令效率较高;DSP均为16位以上的处理器,不适合于低档的场合,适用于复杂控制算法的实现;DSP可以同时处理的事件较多,系统级成本有可能较低。

DSP的灵活性较好,大多数算法都可以软件实现。

DSP的集成度较高,可靠性较好。

与嵌入CPU相比:DSP是单片机,构成系统简单;DSP的速度快;DSP的成本较低;DSP的性能高,可以处理较多的任务。

DSP按数据格式分为定点和浮点DSP。

定点与浮点DSP的基本差异在于它们对数据的数字表示法不同。

定点DSP严格执行整数运算,而浮点DSP既支持整数运算又支持实数运算,后者以科学计数法进行了标准化。

浮点DSP将数据路径分为两部分:一是可用作整数值或实数基数的尾数,二是指数。

业界标准单一精确运算的32位浮点DSP中,尾数是24位,指数是8位。

动态范围大大高于定点格式提供的精确度。

但需要的内部电路多,32位数据路径经当时可用定点器件宽1倍。

晶片面积越大,引脚数量也越多,封装也越大,成本也更高。

但它支持C语言。

浮点格式中,实数运算可直接通过代码加入硬件运算中,而定点器件则须通过软件才能间接运行实数运算。

增加了算法指令与延长了开发时间。

浮点最初用于开发工作强度较大的情况。

所以一般定点DSP功耗低,成本低,而浮点DSP成本高,功耗大。

1-2 TI公司的TMS320有几大系列?分别有什么特点?
TMS320系列DSP主要分为两种类型:定点DSP芯片,浮点DSP芯片;相比之下,定点DSP系列
齐全,时钟频率略高些;浮点DSP适于需要大量高精度运算的场合。

C2000称之为最佳控制平台,集成有事件管理器等多种电机控制系统需要的外设,适合电机的数字控制;C5000称之
为最低功耗平台,具有处理速度快、功耗低、相对成本低等特点,适合便携、消费类电子设备;C6000称之为最佳处理能力平台,处理速度更快、精度高,更适合图像处理及通信设备
等高端市场。

A C2000高性能的数字控制
针对数字运动控制系统设计的定点DSP,具有强大的运算和控制能力;
LF24x为低成本、低功耗系列,速度可达40MIPS;
C28x系列的内核和指令与LF24x完全兼容。

主频高达150MHz,主要用于大存储设备管理,高性能的控制场合。

TMS320C2000 DSP特点:1)唯一内含Flash的DSP系列;2)唯一内含SCI 的DSP系列,易实现和PC机的RS232串口通信。

B C5000低功耗的手持设备
C5000(定点、低功耗)系列是目前TI DSP的主流DSP,它涵盖了从低档到中高档的应用领域,目前也是用户最多的系列。

C55x系列是TI的第三代DSP,与54X兼容,功耗为C54xx的1/6,性能为C54xx的5倍 ;应用领域:3G无线通信、语音处理、GPS、无线网络、数码产品。

C C6000高性能的DSP应用;是TI的超高性能DSP系列,功耗较大;
C62xx系列是定点的DSP,系列芯片种类较丰富,是主要的应用系列;
C64xx系列是新产品,性能是C62xx的10倍;
C67xx系列是浮点的DSP,用于需要高速浮点处理的领域;
应用领域:宽带网络、无线基站、3D图象、语音识别、多媒体系统。

D C3X系列是高性能的32位浮点DSP具有较高的性价比,适于那些数据动态范围大、精度高的应用;推荐使用VC33 ;C3x系列是TI浮点DSP的基础。

应用领域:工业自动化和机器人、视频会议、语音处理、汽车电子、计算机外设。

1-3 DSP芯片主要有哪些特点?
(1) 采用哈佛结构,程序和数据存储空间分开,可以同时访问指令和数据。

(2) 具有专用硬件乘法器,可在一个指令周期内完成一次乘法和一次加法。

(3) 支持流水线操作,使取指、译码和执行等操作可以重叠执行。

(4) 可以并行执行多个操作, 具有特殊的DSP指令。

(5) 片内具有快速RAM,通常可通过独立的数据总线在两块中同时访问,具有片内多
总线结构。

(6) 具有在单周期内操作的多个硬件地址产生器,单周期指令。

(7) 快速的中断处理和硬件I/O支持。

1-4 常用的DSP芯片有哪些?
TI公司:TMS320系列DSP已经成为当今世界最有影响的DSP芯片,其DSP市场占有量占全世界份额的近50%,为世界上最大的DSP芯片供应商;
Motorola公司:MC96002;
ADI (Analog Device)公司:AD2100;
MicroChip: dSC;
A T&T:DSP16/32
二 DSP2812
2-1简述2812 DSP的内部结构主要部分的功能。

CPU、片内存储器、片内外设(片内接口电路)
F28x DSP的硬件资源
2-2 指出下列符号的物理意义
ACC(AH、AL)累加器
XT(T、TL)乘法寄存器
P(PH、PL)乘积寄存器
DP 数据页指针
SP 堆栈指针
XAR0~XAR7 辅助寄存器0~7
AR0~AR7 辅助寄存器0~7的低16位
PC 程序计数器
RPC 程序返回计数器
ST0 状态寄存器0
ST1 状态寄存器1
IFR 中断标志寄存器
IER 中断使能寄存器
DBGIER 调试中断使能寄存器。

2-3 状态寄存器STO和STl有什么作用?
DSP控制器含有两个状态寄存器ST0和ST1,它们含有各种状态和控制位。

状态寄存器的内容可以被保存到数据存储器,也可以从数据存储器中进行加载。

在子程序调用或者进入中断子程序时,实现CPU状态态的保存;在退出子程序或从中断子程序返回前,将CPU的状态回返。

ST0
累加器具有相关状态位信息保存在状态寄存器ST0中。

ST0主要用于算术逻辑运算,并且只能在流水线的E 阶段进行修改,其中,OVM 、OVC/OVCU、V 主要用于控制算术逻辑运算中的溢出保护功能,N,Z,C用于对运算结果做出指示,PM 用于位移操作。

表中的保留位读出时为1。

ST1
ST1主要用于寻址逻辑控制,其中,XF、MOMIMAP、OBJMODE 于兼容模式的选择,AMODE、PAGE0、ELLOW 和SPA 用于指示和控制CPU 的寻址方式。

IDI ESTAT、LOOP用于指示CPU 的工作状态,INTM 实现中断使能的设置。

位 6 EALLOW仿真读取使能位。

复位时,该位允许对仿真和其它寄存器进行读取。

EALLOW可由AEALLOW置位,由EDIS指令清0。

当CPU服务于某一中断时,EALLOW
清0。

然而,在中断服务子程序ISR的开始就去读到仿真寄存器是不允许的。

如果ISR必须读取仿真寄存器,它必须包含一个EALLOW指令,在ISR的结束,可用IRET指令进行恢复。

位0 INTM中断全局屏蔽位。

该位可全局使能和禁止所有的CPU可屏蔽中断。

0 可屏蔽中断被全局使能。

为被CPU确认,必须由中断使能寄存器IER产生局部使能的可屏蔽中断。

1 可屏蔽中断被全局禁止。

即使可屏蔽中断由IER局部使能,也不能被CPU确认。

但对非屏蔽中断、硬件复位和硬件中断NMI没有影响。

另外当CPU在实时仿真模式下暂停时,即使INTM已置为屏蔽,仍可由IER和DBTIER激活一个可屏蔽中断。

2-4 哪些片内外设的寄存器是受EALLOW保护的?
受EALLOW保护即CPU不能写。

在CPU状态寄存器ST1的EALLOW指明了寄存器的保护状态。

复位后,EALLOW清0,使能EALLOW保护。

只允许CPU读,JTAG读和写。

执行EALLOW指令,即EALLOW位置1,CPU可写寄存器。

修改完毕后,执行EDIS指令,EALLOW位清0,保护这些寄存器不被CPU写了。

下列寄存器受EALLOW保护:
DSP仿真寄存器;Flash寄存器;CSM寄存器;PIE矢量表;系统控制寄存器;GPIO MUX 寄存器;特定的eCAN寄存器。

外部存储器及I/O扩展XINTF Zone0/1, Zone2, Zone6/7, 1M+32K。

通过数据线XD0-XD15、地址线XA0-XA18及控制信号线扩展。

典型的DSP应用系统多采用最小系统,即系统由一个F2810 DSP芯片加上相应的电源、时钟、复位、JTAG电路及应用电路构成,这种系统也称为单片系统方案(Single Chip Solution)。

在程序调试过程中,可以先将程序放入到H0 SARAM、L0 SRAM和L1 SARAM中运行仿真调试,对于程序长度小于16K时比较方便。

调试完成后,再将程序放入Flash存储器中运行。

2-5 DSP2812由哪此片内外设组成?
片内外设有事件管理器A、B、ADC、WD、MCBSP、CAN、SCIA、B、SPI和GPIO。

其中只有ADC 输入,WD输出,其它外设都是可双向流动的。

CPU内部有存储器总线挂有算术逻辑单元、乘法器和辅助寄存器。

内部数据总线是32位,地址总线是22位。

其中EV是控制器特有的部件而有别于C5000和C6000。

主要就是用来完成速度和位置数字部件的信号输入和处理,提供速度反馈和位置反馈。

MCBSP 是多通道缓冲串口; CAN、SCI、SPI是通信接口模块。

2 F2812主频最高可达150MHZ,内部集成128KB的Flash存储器,4KB的Boot ROM。

F系列与C系列的区别是F系列带Flash,而C系列不带。

2810可以说是28XX系列的最小系统。

与2812相比,2810不带外部扩展接口XINTF也无外部总线。

三 DSP 软件开发基础
3-1 DSPC语言有何特点?
数据类型
C语言的每个数据类型都有与之对应的类型名保留字,由于281x中数据的最小长度为16位,因此所有的字符(char)型数据,包括有符号字符型(signed char)和无符号字符型(unsigned char),长度均为16位,即用一个字的长度表示。

数据类型的其它特点有:所有的整型(char,short,int,以及对应的无符号类型)都是等效的,用16位二进制值表示;长整型和无符号长整型用32位二进制值表示。

有符号数用2s 补码符号表示。

char 是有符号数,等效于int。

枚举类型enum代表16位值,在表达式中enum 与int等效。

所有的浮点类(float、double、long double)等效,表示成IEEE单精度格式。

3-2 DSPC语言有哪些关键字?
TMS320C28x C/C++编译器支持标准的const、register、volatile等关键字,另外还扩展了cregister、interrupt、near、far等关键字。

const
该关键字可以使你更优化存储器的分配。

你可以加const到任何变量或阵列的定义以确保其内的值不改变。

例如在下例中,定义了一个const型的PIE_VECT_TABLE类型的结构变量PieV ectTableInit:
interrupt void PIE_RESERVED(void) // Reserved space. For test.
{
asm (" ESTOP0 ");
for(;;);
}
const struct PIE_VECT_TABLE PieV ectTableInit = {
PIE_RESERVED, // Reserved space
PIE_RESERVED, // Reserved space

}
其中PIE_VECT_TABLE 是一个存放中断矢量表的结构,PieV ectTableInit是该结构的一个变量,其中定义了所有中断函数的起始地址。

由于这些地址在Flash中都固化好,不会改变,因此在声明PieV ectTableInit前可以加const以表示其中的变量内容是常数,不会改变。

volatile
编译时优化器会分析数据的流动,尽可能避免对存储器的读写。

因此如果你要编写C 代码对存储器进行读写操作,就必须用volatile关键字确定这些操作,以此来说明所定义的变量是“可变的”,是可以被DSP中的其它硬件修改的,而不是仅仅只能由C程序本身修改。

用volatile关键字修饰的变量会被分配到非初始化块。

编译器不会对volatile 变量做任何优化。

cregister
编译器扩充了C,增加了cregister关键字,从而允许高级语言读写控制寄存器。

当你对一个对象加cregister修饰时,编译器比较对象和IER(中断使能寄存器)、IFR(中断标志寄存器)的名字。

如果名字相符,编译器产生对控制寄存器操作的代码;如果名字不符,编译器提示一个错误。

cregister关键字仅用于文件范围内,不能用于函数内的声明。

而且cregister只能用于整型或指针,不能用于浮点、结构或联合等类型。

cregister并没有指明对象是否是volatile,如果控制寄存器是volatile的(即可以被外部控制所修改),该对象就应该同时用volatile 声明。

在281x C中,cregister仅限于IER、IFR,因此程序中必须有如下声明:
extern cregister volatile unsigned int IER;
extern cregister volatile unsigned int IFR;
在声明了寄存器后,就可以直接用它了。

注意IFR只能用| (或)操作和&(与)操作,例:IFR | =0x100;
IFR & =0x100;
interrupt
28x C/C++编译器增加了interrupt关键字用来说明一个函数是一个中断函数。

中断函数有一些特殊的地方,如寄存器保存和返回顺序。

当一个函数用interrupt定义后,编译器就自动加入基于中断函数的寄存器内容保存和特殊的中断返回顺序的部分。

pragma对象
pragma对象告诉编译器的预处理器如何对待函数。

TMS320C28x C/C++支持如下的pragma:CODE_SECTION(func,“section name”)
DA TA_SECTION(symbol,“section name”)
INTERRUPT(func)
FUNC_EXT_CALLED(func)
FAST_FUNC_CALL(func)
其中,func和symbol必须在函数外声明或定义。

同时也必须在函数外指定pragma,而且必须在声明、定义、引用func和symbol之前指定pragma。

不这样做编译器会产生警告错误。

CODE_SECTION
CODE_SECTION为func在一个名为section name的块中指定空间。

如果你有一个代码对象并想将其链接到不同于.txt的空间时,该语法就非常有用。

C的标准用法是:
#pragma CODE_SECTION(func,“section name”);
例:
char bufferA[80]; // bufferA是全局变量
#pragma CODE_SECTION(funcA,“codeA”);
char funcA(int i); //对函数funcA的声明
void main()
{
char c;
c=funA(1); //对函数funcA的引用
}
char funcA(int i) //函数funcA的定义
{
return bufferA[i];
}
在上例中,函数代码块funcA被定位于codeA段中。

codeA段在.cmd文件中规定了物理地址。

DATA_SECTION
DA TA_SECTION为symbol在一个名为section name的块中指定空间。

如果你有一个数据对象并想将其链接到不同于.bss的空间时,该语法就非常有用。

C的标准用法是:
#pragma DA TA_SECTION(symbol,“section name”);
例:
#pragma DA TA_SECTION(bufferB,“my_sect”);
char bufferB [512]; // 对bufferB的定义放在pragma的后面
数据块bufferB被定位于my_sect段中,my_sect段在.cmd文件中规定了物理地址。

far
C/C++编译器的默认寻址空间是64K。

所有指针的默认大小为16位。

C28x支持的寻址空间达4M字, 即22位。

加上far关键字限定符的指针大小为22位,可以寻址4M字空间。

3-3 DSPC语言中如何用实现寄存器及存储器的硬件抽象?
DSP2812可以用汇编语言和C语言编写程序代码。

由于系统时钟高,运行速度快,大多采用C语言编程。

同单片机一样,DSP的C语言也是面向硬件的C语言。

对硬件的操作就是对寄存器的操作。

用C语言实现寄存器的硬件抽象是关键。

不同于MCU,DSP2812及C5000、C6000系统符合嵌入式系统C语言规范EC++。

通过pragma伪指令告诉编译器如何对待特定的函数、对象或代码段。

TMS320C28x C/C++编译器支持如下形式的pragma伪指令:
CODE_SECTION(func,“section name”);
DATA_SECTION(symbol,“section name”);
注意:func和symbol必须在函数外声明或定义。

同时,pragma伪指令也必须在函数外,且位于声明、定义或引用func和symbol之前,否则,编译器会给出警告信息。

寄存器的定义
1采用结构体、共用体、位域结构体定义寄存器变量,并虚拟一个外设寄存器结构体,它包含了相应外设如EV的所有寄存器及位定义。

其寄存器定义在DSP281x_Ev.h文件中,此文件中还定义了函数原型和外部定义如:
extern volatile struct EVA_REGS EvaRegs;extern volatile struct EVB_REGS EvbRegs; extern 将此结构变量说明为外部变量;volatile 意思为“可变的”,所修饰的变量会
被分配到非初始化段,编译器不会对此变量进行任何优化。

是可以由DSP中的其它硬件修改的,而不仅仅只能由C程序本身。

由于寄存器都是映射到数据存储器,要编写C代码对
存储器进行读/写操作,必须用volatile关键字确定这些操作。

而函数原型在文件DSP281x_GlobalPrototypes.h中定义,如extern void InitAdc(void); extern void InitEv(void); extern void KickDog(void);extern void DisableDog(void);等。

2在全局变量和为命名段名的段中符号分配空间文件DSP281x_GlobalVariableDSP281x 中,通过pragma伪指令将寄存器变量分配到数据段。


#pragma DATA_SECTION(AdcRegs,"AdcRegsFile");
3 DSP281x外设寄存器链接命令文件DSP281x_Headers_nonBIOS.cmd中,通过MEMORY伪指令指示寄存器的实际硬件空间如 ADC : origin = 0x007100, length = 0x000020
4 DSP281x外设寄存器链接命令文件DSP281x_Headers_nonBIOS.cmd中通过
SECTIONS伪指令将寄存器数据段分配到实际硬件空间。


AdcRegsFile : > ADC, PAGE = 1
存储器的映射也类似于寄存器,但简单得多,只需在命令文件中分配到实际硬件空间。

一般在存储器F2812程序在RAM运行时的连接命令文件F2812_EzDSP_RAM_lnk.cmd中。

这样就将用结构变量AdcRegs、PieVectTable等描述的ADC寄存器、中断矢量表和真正的硬件地址对应起来。

因此用户在使用时就完全可以不用考虑具体的硬件地址映射问题。

其他硬件的编程方法类似。

3-4 C/C++工程项目由哪些文件组成?各自的功能是什么?
一个DSP应用,在TI公司的集成开发环境CCS(code composer studio)中组织成一个项目(project)。

项目通常由以下文件组成:
(1)C语言程序(.c)
(2)头文件(.h)
(3)库文件(rts2xx.lib)
(4)命令文件(.cmd)
(5)复位和中断向量文件vectors.asm
其中只一个.c文件含有main(),称为主程序,其它.c文件可是一些相关的子程序,如中断、初始化子程序等,这些都是可执行的.c文件。

编译程序在编译时会分别编译所有的文件再用链接器将所有的.OBJ文件链接起来。

另外,.h文件按照各种外设和CPU资源定义了各种寄存器。

上述绝大部分子程序其实都不用用户自己编写,在TI公司的免费例程中已经写好,用户只需要稍加修改,并加入自己的主程序,就可编写出自己的工程文件。

这也就是用C语言编程上手快的原因之一。

DSP281x_SysCtrl.h 系统控制寄存器定义
DSP281x_PieVect.h PIE 矢量表定义
DSP281x_PieCtrl.h PIE 控制寄存器定义
DSP281x_DefaultIsr.h 缺省中断服务定义
DSP281x_XIntrupt.h外部中断寄存器定义
DSP281x_Adc.h ADC寄存器定义
DSP281x_CpuTimers.h CPU寄存器定义
DSP281x_Ecan.h Ecan 寄存器定义
DSP281x_Ev.h 事件管理器寄存器定义
DSP281x_Gpio.h 通用IO 寄存器定义
DSP281x_Mcbsp.h Mcbsp 寄存器定义
DSP281x_Sci.h Ecan 寄存器定义
DSP281x_Spi.h Ecan 寄存器定义
DSP281x_Ecan.h Ecan 寄存器定义
DSP281x_Xintf.h Xintf 寄存器定义
DSP281x_Xintf.h Xintf 寄存器定义
DSP281x_SWPrioritizedIsrLevels.h 软件优先级定义
DSP281x_Dvice.h 28XX元件定义,包括常用CPU寄存器如IFR,IER,常用汇编的预编译
#define DINT asm(" setc INTM")
#define ERTM asm(" clrc DBGM")
#define DRTM asm(" setc DBGM")
#define EALLOW asm(" EALLOW")
#define EINT asm(" clrc INTM")
#define EDIS asm(" EDIS")
#define ESTOP0 asm(" ESTOP0")
还有常用中断的数字定义,寄存器位定义,DSP C语言数据类型定义如
#ifndef DSP28_DATA_TYPES
#define DSP28_DATA_TYPES
typedef int int16;
typedef long int32;
typedef unsigned int Uint16;
typedef unsigned long Uint32;
typedef float float32;
typedef long double float64;
#endif
并包含了所有外设的头文件
DSP281x_GlobalPrototypes.h 全局函数原型for DSP28 Examp les
extern void InitAdc(void);
extern void InitPeripherals(void);
extern void InitECan(void);
extern void InitEv(void);
extern void InitGpio(void);
extern void InitMcbsp(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void EnableInterrupts(void);
extern void InitSci(void);
extern void InitSpi(void);
extern void InitSysCtrl(void);
extern void InitXintf(void);
extern void InitXIntrupt(void);
extern void InitPll(Uint16 val);
extern void InitPeripheralClocks(void);
extern void KickDog(void);
extern void DisableDog(void);
在相应的.c文件中规定了寄存器的初始化函数及其缺省值。

DSP281x_PieCtrl.c PIE 控制寄存器初始化函数
DSP281x_PieVect.c PIE矢量表初始化函数
DSP281x_DefaultIsr.c 缺省中断服务路线
DSP281x_GlobalVariableDefs.c 全局变量和数据段程序
DSP281x_GlobalVariableDefs.c DSP281x 全局变量和数据段
3-5与教材中C语言的函数模块相比,类模块具有以下优点:
1函数名比变量名稳定。

所有的接口使用公有的成员函数而不是公有的数据成员。

代价是即便是简单的输入输出(本可以通过变量赋值来实现的)也须通过成员函数来完成。

函数调用是有额外开销的。

是以降低效率来换取可维护性的一种策略。

C++可通过在类的内部定义函数或用关键字inline实现内联,来减少函数开销。

TI采用赋值语句来完成对象的输出输入功能。

2相对于C,C++可节省全局符号资源
3相对于函数,对象是更抽象的概念
4 对象是更大的容器
5 以数据为中心是更为合理的模块
6 提供了改进如构造函数、关键词private等
构造函数保证了对象的自动初始化,防止程序员遗忘;pvivate有利于信息的隐藏,防止误引用。

对于函数,对象可实现重入性。

3-6面向DSP的C/C++是如何实现类的?
C语言没有关键字class,但可用结构体来实现类。

通过typedef 实现指针的简洁定义以类名加后缀”_Handle”表示指针
Typedef STUD* STUD_Handle;
typedef struct
{ _iq As;
_iq Bs;
_iq Alpha;
_iq Beta;
void (*calc)();
} CLARKE;
typedef CLARKE *CLARKE_handle;
对象的初始化
C语言没有自动初始化的构造函数机制,每次定义对象时,可以用结构体的初始化来模拟构造函数,实现对象的初始化,作为简化,初始化值用宏定义来代替
#define CLARKE_DEFAULTS { 0, \
0, \
0, \
0, \
(void (*)(Uint32))clarke_calc }
TI的例程中,对象中所变量都作了初始化;防止漏写,所有类的定义都是变量在前,函数指针在后,要浪费内存。

必须初始化所有的变量后才能对必须有所指的函数指针做初始化。

3-7 TI算法模块C/C++规范
Module.h
typedef struct module_data {
int in, pastIn ,result; // Persistent data, coefficients etc.
void (*calc)() // Pointer to calculation function
} MODULE;
#define MODULE_DEF AULTS { 0,0,0, (void (*)(Uint32))module_calc
Module.c
void module_calc(MODULE *p)
{
// compute code
p->result = p->pastIn+p->In;
p->pastIn = p->In;
}
Client.c
MODULE mod = MODULE_DEFAULTS;
void somefunc(void)
{
int foo;
mod.in = 10; // coefficient configuration
mod.calc(&mod);
foo = mod.result; // Use result
}
3-8 以CLARKE变换\PARK变换为例,说明TI软件模块的规范。

解答:
1 首先,确定模块的输入输出,并增加对应的头文件进行定义类、定义缺省值即初始化化值,并定义函数原型。

typedef struct { _iq As; // Input: phase-a stator variable
_iq Bs; // Input: phase-b stator variable
_iq Alpha; // Output: stationary d-axis stator variable
_iq Beta; // Output: stationary q-axis stator variable
void (*calc)(); // Pointer to calculation function
} CLARKE;
typedef CLARKE *CLARKE_handle;
//Default initalizer for the CLARKE object.
#define CLARKE_DEFAULTS { 0, \
0, \
0, \
0, \
(void (*)(Uint32))clarke_calc }
//Prototypes for the functions in CLARKE.C
void clarke_calc(CLARKE_handle);
2 在C文件中,根据算法原理编写函数。

include "IQmathLib.h" // Include header for IQmath library
// Don't forget to set a proper GLOBAL_Q in "IQmathLib.h" file
#include "dmctype.h"
#include "clarke.h"
void clarke_calc(CLARKE *v)
{ v->Alpha = v->As;
v->Beta = _IQmpy((v->As + _IQmpy(_IQ(2),v->Bs)),_IQ(0.57735026918963));
// 1/sqrt(3) = 0.57735026918963
}
3-9 系统初始化即时钟模块和锁相环初始化
锁相环的目的是外部时钟允许较低的工作频率,片内通过锁相环倍频提供较高的系统时钟,这可有效降低系统对外部时钟的依赖和电磁干扰,提高系统启动和运行的可靠性,降低对硬
件设计的要求。

外设时钟控制寄存器PCLKCR
系统控制与外设状态寄存器SCSR
高速外设时钟定标寄存器HISPCP
低速外设时钟定标寄存器LOSPCP
锁相环倍频寄存器PLLCR
void InitSysCtrl(void) // 系统初始化子程序
{
EALLOW; //#define EALLOW asm (“ EALLOW”) 宏定义
SysCtrlRegs.PLLCR=0x000A; //初始化锁相环, OSCCLK=30MHz
// DIV=0x0A, CLKIN=30MHz*10/2=150 MHz
asm(“ NOP”);
asm(“ NOP”);
for (i=0; i<3000; i++) {;} //延时,等待锁相环稳定
SysCtrlRegs.HISPCP.all=0x0000; //HSPCLK= SYSCLKOUT=150MHz
SysCtrlRegs.LOSPCP.all=0x0002; //LSPCLK= SYSCLKOUT/4=37.5MHz
SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; //使能EVA
SysCtrlRegs.PCLKCR.bit.EVBENCLK=1; //使能EVB
SysCtrlRegs.PCLKCR.bit.SCIENCLKA=1; //使能SCI_A
// SysCtrlRegs.PCLKCR.bit.SCIENCLKB=1; //不用的外设不使能,
//以降低功耗
SysCtrlRegs.PCLKCR.bit.ADCENCLK=1; //使能ADC
EDIS; //#define EDIS asm (“ EDIS”) 宏定义
}
3-10 看门狗定时器
281x DSP内置了一个看门狗定时器(WDT), 用来监视DSP的运行状况。

当系统进入不可预知的状态而造成“死机”时,WD将产生一个复位操作,从而使DSP进入一个已知的起始位置重新运转。

如果CPU崩溃一旦8 位的看门狗计数器达到最大计数值,看门狗模块就产生一个512 个OSCCLK周期宽的脉冲,使DSP复位或中断被触发。

为防止计数器溢出,CPU必须周期性的向看门狗KEY寄存器写入0X55+0XAA序列,在复位之后(30 M外部时钟)3ms之内看门狗必须被启用或者禁止。

因为281x上电时看门狗是使能的,所以要尽快屏蔽,以免程序跑飞。

上电后SCSR寄存器中的WDOVERRIDE位为1,即允许WDCR寄存器中的WDDIS位被修改,所以不用先对WDOVERRIDE位操作就能修改WDDIS位。

8位WD计数寄存器: WDCNTR
WD复位钥匙寄存器: WDKEY
WD定时器控制寄存器: WDCR
WDKEY: 如果先写入0x55,在写入0xAA就会使WDCNTR清零。

写入任何其他数值则马上使DSP复位。

读操作返回的是WDCR寄存器的值。

void KickDog(void)
{
EALLOW;//允许CPU对寄存器进行操作
SysCtrlRegs.WDKEY = 0x0055;//防止WD溢出
SysCtrlRegs.WDKEY = 0x00AA;//
EDIS;//禁止CPU对寄存器进行操作
}
void DisableDog(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x0068;//屏蔽看门狗,以免程序跑飞
EDIS;
}
3-11 281x DSP有哪些32位CPU定时器?如何使用?
F281x 与240x相比,增加了三个32位CPU定时器0/1/2。

CPU定时器1和2保留给实时操作系统(RTOS),只有CPU定时器0留给用户使用。

配置CPU定时器就是设置周期寄存器,由给定的DSP时钟频率Freq(MHz)和定时器周期Period(µs)两个参数确定。

初始化后定时器处于停止状态。

必须在主程序中启动。

void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)
{
unsigned long temp;
Timer->CPUFreqInMHz = Freq; // Initialize timer period
Timer->PeriodInUSec = Period;
temp = (long) (Freq * Period); // 150MHz×100us=15000
Timer->RegsAddr->PRD.all = temp;
Timer->RegsAddr->TPR.all = 0; // Set pre-scale counter to divide by 1 Timer->RegsAddr->TPRH.all = 0;
// Initialize timer control register:
Timer->RegsAddr->TCR.bit.TSS = 1/0; // 1 = Stop timer, 0 = Start Timer
Timer->RegsAddr->TCR.bit.TRB = 1; // 1 = reload timer
Timer->RegsAddr->TCR.bit.SOFT = 1;
Timer->RegsAddr->TCR.bit.FREE = 1; // Timer Free Run
Timer->RegsAddr->TCR.bit.TIE = 1; // 1 = Enable Timer Interrupt
}
3-11 PIE中断控制
F281×共支持17个CPU级中断,包括一个NMI和16个可屏蔽中断(INT1~INT14,RTOSINT和DLOGINT)。

外设中断扩展模块(PIE)中多个中断源复用1个中断信号。

PIE支持多达96个中断源,其中8个中断源为一组,复用一个中断信号,总共有12个中断信号(INT1~INT12)PIE 的中断优先级由高到低分别是INT1-INT12,组内8个优先级由高到低的次序依次是INTx.1-INTx.8。

每个中断源都有相应的中断向量存放在RAM中,构成整个系统的中断向量表来存在中断服务程序的地址,中断向量表由256×16位的SRAM构成,每个中断矢量占用两个2个16位的地址空间。

F281×支持三个外部中断,INT1、INT2和INT13,其中INT13和NMI复用,每个外部中断可以使能/屏蔽、设定为上升/下降沿触发。

中断系统包括三个层次:外设级、PIE级和CPU级
例配置CPU定时器0产生定时中断,每次中断LED的状态切换一次(0/1)
外设中断的编程:
1)定义使用的外设中断矢量表。

相关文档
最新文档