DSP算法大全C语言版本
- 格式:doc
- 大小:18.00 KB
- 文档页数:1
一个简单的dsp C语言例子开发平台: CCS集成开发环境通过这个简单的例子, 可以大致了解用C语言开发dsp程序的原理。
程序要求: 用C语言编写产生正弦调幅波信号的源程序;正弦调幅波的公式在离散域中的表示:y(n) = (1 + M*sin(2 * PI * fb / fs * n)) * sin(2 * PI * fa / fs * n);编写文件1.sin_am.c#include<stdio.h>#include<math.h>#define TRUE 1#define pi 3.1415926536int y[500],i;float M;void main(){puts("amplitude modulation sinewave example started.\n");M = 50;for(i = 0; i < 500; i++)y[i]= 0;while(TRUE){for(i = 0; i < 500; i++)y[i]=(int)((1 + M / 100 * sin(i * 2 * pi * 20 / 4000))* sin(i * 2 * pi * 200 / 4000)* 16384);puts("program end");}}2.sin_am_v.asm (reset vector file).title "sin_am_v.asm".sect ".vectors".ref _c_int00RESET:B _c_int00.end..3.sin_am.cmdsin_am.objsin_am_v.obj-m sin_am.map-o sin_am.outMEMORY{PAGE 0:EPROG: origin = 0x1400, len = 0x7c00 VECT: origin = 0xff80, len = 0x80PAGE 1:USERREGS: origin = 0x60, len = 0x1c IDATA: origin = 0x80, len = 0x3000 }SECTIONS{.vectors:>VECT PAGE 0.text:>EPROG PAGE 0.cinit:>EPROG PAGE 0.bss:>IDATA PAGE 1.const:>IDATA PAGE 1.switch:>IDATA PAGE 1.system:>IDATA PAGE 1.stack:>IDATA PAGE 1}"*.cmd"文件说明:链接命令文件是实现对段的存储空间位置的定位, C语言程序中常用已初始化和未初始化段如下:已初始化段包括:.init 存放C程序中的变量的初值和常量, 放在ROM和RAM 中均可, 一般属于PAGE 0.const 存放C程序中的字符常量、浮点常量和用const声明的常量, 放在ROM和RAM中均可, 一般属于PAGE 1.text 存放C程序代码, 放在ROM和RAM中均可, 一般属于PAGE 0.switch 存放C程序中的语句的跳针表, 放在ROM和RAM中均可, 一般属于PAGE 0未初始化段包括:.bss 为C程序中的全局和静态变量保留存储空间, 一般存放于RAM中, 属于PAGE 1.stack 为C程序系统堆栈保留存储空间, 用于保存返回地址、函数间的参数传递、存储局部变量和保存中间结果, 一般存放于RAM中, 属于PAGE 1.sysmem 用于C程序中malloc、calloc和realloc函数动态分配存储空间, 一般存放于RAM中, 属于PAGE 14.vary_M.gelmenuitem "Myfunctions"slider vary_M(0, 100, 10, 1, Amount_of_modulation){M = Amount_of_modulation;}该文件用于调试的时候可随意改变变量M的值, 该文件通过file->load GEL File添加到工程中, 调试的时候可选择GEL->My Functions->vary_M来打开vary_M滑动条组件。
嵌入式C语言开发ADSP21系列DSP嵌入式C语言开发ADSP21XX系列DSP摘要详细介绍使用VisualDSP开发工具进行ADSP21XX的C语言编程的方法;分析其C语言运行库的结构,并且结合实例介绍C语言工具的使用方法,包括C语言与汇编语言混合编程的方法,从C运行库提取代码用于自己的汇编语言程序的方法、修改运行库的源代码以适应自己开发需要的方法等。
关键词DSPVisualDSP嵌入式C语言汇编语言引言长期以来,在DSP系统开发中,一直把汇编语言作为主要的开发工具;但汇编语言与自然语言差距很大,不易常,而且汇编语言是依赖于处理器的,不利于软件的可重复利用和系统的稳定性,程序不易移植,给开发工作带来了很大的困难。
随着嵌入式系统复杂程度的不断提高,用汇编语言编写一个巨大的程度将是困难,甚至是不可能的。
为此,AD公司推出了针对ADSP21XX系列DSP的嵌入式C和C++语言集成开发工具,分别是VisualDSP和VisualDSP++系列,这些开发工具提供了C语言和C++语音的开发功能。
以下就以笔者在实际开发中的一些经验,结合VisualDSP6.1版本,介绍用C语言开发VisualDSP6.1版本,介绍用C语言开发ADSP21XX的方法。
VisualDSP提供了一个开放源码软件组织GNU的C编译器,和一套成熟稳定的C运行时间库(CRuntimeLibrary)等。
GNU 的编译器一向以编译效率高著称,在编译后的代码长度和运行速度方面非常优秀;C运行时间库则把很多重复性的工作,如浮点运行、三角函数、FFT等作为C语言的库函数,提供给用户,大大提高了用户的开发效率和程序的稳定性,降低了开发难度,另外,由于把这些库函数的源代码提供给了用户,还提高了C语言与汇编语言之间的透明性,使用户开发的程序兼具两者的优点。
1VisualDSP简介VisualDSP是AD公司的DSP开发工具,主要由可执行文件、库文件和各种帮助文档组成。
一、32 位加法//链接命令文件MEMORY{PAGE 0: ROM :origin=0080h,length=1000hROM :origin=0060h,length=10hPAGE 1: OTHER :origin=0400h,length=40h}SECTIONS{.text : { }>ROM PAGE 0.data :{ }>ROM PAGE 0.bss : { }>OTHER PAGE 1.stack : { }>OTHER PAGE 1}//汇编语言源代码.title "ADD32".mmregs.def start,_c_int00.bss xhi , 2,1,1.bss yhi , 2,1,1.bss zhi , 2,1, 1table .long 13578468H.long 1020B30AH.text_c_int00b startnopnopstart: LD #xhi ,DPSTM #xhi,AR1RPT #3MVPD table,*AR1+DLD xhi , ADADD yhi , ADST A ,zhiEND: B END.end二、64位加法/减法//链接命令文件/*ADDSUB64.cmd*/ADDSUB64.obj-m ADDSUB64.map-o ADDSUB64.outMEMORY{PAGE 0: ROM :origin=0080h,length=1000hROM :origin=0060h,length=10hPAGE 1: OTHER :origin=0400h,length=40h}SECTIONS{.text : { }>ROM PAGE 0.data :{ }>ROM PAGE 0.bss : { }>OTHER PAGE 1.stack : { }>OTHER PAGE 1}//汇编语言源代码.title "ADDSUB64".mmregs.def start,_c_int00.bss x1 , 2 ,1,1.bss x3 , 2 ,1,1.bss y1 , 2 ,1,1.bss y3 , 1.bss y2 , 1.bss z1 , 2 ,1,1.bss z3 , 1.bss z2 , 1.bss w1 , 2 ,1,1.bss w3 , 2 ,1,1table .long 12345678H ;x1x0.long 02468ACEH ;x3x2.long 22222222H ;y1y0.word 1357H,2468H ;y3,y2.long 44444444H ;z1z0.word 1020H,0B30AH ;z3,z2.text_c_int00b startnopnopstart: LD #x1 ,DPSTM #x1,AR1RPT #11MVPD table,*AR1+DLD x1,A ; A = X1 X0DADD y1,A ; A= X1 X0 + Y1 Y0,产生进位CDLD x3,B ; B = X3 X2ADDC y2,B ; B = X3 X2 + 00 Y2 + CADD y3,16,B ; B = X3 X2 + Y3 Y2 + CDSUB z1,A ; A= X1 X0 + Y1 Y0-Z1Z0,产生借位C'DST A,w1 ; W1W0= X1 X0 + Y1 Y0-Z1Z0SUBB z2,B ; B = X3 X2 + Y3 Y2 + C - 00 Z2-C'SUB z3,16,B ; B = X3 X2 + Y3 Y2 + C -Z3 Z2-C'DST B,w3 ; W3 W2= X3 X2 + Y3 Y2 + C - Z3 Z2-C' END: B END.end三、FIR滤波//链接命令文件fir.obj-m fir.map-o fir.outMEMORY{PAGE 0: ROM1(RIX) :ORIGIN=0080H,LENGTH=100HPAGE 1: INTRAM1(RW) :ORIGIN=2400H,LENGTH=0200HINTRAM2(RW) :ORIGIN=2600H,LENGTH=0100HINTRAM3(RW) :ORIGIN=2700H,LENGTH=0100HB2B(RW) :ORIGIN=0070H,LENGTH=10H}SECTIONS{.text : {}>ROM1 PAGE 0.data : {}>INTRAM1 PAGE 1FIR_COFF: {}>INTRAM2 PAGE 1FIR_BFR : {}>INTRAM3 PAGE 1.stack : {}>B2B PAGE 1}//汇编语言源代码;一个FIR滤波器源程序fir.asm.mmregs.global start.def start,_c_int00INDEX .set 1KS .set 256 ;模拟输入数据缓冲区大小N .set 17COFF_FIR .sect "COFF_FIR" ;FIR滤波器系数.word 0.word 158.word 264.word -290.word -1406.word -951.word 3187.word 9287.word 12272.word 9287.word 3187.word -951.word -1406.word -290.word 260.word 158.word 0.dataINPUT .copy "firin.inc" ;模拟输入在数据存储区0x2400 OUTPUT .space 1024 ;输出数据在数据区0x2500 ;FIR_DP .usect "FIR_V ARS",0;D_FIN .usect "FIR_V ARS",1;D_FOUT .usect "FIR_V ARS",1COFFTAB .usect "FIR_COFF",NDA TABUF .usect "FIR_BFR",NBOS .usect "STACK",0FhTOS .usect "STACK",1.text.asg AR0,INDEX_P.asg AR4,DA TA_P ;输入数据x(n)循环缓冲区指针.asg AR5,COFF_P ;FIR系数表指针.asg AR6,INBUF_P ;模拟输入数据指针.asg AR7,OUTBUF_P;FIR滤波器输出数据指针_c_int00b startnopnopstart: ssbx FRCTSTM #COFFTAB,COFF_PRPT #N-1 ;将FIR系数从程序存储器移动MVPD #COFF_FIR,*COFF_P+ ;到数据存储器STM #INDEX,INDEX_PSTM #DATABUF,DATA_PRPTZ A,#N-1STL A,*DATA_P+ ;将数据循环缓冲区清零STM #(DA TABUF+N-1),DATA_P ;数据缓冲区指针指向x[n-(N-1)]STM #COFFTAB,COFF_P ;FIR_TASK:STM #INPUT,INBUF_PSTM #OUTPUT,OUTBUF_PSTM #KS-1,BRCRPTBD LOOP-1STM #N,BK ;FIR循环缓冲区大小LD *INBUF_P+,A ;装载输入数据FIR_FILTER:STL A,*DATA_P+%RPTZ A,N-1MAC *DATA_P+0%,*COFF_P+0%,ASTH A,*OUTBUF_P+LOOP:EEND B EEND.end四、IIR滤波//链接命令文件MEMORY{PAGE 0:EPROM: org=0E00H, len=1000HVECS0: org=0FF80H, len=0080hPAGE 1:SPRAM: org=0060H, len=0020hDARAM: org=0080H, len=1380H}SECTIONS{.text :>EPROM PAGE 0.data :>EPROM PAGE 0X: align(8) {}>DARAM PAGE 1Y: align(8) {}>DARAM PAGE 1B: align(8) {}>DARAM PAGE 1A: align(8) {}>DARAM PAGE 1.vecs0:>VECS0, PAGE 0}//输入数据序列(512点)0x7fff0x00x0…0x0//汇编语言源代码.title "IIR.ASM".mmregs.def _c_int00X .usect "X", 5Y .usect "Y", 5B .usect "B", 5A .usect "A", 5PA0 .set 0PA1 .set 1.datatable: .word 0.word 0.word 0.word 0.word 0.word 0.word 0.word 0.word 3116.word -10286.word 14615.word -10286.word 3116.word -22082.word 31149.word -30484.word 28383.text_c_int00:SSBX FRCTSTM #X, AR1RPT #3MVPD #table, *AR1+STM #Y, AR1RPT #3MVPD #table+4, *AR1+STM #B, AR1RPT #4MVPD #table+8, *AR1+STM #A, AR1RPT #3MVPD #table+13, *AR1+STM #X+4, AR2STM #A+3, AR3STM #Y+3, AR4STM #B+4, AR5STM #5, BKSTM #-1, AR0STM #1000H, AR6STM #0200H-1, AR7loop:PORTR PA1, *AR2LD *AR2, ASTL A, -1, *AR2MPY *AR2+0%, *AR5+0%, AMAC *AR2+0%, *AR5+0%, AMAC *AR2+0%, *AR5+0%, AMAC *AR2+0%, *AR5+0%, AMAC *AR2, *AR5+0%, AMAC *AR4, *AR3, AMAC *AR4, *AR3, AMAC *AR4, *AR3, AMAC *AR4+0%, *AR3+0%, AMAC *AR4, *AR3, AMAC *AR4, *AR3, AMAC *AR4, *AR3, AMAC *AR4, *AR3, AMAC *AR4+0%, *AR3+0%, AMAC *AR4, *AR3, AMAC *AR4, *AR3, AMAC *AR4+0%, *AR3+0%, AMAC *AR4+0%, *AR3+0%, AMAR *AR3+0%STH A, *AR4PORTW *AR4, PA0STH A, *AR6+BANZ loop, *AR7-end: B end.end五、除法//链接命令文件/*chuf.cmd*/chuf.obj-m chuf.map-o chuf.outMEMORY{PAGE 0: ROM :origin=0080h,length=1000hROM :origin=0060h,length=10hPAGE 1: OTHER :origin=0400h,length=40h}SECTIONS{.text : {}>ROM PAGE 0.data :{}>ROM PAGE 0.stack : {}>OTHER PAGE 1.bss : {}>OTHER PAGE 1}//汇编语言源代码;*** 编制计算除法运算的程序段。
DSP的C语言开发一、流程步骤:main() {}下面是vectors.asm函数,该文件在每个DSP的project中(需手工加入),其中有对_c_int00的调用,而_c_int00在rts.lib中,在开发时要手工加入。
在reset 后,rom等外存中的程序已经转移到了L2 cache中,并且程序从0x0000 0000处开始执行,而0x0000 0000处的程序正是vectors.asm,以下就开始层层调用,进入main函数。
======== vectors.asm ========; Plug in the entry point at RESET in the interrupt vector table;;; ======== unused ========; plug inifinite loop -- with nested branches to; disable interrupts -- for all undefined vectors;unused .macro id.global unused:id:unused:id:b unused:id: ; nested branches to block interruptsnop 4b unused:id:nopnopnopnopnop.endm.sect ".vectors".ref _c_int00 ; C entry point.align 32*8*4 ; must be aligned on 256 word boundaryRESET: ; reset vectormvkl _c_int00,b0 ; load destination function address to b0mvkh _c_int00,b0b b0 ; start branch to destination functionmvc PCE1,b0 ; address of interrupt vectorsmvc b0,ISTP ; set table to point herenop 3 ; fill delay slotnopnop;; plug unused interrupts with infinite loops to; catch stray interrupts;unused 1unused 2unused 3unused 4unused 5unused 6unused 7unused 8unused 9unused 10unused 11unused 12unused 13unused 14unused 15Rts6000.lib来自于rts6000.src,该原文件是由多个.c和.cpp以及.asm组成的,其中关于int _args_main()的函数:这个函数就是void __interrupt c_int00()在初始化完成后调用的函数,int _args_main()函数中调用了main(argc, argv)从而正式转入main函数。
1卷积:#include <stdio.h>#include "volume.h"/* Global declarations */int inp1_buffer[BUFSIZE];int inp2_buffer[BUFSIZE]; /* processing data buffers */int out1_buffer[BUFSIZE];int out2_buffer[BUFSIZE];int out3_buffer[BUFSIZE];int out4_buffer[BUFSIZE*2];int size = BUFSIZE;int ain = MINGAIN;int zhy=0;int sk=64; /*sk代表所开的bufsize的大小,需修改它.输入文件sine.dat为32点,sine11.dat,sin22.dat,sin33.dat,sin44.dat为64点的输入波形.*//* volume control variable */unsigned int processingload = 1; /* processing routine //load value *//* Functions */extern void load(unsigned int loadValue);static int processing1(int *output1, int *output2);static int processing2(int *output2, int *output3);static int processing3(int *input1,int *output2,int *output4);static int processing4(int *input2, int *output1);static void dataIO1(void);static void dataIO2(void);/** ======== main ========*/void main(){int *input1 = &inp1_buffer[0];int *input2 = &inp2_buffer[0];int *output1 = &out1_buffer[0];int *output2 = &out2_buffer[0];int *output3 = &out3_buffer[0];int *output4 = &out4_buffer[0];puts("volume example started\n");/* loop forever */while(TRUE){/** Read input data using a probe-point connected to a host file.* Write output data to a graph connected through a probe-point.*/dataIO1();dataIO2();/* apply gain */processing4(input2,output1);processing1(output1, output2);processing2(output2, output3);processing3(input1,output2,output4) ;}}/** ======== processing ========** FUNCTION: apply signal processing transform to input signal.** PARAMETERS: address of input and output buffers.** RETURN V ALUE: TRUE.*/static int processing4(int *input2,int *output1){ int m=sk;for(;m>=0;m--){*output1++ = *input2++ * ain;}for(;(size-m)>0;m++){output1[m]=0;}////load(processingload);return(TRUE);}static int processing1(int *output1,int *output2){int m=sk-1;for(;m>0;m--){*output2++ = *output1++ * ain;}/* additional processing //load *///load(processingload);return(TRUE);}static int processing2(int *output2, int *output3){ int n=zhy;size=BUFSIZE;for(;(size-n)>0;n++){ *output3++ = output2[n];}/* for (;n>0;n--){ *output3++ = 0;} *///load(processingload);return(TRUE);}static int processing3(int *input1,int *output2,int *output4) { int m=sk;int y=zhy;int z,x,w,i,f,g;for(;(m-y)>0;){i=y;x=0;z=0;f=y;for(;i>=0;i--){g=input1[z]*output2[f];x=x+g;z++;f--;}*output4++ = x;y++;}m=sk;y=sk-1;w=m-zhy-1;for(;m>0;m--){y--;i=y;z=sk-1;x=0;f=sk-y;for(;i>0;i--,z--,f++){g=input1[z]*output2[f];x=x+g;}out4_buffer[w]=x;w++;}//load(processingload);return(TRUE);}/** ======== dataIO ========** FUNCTION: read input signal and write processed output signal. ** PARAMETERS: none.** RETURN V ALUE: none.*/static void dataIO1(){/* do data I/O */return;}static void dataIO2(){/* do data I/O */return;}2排序选择:程序如下,但是这个题目有些问题,随机产生10000个100之内的整数,根据概率来看至少有100个左右的100,所以输出前10个最大值基本上100%的可能都是100,你要是不放心,可以将我下面的程序里面的k改成10000看一下实际效果:#include <stdio.h>#include <time.h>#include <stdlib.h>#include <conio.h>#define N 10000void SelectSort ( int array[], int n ){int nMinIndex;int nIndex_1, nIndex_2;for (nIndex_1 = 0;nIndex_1 < n - 1 ;nIndex_1++){nMinIndex = nIndex_1;for (nIndex_2 = nIndex_1 + 1 ; nIndex_2 < n;nIndex_2++){if ( array[nMinIndex] > array[nIndex_2] ){nMinIndex = nIndex_2;}}if ( nMinIndex != nIndex_1 ){int temp = array[nIndex_1];array[nIndex_1] = array[nMinIndex];array[nMinIndex] = temp ;}}}void ShowArray(int array[], int k){int i;for (i = 0; i < k; i++){printf("%d\t", array[i]);if ((i+1)%10 == 0){printf("\n");}}printf("\n");}int main(){int array[N] = {0};int k=10,i;srand((unsigned) time(NULL));for(i=0;i<N;i++)array[i]=rand()%100+1;SelectSort(array, N);printf("Sorted Array:\n");ShowArray(array, k);system("pause");return 0;}3冒泡:void sort(int p[],int n){int i,j,temp;for(i=0;i<n-1;i++)for(j=i+1;j<n;j++)if(p[i]>p[j]){temp=p[i];p[i]=p[j];p[j]=temp;}}4差分方程法一:用C语言画差分方程C(K+2)=1.025C(K+1)-0.4733C(K)+0.2385R (K+1)+0.2089R(K)图象k<0时c(k)=0,r(k)=0k>=0时r(k)=1初试条件c(0)=,c(1)=0.238#include <stdio.h>#include <conio.h>#define N 100main(){int i;double c[N+1];FILE *fp;fp=fopen("d:\\zhidao.txt","w");if (!fp){printf("File Open ERROR:\nPress any to exit:");getch();exit(1);}c[0]=0;c[1]=0.238;fprintf(fp,"0\t%g\n",c[0]);fprintf(fp,"1\t%g\n",c[1]);for (i=2;i<=N;i++){c[i]=1.025*c[i-1]-0.4733*c[i-2]+0.2385*1+0.2089*1;fprintf(fp,"%d\t%g\n",i,c[i]);}fclose(fp);printf("OK");getch();}得到数据文件zhidao.txt后用origin或excel进行作图。