DSP

DSP28335的一些笔记

2019-07-13 11:02发布

1.代码运行时间

代码运行时间,可以采用多种方式测量,它们之间是吻合的: Ø  示波器接IO引脚 Ø  CPU计数器 Ø  定时器0 Ø  EPWM模块

1.1示波器接IO引脚

将GPIO设置为通用IO口,输出模式,在待测试代码之前和之后,置位或者复位或者不断取反,即可在示波器上面读出代码运行时间; 对于一段运行时间不多的代码,示波器可能一出现一下就被覆盖掉了,测试这样的代码有两种方法: Ø  累计:在代码外面加一个比较大的数循环,从而得到累计时间,再除以这个大数,即得到真实值; Ø  循环:不断地执行这段代码,从而不断出现高低电平,这样就可以读到数据了;

1.2CPU计数器

菜单栏:Profile——Clock——Enable+View;即可在右下角看到计数器,计数代表的是CPU的计数个数,150MHZ情况下,乘以计数周期6.67ns即可得到真实值! 双击该计数值即可清零!

1.3定时器0

设置完分频数之后,要将周期设置到很大,这样可以避免跨越周期的计数错误,比如如果只设置3000,计数到1000,你无法判断3000*N+2000中的N为多少;如果分频数设置过大,也会造成量化误差过大;

1.4EPWM模块

该模块同样存在定时器0的相似问题,一个增减计数,如果周期时1000,计数到800,就难以判断是在上升沿还是下降沿;一个办法是在此计数值读取之后,执行几句代码再读取一次,就可以求取斜率,从而判断上升下降沿! 其他利用DSP内部模块测量,都与定时器和EPWM模块类似,存在的问题也类似!

2.CMD与MAP文件

2.1内存结构

所有的程序和数据都必须在内存中运行,28335的各种内存如下表所示: 内存类型 容量K 含义 RAM 34 掉电会丢失,速度比FLASH快 FLASH 256 烧写程序和数据使用 ROM 1 很少使用 PF 0-3 数据空间,外设寄存器 PIE   中断向量表

2.2CMD分配

Ø  H文件里面,通过结构体和共用体,将外设0-3的相关寄存器全部定义为结构体变量;C文件里面,使用#pragma DATA_SECTION(X,Y)指定这些结构体X分配到内存Y中;然后在CMD中,将外设空间分块,再将Y指定分配到具体物理地址块中:DEV_EMU     : origin =0x000880, length = 0x000180 。这就是PF0-3的内存映射;这一部分是不变的,芯片型号一定,这些内容就定了,PIE向量表也是这样分配 Ø  我们可以分配的就是RAM和FLASH,可以通过指定#pragma DATA_SECTION()或者#pragma CODE_SECTION()将指定代码或者数据指定分配到某个地址,如果不指定,就由编译器分配;某些算法要求指定,比如FFT; Ø  以.reset为特征的,以点开始的是编译后的一些量,比如全局变量,这些可以查资料,自己没怎么关注!

2.3MAP

编译之后,File——Open,在debug里面,可以打开Map文件,李曼包含了编译后的物理内存分配信息:

这一块是代表内存分配,我们将所有的内存划分的小块,包括程序空间0和数据空间1;从左到右分别是:小块的属性(0-程序,1-数据)和名称,起始地址,长度,已经使用的空间,剩余的空间,地址的属性;

这个讲我们分配的段的物理地址,刚才那个是讲物理地址分块,现在这个是映射的意思。

这些是全局变量的地址;map文件就大概由这三类组成。查看map文件,可以看到剩余多少空间,以及空间不够合理的时候的优化等等!

2.4小结

CMD和map就主要管理内存!

3.烧写运行与在线仿真

3.1RAM在线仿真

编译完成之后,直接file——load program进去之后就可以跑了; 它测试的时间会比烧写到flash里面快很多,实际应用都是烧写,所以这种比较好像并没有意义,真正有意义的是下面两种;

3.2FLASH烧写运行

