数字信号处理
信号:信号是信息的载体,以某种函数的形式传递信息。这个函数可以是时间域、频率域或其它域,但最基础的域是时域。
信号的分类:
周期信号 / 非周期信号
确定信号 / 随机信号
能量信号 / 功率信号
连续时间信号 / 离散时间信号 / 数字信号
1-D 信号:单个独立变量的一维函数, e.g. 语音信号。
2-D 信号:两个独立变量的二维函数, e.g. 图像信号。
M-D 信号:多个独立变量的多维函数, e.g. 彩 {MOD}视频信号(RGB) 。
数字信号处理是用数值计算的方法,完成对信号的处理。因此处理的实质是“运算”,运算的基本单元是延时器、乘法器和加法器。
模拟信号数字化处理的系统框架:
前置滤波器:将输入信号xa(t)中高于某一频率(称折叠频率,等于抽样频率的一半)的分量加以滤除。
A/D变换器:在A/D变换器中每隔T秒(抽样周期)取出一次xa(t)的幅度,抽样后的信号称为离散信号。
数字信号处理器:按照预定要求,在处理器中将信号序列x(n)进行加工处理得到输出信号y(n)。
D/A变换器:由一个二进制码流产生一个阶梯波形,是形成模拟信号的第一步。
模拟滤波器:把阶梯波形平滑成预期的模拟信号;以滤除掉不需要的高频分量,生成所需的模拟信号ya(t)。
以傅里叶变换为基础的“经典”处理方法,主要包括:
(1)离散傅里叶变换及其快速算法。
(2)滤波理论(线性时不变离散时间系统,用于分离相加性组合的信号,要求信号频谱占据不同的频段)。
MATLAB基础及在DSP中的应用
MATLAB即Matrix Laboratory 矩阵实验室的意思,matlab语言是由美国的Clever Moler博士于1980年开发的。
MATLAB是一种直译式的高级语言,比其它程序设计语言容易。
MATLAB语言不受计算机硬件的影响,286以上的计算机都可以使用。
MATLAB提供了丰富的矩阵运算处理功能,是基于矩阵运算的处理工具。
变量----矩阵,运算----矩阵的运算
一些简单的例子:
用简短命令计算并绘制在 0=
x=linspace(0,6)
y1=sin(2*x),y2=sin(x.^2),y3=(sin(x)).^2; 符号x和^之间要加上一个. <-----
plot(x,y1,x, y2,x, y3)
求1到100的和:
s = 0;
for n = 1:100 % for n=1:1:100 also is ok
s = s + n;
end
Matlab的变量命名规则:
(1)以字母开头,后面可跟字母、数字和下短线;
(2)大小写字母有区别;
(3)不超过31个字符。
M文件:就是用Mat lab语言编写的,可在Matlab里运行的程序。M文件有两大类:命令文件和函数文件。
M命令文件(脚本文件):只是一些命令行的组合。而且其中的所有变量也成为工作区的一部分。
M函数文件:格式:function 输出变量=函数名(输入变量)。
函数文件注意的几个地方:
(a)输出变量多于一个时,要用方括号;
(b)输入、输出变量多于一个时,要用逗号隔开;
(c)必须以函数名存盘。
Matlab绘制曲线:
fplot:用于绘制一元函数曲线。
fplot (‘fun’ ,[a , b])示绘制区间[a ,b]上函数 y=fun 的图形。
Matlab求导数:
diff(f,x):f(x)对x求导
diff(f,x,n):f(x)对x求n阶导
一个求导的例子:
syms x
y = 3*x^3 - exp(x)/2 + 1
dy = diff(y,x,1)
pretty(dy)
Matlab求驻点:
求 y=f(x) 驻点命令格式为:x= solve(‘f(x)’)
Matlab求特征值和特征向量:
(1)E=eig(A) 求矩阵A的全部特征值,构成向量E。
(2)[V,D]=eig(A) 求矩阵A的全部特征值,构成对角阵D,并求A的特征向量构成V的列向量。
(3)[V,D]=eig(A,'nobalance') 与第2种格式类似,但第2种格式中先对A作相似变换后求矩阵A的特征值和特征向量,而格式3直接求矩阵A的特征值和特征向量。
例 : 用3种不同的格式求A的特征值和特征向量。
命令如下:
A=[1,2,2;1,-1,1;4,-12,1];
E=eig(A)
[V,D]=eig(A)
[V,D]=eig(A,'nobalance')
Matlab产生信号波形:
三种方法:
1.使用funtool 图形化函数计算器
可以自定义自变量x变化范围,缺省为
[-2pi,2pi], a为自由参数.
1.5sin(x)、5exp(-x)、sin(x)/x、sqrt(a*x)
2.用信号处理工具箱(Signal Processing toolbox)
3.向量表示法
t= -10:0.5:10 ;
f=sin(t)./t ;
plot(t,f);
title(‘f(t)=Sa(t)’);
xlabel(‘t’); axis([-10,10,-0.4,1.1]);
用以下程序可产生正弦波:
t=0:0.001:50; y=sin(2*pi*50*t); plot(t(1:50),y(1:50));
用以下程序可产生加入随机噪声的正弦波:
t=0:0.001:50; y=sin(2*pi*50*t); s=y+randn(size(t)); plot(t(1:50),s(1:50));
用以下程序可产生周期方波:
t=0:0.001:2.5; y=square(2*pi*30*t); plot(t(1:50),y(1:50));
用以下程序可产生周期锯齿波:
t=0:0.001:2.5; y=sawtooth(2*pi*30*t); plot(t,y);
数字信号图像处理
图像:是对客观对象的一种相似性的描述或写真,它包含了被描述或写真对象的信息,是人们最主要的信息源。
图(picture):是物体反射或透射光的分布,它是客观存在的
像(Image):是人的视觉系统所接收的图在人的大脑中所形成的印象和认识
模拟图像:也称光学图像,是指空间坐标和明暗程度连续变化的,计算机无法直接处理的图像,它属于可见图像。
数字图像:是指
能被计算机存储、处理和使用的图像,是空间坐标和灰度均不连续,用离散数字表示的图像。
图像数字化:
(1) 采样(空间离散):空间上连续的图像变化成离散点的操作成为采样,实际上是空间坐标(x,y)的数字化,即按一定的间隔(△x, △ y)将图像划分M行×N列的网格。采样网格的大小关系到图像的质量及所包含的信息。(图像的大小)
(2)量化(灰度离散):灰度等级越高,图片质量越好。(包含 {MOD}彩数目)
图像的类型:
1.按
灰度值可以分为
二值图像和
多值图像。
二值图像:每个像素灰度由0或1构成
多值图像:每个象素灰度由0~2n之间的数表示(n>1)
2. 按
波段量可分为单波段、彩 {MOD}或多波段数字图像。
Matlab图像的读取与显式:
A = imread(filename,fmt)
[X,map] = imread(filename,fmt)
x:像素颜 {MOD}值 map: {MOD}谱
load filename:都系统自带的图片
imshow football.jpg
imshow(X,map)
imshow(uint8(X))
imview('trees.tif')
figure :创建一个新的窗口
彩 {MOD}图像的显式:(调整RGB的显式顺序)
tu=imread('football.jpg');
imshow(tu)
imshow(tu(:,:,[1 2 3]))
imshow(tu(:,:,[3 2 1]))
imshow(tu(:,:,[1 3 2]))
灰度图像的显式:
I=imread('pout.tif');
figure,imshow(I)
figure,imshow(I,[1 200])
figure,imshow(I,2)
figure,imshow(I,8)
figure,imshow(I,256)
调整图像大小:使用truesize
figure,imshow(bw),truesize([100 100])
figure,imshow(bw,'notruesize')
图像显示中逻辑操作符的使用(常用于二值图像)
bw=imread('circbw.tif');
imshow(bw)
figure,imshow(~bw) 每个像素值取反,黑白颠倒
显式多帧图像(实现动画):
语法
mov = immovie(X,map)
mov = immovie(RGB)
通常和movie(mov)联合使用
一个例子:
axis equal
M=moviein(16)
set(gca,'NextPlot','replacechildren')
for j=1:100
plot(fft(eye(j+16)))
M(:,j)=getframe;
end
Movie(M,2)%指定放映几次
图像的几何运算:
1.图像大小的调整:imresize
语法
B = imresize(A,m) n:放大的倍数
B = imresize(A,m,method)
B = imresize(A,[mrows ncols],method)
B = imresize(...,method,n)
B = imresize(...,method,h)
imresize()
X3 = imresize(X,4); 放大4倍
figure
imshow(X3,[]);
2.图像旋转:imrotate
语法
B = imrotate(A,angle)
B = imrotate(A,angle,method)
A>0逆时针选择一个角度angle,反之顺时针
subplot(222);将窗口分为2行2列4块,选择第2块。
3.图像裁剪:imcrop
基本语法
J= imcrop
J = imcrop(I)
J = imcrop(X,map)
4.图像亮度的调整:
线性处理:
tu1=(double(tu))*1.5+30; 对tu进行运算处理,从而调整亮度
figure,imshow(uint8(tu1))
用imadjust来进行调整:
tu= imadjust(i,[low_in; high_in],[low_out; high_out])
LI=imadjust(tu,[0.3 0.7],[0,1]);
figure,imshow(LI)
5.直方图均衡化处理:histeq
hm=histeq(m);将原图m均衡化处理。
hist(double(hm)); 显式均衡化处理后的直方图。
6.图像中斑点的去除:
I=imread('eight.tif');
J=imnoise(I,'salt & pepper',0.06);
subplot(221),imshow(I),title('原图')
subplot(222),imshow(J),title('含斑点的图')
H = fspecial('average');
am =
imfilter(J,H);
subplot(223),imshow(am),title('均值')
zm=medfilt2(J);%中值
subplot(224),imshow(zm),title('中值')
7.图像的轮廓:语法
imcontour(I,N)
I = imread('cameraman.tif');
imcontour(I,1)
8.图像的边界检测:
语法:
edge(I)
I=imread('coins.png');
BW1 = edge(I,'roberts');
BW2 = edge(I,'sobel');
BW3 = edge(I,'log');
figure
subplot(221),imshow(I),title('原图')
subplot(222),imshow(BW1),title('roberts算子')
subplot(223),imshow(BW2),title('sobel算子')
subplot(224),imshow(BW3),title('laplacian算子')
9.图像间的运算:
两个图像合并:
I=imread(‘rice.tif');
J=imread('cameraman.tif');
k=
imadd(I,J);
10.特定区域的增强处理:
I = imread('pout.tif');
imshow(I)
BW = roipoly(I);
H = fspecial('unsharp');
J =
roifilt2(H,I,BW);
figure, imshow(J)
11.特定区域的填充:
load trees
I=ind2gray(X,map);
figure,imshow(I)
J=
roifill;
figure,imshow(J)
55系列的DSP基础
DSP: 数字信号处理,用数学方法处理数字化了的信号。
经典数字处理方法:
时域:信号滤波FIR、IIR
频域:频谱分析FFT
数字信号处理特点:
ΣAi×Xi
高速实时
DSP特点:多总线,流水线执行
德州仪器(TI)的三大DSP系列:
TMS320C2000™:控制优化
TMS320C5000™:低功耗
TMS320C6000™:高性能
DAVINCI技术是TI推出的新一代视频、图像、语音和音频解决方案的统称。
C55x根据功能的不同将CPU分为4个单元:
指令缓冲单元(I):由指令缓冲队列IBQ(Instruction Buffer Queue)和指令译码器组成。
程序流程单元(P):由程序地址产生电路和寄存器组构成。
地址流程单元(A):由数据地址产生电路、算术逻辑电路和寄存器组构成。
数据计算单元(D):由移位器、算术逻辑电路、乘法累加器和寄存器组构成。D单元包含了CPU的主要运算部件。
读程序地址总线(PAB)上传送24位的程序代码地址,由
读程序数据总线(PB)将32位的程序代码送入指令缓冲单元I进行译码。
指令流水线:
C55x CPU采用指令流水线工作方式,C55x的指令流水线包括两个阶段:
第一阶段是
取流水线,即从内存中取出32位的指令包,放入指令缓冲队(IBQ)中,然后为流水线的第二阶段提供48位的指令包。
流水线的第一阶段(取流水线):
其中PF1表示向存储器提供的程序地址,PF2表示等待存储器的响应,F表示从存储器取一个指令包并放入指令缓冲队列中,PD表示对指令缓冲队列中的指令预解码(确定指令的起始和结束位置;确定并行指令)。
第二阶段是指
执行流水线,这部分的功能是对指令进行解码,完成数据的存取和计算。
CCS与DSP开发基础
CCS的两种工作模式:
1.软件仿真器模式:可以脱离DSP芯片,在PC机上模拟DSP的指令集和工作机制,主要用于前期算法实现和调试。
2.硬件在线编程模式:可以实时运行在DSP芯片上,与硬件开发板相结合在线编程和调试应用程序。
使用CCS软件要用到的文件类型介绍:
*.cmd:链接命令文件。
*.obj —— 由源文件编译或汇编后所生成的目标文件;
*.out —— 完成编译、汇编、链接后所形成的可执行文件,可在CCS监控下调试和执行;
*.wks — 工作空间文件,可用来记录工作环境的设置信息;
*.cdb — CCS的配置数据库文件,是使用DSP/BIOS API模块所必须的。当保存配置文件时,将产生链接器命令文件(*cfg.cmd)、头文件(*cfg.h54)和汇编语言源文件(*cfg.s54)。
CCS窗口中的两个目录文件夹:
1、“GEL files”文件夹,用来修改和保存用户所设置的开发环境,包括窗口和工具条的位置以及自动打开窗口的设置等。
2、“Project”文件夹包含了工程项目中所有的文件库和文件。在一个工程项目中,文件被分成几个不同的库进行管理。
装载文件:选择“File”菜单中的“Load Program(装载程序)”命令,弹出“Load Program(装载程序)”对话框。
实时运行:CCS提供了4中实时运行操作:执行程序、暂停执行、动画执行、自由执行。
实时数据交换:
RTDX由目标系统和主机两部分组成,小的RTDX库函数在目标系统DSP上运行。开发者通过调用RTDX软件库的API函数将数据输入或输出目标系统的DSP,库函数通过在片仿真硬件和增强型JTAG接口将数据输入或输出主机平台,数据在DSP应用程序运行时实时传送给主机。
在主机平台上,RTDX库函数与CCS一道协同工作。显示和分析工具可以通过COM API与RTDX通信,从而获取目标系统数据,或将数据发送给DSP应用例程。
RTDX适合于各种控制、伺服和音频应用。
DSP编程基础
C54x的程序设计语言可以选择:汇编语言和C语言。
汇编语言的优点:程序执行效率高,硬件定时准确;
缺点:程序不够直观,可移植性和可维护性差
C语言特点:可移植性和可维护性好
C54x C与ANSI C:
C54x C编译器支持美国国家标准委员会(American Nation Standards Institute ,ANSI)开发的C语言标准。
C54x C与ANSI C的相同点:
概括地讲,C54x C继承了ANSI C的大部分基本特征,只要与硬件不是特别相关的部分都是它们的相同点。
C54x C与ANSI C的不同点:
面向PC机的ANSI C对实时性要求不高,而 C54x C 的编程对象C54x DSP工作于实时性处理场合,对于处理时间有比较严格的实时性要求。
C54x的C语言数据类型及其表示范围:
由于C54x是一种16位定点DSP,所处理的数据一般都是以字(word ,16bit)为单位,而对于小于16位的数据的运算,需要配合逻辑和以为运算来完成。
C54x编译器将16位数据定义成最短的数据表示类型,如signed char, char, unsigned char, short, signed short, int, signed int, enum, unsigned int,* 指针都是16位数据,与ANSI C有较大区别。
对于16位表示范围不够的数据,C54x编译器安排了32位的数据类型,32位的数据包括long, signed long, float, double, long double。这也是表示范围最大的一种数据类型。与ANSI C有较大区别。
54x的C语言特有数据类型:
(1) 地址变量:对某一个存储单元进行访问,这个存储单元可能是普通的数据存储器单元,也可能是存储器映像寄存器。 所谓的地址变量实际上就是指定了具体地址的指针变量。
加上 volatile 关键字,防止编译器将其优化掉。
volatile short *mcbsp0_drr10=0x10;
(2) I/O端口变量:C54x的存储空间有三个:程序存储空间、数据存储空间和I/O空间。为了实现C访问DSP的I/O空间,C54x C语言规定了一种I/O端口变量,对这些端口变量的访问就是对I/O空间的访问。
格式:ioport 数据类型 porthex_num;
其中, ioport:端口变量定义关键字;数据类型:只能是char, short, int, unsigned等16位类型;hex_num:该I/O端口的16进制表示的端口地址。
例子:ioport short port100; //定义了一个端口变量,端口地址是100h
(3) 寄存器变量:DSP的C语言扩展了寄存器变量。在一个C函数内部最多可以使用两个寄存器变量,编译器在编译这两个寄存器变量时用AR6和AR7这两个辅助寄存器分别做了对应:
AR6被赋给第一个寄存器变量
AR7被赋给了第二个寄存器变量
寄存器变量的定义格式: register type AR6 或 register type AR7
DSP C语言关于变量的特殊规定:
DSP的C语言规定:没有显式初始化的变量仍保持未初始化状态;
DSP的C语言规定,有符号数的右移等价于算术右移,即右移时符号位会扩展,这样右移一位相当于除2;
DSP的C语言做了如下规定:余数的符号与被除数的符号保持一致
10/-3==3, 10%-3==1
-10/3==-3, -10%3==-1
浮点数转换到整数时,DSP的C语言采用朝0截止的方式,即简单地去掉分数部分。
(标准C可以选择是向下截取——取比该浮点数小的最大整数,向上截取——取比该浮点数大的最小整数)
TI公司的DSP C语言规定取最后一个字符有效:‘abc’==‘c’
C54x C语言编程
1.C54x C语言开发的段结构:
C编译器对C语言源程序进行编译后产生汇编程序,汇编程序再经过汇编将成为COFF格式的目标文件,该文件将包含七个可以进行重新定位的代码和数据段,他们是:
已初始化的段:
(1) .text段,包含了可执行代码。
(2) .cinit段,包含明显初始化的静态变量和全局变量。 DSP的C语言全局变量和静态变量,其存储单元定义在 段.bss 中,
需要显式初始化的值存放在段.cinit中。
(3) .const段,包含字符串常量和全局变量。
(4) .switch段,包含大型switch的跳转表。
未初始化的段:
(1) .bss段,包含了未初始化的全局变量和静态变量。
(2) .stack段,定义软件堆栈。
(3) .system段,为动态存储器函数malloc、calloc、realloc(这些函数由运行支持库提供)分配空间。
自定义段:
利用progma伪指令来产生其他的自定义段。
① CODE_SECTION
pragma
例子:# pragma CODE_SECTION (symbol,“section name”)
这里 ,section name代表了要产生的段名,而symbol代表了要汇编到该段的符号(如函数名)。
②DATA_SECTION
pragma
例子:# pragma DATA_SECTION (symbol,“section name”)
这里 ,section name代表了要产生的段名,而symbol代表了要汇编到该段的符号(如变量名)。
2.段的存储器定位
段在链接时必须指定相应的存储位置。
已初始化的段放在ROM 或者 RAM中;
未初始化的段放在RAM中;
自定义CODE_SECTION段放在ROM或者RAM中, DATA_SECTION段放在RAM中。
DSP编译器支持两种存储器模式:
小存储器模式(little endian):编译器默认的存储器模式。这要求.bss在
128个字(一个数据页)范围内,这样编译器在编译成汇编时,不需要修改DP的值,程序代码简单,运算效率高。
大存储器模式(big endian):
对.bss大小没有限制,访问变量 时需要首先确定DP值,这将增加指令访问周期。
C54x C语言中 寄存器值的保存分成两种基本类型,即
入口保存和
调用保存。
C54x C语言开发的标识符命名约定和混合语言编程:
--> 汇编程序中定义一个标识符_x,C语言程序调用是x,而不是_x。
C54 C语言中断处理函数的实现:2种方法
1. c_intd 函数:C编译器约定,任何具有名为c_intd(d为0~9)的函数都被假定为一个中断程序。
2. interrupt 函数:
void interrupt isr()
{
…
}
中断函数的几点说明:
1)中断函数的返回类型必须是void类型,并且不能有参数。
2)对中断函数,其寄存器的保护不使用入口或调用保护规则;
3)在返回时中断函数使用RETI。
4)
中断函数不能被普通C代码之间调用
5)C编译器规定进入中断函数时,要求SP的内容是偶数;
6)如果屏蔽中断时,用户可以使用内嵌汇编语句来修改IMR使能或禁止指定的中断。
7)一个中断程序可以处理一个或多个中断;
8)中断处理和具体某种中断的联系,由中断向量来表明
9)在汇编语言中,访问中断处理函数是,
加上“_”
TI公司提供两种形式的
运行支持库(run-time-support library):
目标代码:rts.lib
源代码:rts.src
CCS工程中的文件:
1. *.cmd :用来分配存储空间。
2. C语言系统库rts55x.lib。系统库包含了编译器提供的所有功能,初始化C语言环境(入口地址是_c_int0),设置堆栈,标准C的函数库。
3. *.map:存储器映射文件