定点处理器对浮点数的处理:
1> 定义变量为浮点型(float,double),用C语言抹平定点处理器和浮点处理器的区别,但是程序的代码庞大,运算速度也慢。
2> 放大若干倍表示小数。比如要表示精度为0.01的变量,放大100倍去运算,运算完成后再转化。但是这个做法比较僵硬,如要将上面的变量重新定义成0.001精度,又需要放大1000倍,且要重新编写整个程序,考虑溢出等问题。
3> 定标法:Q格式:通过假定小数点位于哪一位的右侧,从而确定小数的精度。
Q0:小数点在第0位的后面,即我们一般采用的方法
Q15 小数点在第15位的后面,0~14位都是小数位。
转化公式:Q=(int)(F×pow(2,q))
F=(float)(Q×pow(2,-q))
Q格式的运算
1> 定点加减法:须转换成相同的Q格式才能加减
2> 定点乘法:不同Q格式的数据相乘,相当于Q值相加
3> 定点除法:不同Q格式的数据相除,相当于Q值相减
4> 定点左移:左移相当于Q值增加
5> 定点右移:右移相当于Q减少
Q格式的应用格式
实际应用中,浮点运算大都时候都是既有整数部分,也有小数部分的。所以要选择一个适当的定标格式才能更好的处理运算。一般用如下两种方法:
1> 使用时使用适中的定标,既可以表示一定的整数复位也可以表示小数复位,如对于2812的32位系统,使用Q15格式,可表示-65536.0~65535.999969482区间内的数据。
2> 全部采用小数,这样因为小数之间相乘永远是小数,永远不会溢出。取一个极限最大值(最好使用2的n次幂),转换成x/Max的小数(如果Max是取的2的n次幂,就可以使用移位代替除法)。
5. Ti的qmath.lib库说明:
见TI的文档C28x IQMath Library (SPRC087a).zip的详细说明。
TI公司给出了一个Q格式的数学库qmath.lib
注意Q格式函数使用的时序和空间要求,尽量避重就轻。
来看个具体的例子吧
#define maxf 120; //整数默认的是Q0;
f=50.01 //想表示的频率
unsigned int f;
f=((unsigned long )5001<<15)/(maxf*100) //先移位扩大100倍,转换格式之后移位15位后结果就是想要的
可以得到f=13656
DSP2812的启动过程
a)程序硬件复位或者软件复位
b)判断mp/mc是否为0,微计算机模式(为1,当为微处理器模式时,2812内部的bootrom被禁止,通过zone7从外部调引导程序启动。这个比较适合flash引导的启动。)
c)为0则从boot rom启动,否则从外部启动(0x3F FC00)
d)到boot rom的0x3F FC00处取出复位向量,跳到boot函数:2812有一块flash地址从0x3F F000-0x3F FFFF在出厂时ti已经固化好了引导程序initboot:Iniboot函数判断几个GPIO引脚来判断使用哪一种引导模式,比如flash boot模式,检测SPICLKA,SCITXA,GPIO34的电平,当都为高电平时表明是片内flash boot模式,那么initboot执行完后跳转到0x3F 7FF6处,这个时候指令占据两个字节,刚好在代码模块之前。一定是是跳转指令才行。。。)
e)采集io管脚状态,确定启动模式。2812提供几种启动模式:
SCITXDA(GPIOF4) MDXA(GPIOF12) SPISTEA(GPIOF3) SPICLK(GPIOF2)
1 x x x FLASH启动
0 1 x x SPI启动
0 0 1 1 SCI启动
0 0 0 0 PARALLEL启动
f)根据io状态选择boot方式
g)如果是flash,程序退出boot函数,跳转到0x3F 7FF6(codestart)
h)取出跳转指令,跳转到自己的指定地址或者C初始化的入口_C_INT00(0x3F6000)处(DSP281x_CodeStartBranch.asm中)
i)在C初始化的入口_C_INT00对一些变量,堆栈和寄存器进行必要的设置,该函数在c的库函数内(RTS Library)
j)进入main函数(0x3F658E,这个地址不是固定的。但是在flash里面。)
注:根据TI中文手册总结如上。。。。。
3F8238
_c_int00: 这个地址是我一次程序运行观测到的。这个地址会随时的变化,但是总在3F8000到3FA 000 之间,也就是在H0 SRAM中间。
具体的可以参照TMS320F2812的存储器的空间。。
CMD文件的编写
首先简要介绍:
链接命令文件(.cmd文件)通过段定位控制命令,分配程序代码和数据运行存储空间。
链接命令文件有两个重要的指令:MEMORY和SECTIONS。
(1)、MEMORY
指出目标系统中物理上存在的存储空间的范围,即可供程序使用的存储空间范围。在默认状态下,PAGE0代表程序空间,PAGE1代表数据空间。
(2)、SECTIONS
1)、描述输入段如何组合成输出段。
2)、定义可执行程序的输出段。
3)、指出输出段存放在存储空间中的位置。
4)、允许重命名输出段。
.cmd文件编写的目的 确定程序和数椐的装载运行空间,校验数据和程序代码的长度,定义输入/输出文件,安排系统中可用的存储器,程序段、数据段、堆栈以及复位向量和中断向量的地址空间。
链接命令文件通过段定位控制命令,分配程序代码空间、数据代码空间、程序运行空间、堆栈空间。
.CMD文件命令格式
Ø MEMORY:定义目标板物理存储空间分配,默认状态下,PAGE0为程序空间, PAGE1为数据空间。
Ø SECTIONS:定义程序连接过程中各个输入段与输出段之间的关系,并给出输出段地址。
① 给出输入段组合成输出段的方式;
② 定义可执行程序的输出段;
③ 指出输出段存放在存储空间中的位置;
④ 允许重命名输出段。
下面分析一个简单的,helloword 经典的CMD
MEMORY
{
PAGE 0 :
PROG : origin = 0x3f8000, length = 0x0023fff
RESET : origin = 0x0, length = 0x3f
PAGE 1 :
DATA : origin = 0x008000, length = 0x001fff
}
SECTIONS
{
.reset : load = RESET, PAGE = 0
.text : load = PROG, PAGE = 0
.cinit : load = PROG, PAGE = 0
.vectors : load = PROG, PAGE = 0
.stack : load = DATA, PAGE = 1
.data : load = DATA, PAGE = 1
.ebss : load = DATA, PAGE = 1
.bss : load = DATA, PAGE = 1
.econst : load = DATA, PAGE = 1
.const : load = DATA, PAGE = 1
.cio : load = DATA, PAGE = 1
}
说明:
.text: ;程序代码在第0页
.reset ;复位在第0页
.cinit: ;初始化变量在第0页
.pinit: ;初始化参数在第0页
.vectors :一些向量在第0页
.bss: ;非初始化变量在第1页
.ebss ;初始化变量在第一页。
.const: ;常数在第1页
.
.sysmem: ;系统的东东,初始化一些东西,硬件的。
.cio: ;C语言I/O调用在第1页
.stack: ;堆栈在第1页 |