从RAM在线运行到flash烧写运行,需要改的地方: Ø  主函数里面:使用MemCopy函数将代码运行地址从RAM拷到flash里面;初始化FLASH,比如使能管道,可以提升速度,另外根据最高频率,设置最快翻页和等待时间:
Ø  CMD文件中:将指定段分配到具体的物理位置:

Ø  另外,不能再flash内部初始化flash,就是不能自己对自己操作,所以有了CMD文件里面的load出来,同时在源文件里面要对这个块进行指定: #pragma CODE_SECTION(InitFlash, "ramfuncs"); Ø  总结一下:其实程序真正是到load到ram里面,还是烧写到FLASH里面,是CCS里面点击不同按钮操作来决定的。上述的三个步骤只是保证烧写到flash里面可以正常运行而已:需要初始化flash,但是不能自给初始化自己,所以要将初始化代码,先指定一个段,然后再CMD中将该段设置为烧写后load。同时在主函数里面执行将该段代码复制出来再运行;应该就是这个逻辑!

3.3FLASH烧写、LOAD运行

Ø  与上一节烧写类似,上一节可以将FLASH初始化函数load出来运行,其他的load出来运行的步骤也是一样:指定代码分配;主函数里面复制代码,执行代码;CMD将指定的块分配到具体物理空间; Ø  Load运行主要用于某些对时间要求高的场合,烧写之后,如果load出来,速度大概可以达到百分之八十。应用场合包括,某些中断里面的反复做的控制等

3.4疑问

Ø  MemCopy函数中使用到的变量,举例: MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd, &RamfuncsRunStart); 这些变量的定义: extern Uint16RamfuncsLoadStart; 但是并没有初始化,这一句也不知道是在这里定义还是只是在这里引用。我理解的是它是在编译器内部定义了的,这里只是一个引用申明:x的其实地址就是xLoadStart,以此类推。因为我自己使用的段,也可以这样使用,说明是编译器在管理;

4.外设

4.1ePWM

6路12个PWM,也可以配置为高精度PWM(这个自己没用过)。可用于三电平逆变器的控制,12路既可以对称控制,也可以单独控制;控制单元主要分为七个模块: 时基模块:确定计数周期,计数模式(上、下、上下); 计数比较模块:计数比较寄存器; 动作模块:配置计数比较相匹配的模式(与周期相等,与零相等等),以及动作类型(置位、复位、翻转); 死区模块:产生对称或者独立波形,死区设置; 斩波和错误联防:这两个模块没有使用过; 事件触发模块:计数值等于某个设定值后触发指定动作,可用于触发ADC,从而在中断里面实现采样控制;

4.2eCAP

该模块是复用的:6个既可以用于PWM产生——只能产生独立的PWM,也可以用于捕获上升沿或者下降沿;

4.3ADC

4.3.1采样

Ø  电流采样,主要采用CT进行;电压采样,既可以用PT,也可以用一串电阻串联,从中某个电阻取电压; Ø  电流采样之后,一般也要经过一个电阻,转化为电压信号,再到后面进行处理

4.3.2调理

Ø  最基本的电压跟随器,解除负载效应; Ø  使用二极管限幅,因为调理之后就要输入ADC模块,该模块有幅值限制; Ø  对于交流量,可能会使用一个加法电路,叠加一个直流量,将信号提到ADC接受的范围内; Ø  使用电容等构成滤波电路,这个截止频率很大,用于稳压,滤掉极高频分量;

4.3.3ADC

Ø  主要看两个指标:转换精度——用转换位数来表示,比如12位代表最大值3V只能转换到4095,如果位数增加,转换精度则增加;转换速度——这个可以配置,自己没有亲自动手配置过; Ø  ADC有多种转换方法,在数字电路里面有详细,但是在DSP里面只需要封装好,不需要去管这些内部细节; Ø  ADC模块可以配置为单独两组8个,也可以级联为一组16个;可配置转换数量,转换储存位置;可触发中断; Ø  有空可以自己动手写一写这个模块的代码!