DSP简单例程

合集下载

一个简单的dspC语言例子

一个简单的dspC语言例子

一个简单的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滑动条组件。

DSP简单例程

DSP简单例程

不知道你学过单片机没有。

37个寄存器是R1-R16.(当然,里面有很多是分几个模式的,所以总共有37个)类似于单片机的R0-R7.GPXCON,GPXDAT等等是另外的寄存器,应该叫,特殊功能寄存器,类似于单片机的P0,P1,TCON,等等。

GPXCON:是X管脚的控制寄存器,控制它们的模式,比如输出模式,输入模式……GPXDAT:是X管脚的数据寄存器,存储它们的数据,比如:在输出模式中,想在X管脚输出什么数据,就在这个寄存器里写入什么数据,在输入模式中,这个寄存器中存储的就是外部输入的数据。

手把手教你找GPIO寄存器IODIR 定义手把手教你找寄存器定义一直就很纳闷,没有一个向c8051f410.h的头文件定义特殊功能寄存器,找不见定义,使用起来就无从下手,心里总是不舒坦;从网上看了一些帖子,都说就是在头文件里(我也是这么认为的,肯定要有定义的,不然无法调用)StartUp{………..……….GEL_MapAdd(0x3400u,2,0x0400u,1,1); /* GPIO 1KW */………..}这段映射0x3400u 为GPIO空间,其实只是表示这段i/o空间可读可写;下面是我一步一步地追踪,这些都是要用到的宏定义;#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) 从一个ioport Uint16*类型的地址中取出地址内容,就是IODIR寄存器的值了#define _GPIO_IODIR_ADDR (0x3400u) //定义了IO地址常量#define _GPIO_IODIR PREG16(_GPIO_IODIR_ADDR) //得到寄存器的地址#define _IODIR _GPIO_IODIR 定义了 _IODIR 常量#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR 两个变量合并#define _PREG_SET(PregAddr, Val) PREG16(PregAddr) = (Uint16)Val#define GPIO_RSET(Reg,Val) _PREG_SET(GPIO_ADDR(##Reg),Val)从这个宏定义开始1:GPIO_RSET(IODIR,1)这句很明显了,把IODIR寄存器的值置12:_PREG_SET(GPIO_ADDR(##IODIR),1)利用这两个宏#define GPIO_RSET(Reg,Val) _PREG_SET(GPIO_ADDR(##Reg),Val)#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR分解的到a:GPIO_ADDR(IODIR) _GPIO_##Reg##_ADDR_GPIO_ IODIR _ADDRb:_PREG_SET(_GPIO_ IODIR _ADDR,1)3:接下来#define _PREG_SET(PregAddr, Val) PREG16(PregAddr) = (Uint16)ValPREG16(_GPIO_ IODIR _ADDR) =1;4::#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) **(_GPIO_ IODIR _ADDR) = 1;5:这句就简单了*(0x3400u) = 1;一步一步顺藤摸瓜,总算摸到;但我们的问题,还是没讲清楚;究竟IODIR 是在哪里定义的呢?开始我也很迷惑,仔细想想后,惶然大悟,快乐!!问题出在,这些都是宏语句,执行编译前,就已经把GPIO_RSET(IODIR,1) 翻译成*(0x3400u) = 1;编译器不认识IODIR ,而IODIR在直到#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR 两个变量合并前就是个字符串,连个常量都算不上(不知道这么说确切不,完全是因为它在语句的位置,赋予了它意义)跟单片机类比 SFR IODIR = 0X3400;编译器绕了这么一大圈,其实做得工作太简单了,究竟为什么这么做,我还没来得及想。

DSP例程

DSP例程

通用定时器1、通用定时器有四个中断:A、通用定时器1上溢中断B、通用定时器下溢中断C、通用定时器比较中断D、通用定时器周期中断这四个中断标志位在EV A中断标志寄存器A(EV AIFRA)中,这四个中断的使能位在EV A 屏蔽寄存器EV AIMRA中设置。

2、通用定时器有三个16位的和定时比较有关的寄存器:A、通用定时器计数寄存器TXCNTB、通用定时器周期寄存器TxPRC、通用定时器比较寄存器TXCMPR通用定时器计数寄存器TxCNT根据通用定时器的时钟和计数模式开始计数,不停的和周期寄存器和比较寄存器从而产生中断或者各种事件。

当工作在定时器的模式时,TxCNT得值和TxPR中设置的值比较,当比较匹配后的一个时钟后,产生相应的事件当工作在比较的模式时,TxCNT得值和TxCMPR中设置的值比较,当比较匹配后的一个时钟后,产生相应的比较事件TxPR和TxCMPR都是带有影子寄存器的,在一个周期的任何时刻都可以对这两个寄存器进行读写,读写的是他们的影子寄存器。

对于TxCMPR,只有当TxCON寄存器指定的特定条件满足时,影子寄存器中的值才加载到比较寄存器中;对于周期寄存器,只有当计数寄存器为0时,影子寄存器的值才能重新加载到周期寄存器。

3、通用定时器的计数模式通用定时器有四种计数模式A、停止/保持吧、模式(TxCON.TMODE1~TMODE0=00)B、连续增计数模式(TxCON.TMODE1~TMODE0=01)C、定向增/减计数模式(有外部引脚决定,xCON.TMODE1~TMODE0=11D、连续增减计数模式(TxCON.TMODE1~TMODE0=10)通过定时器控制寄存器TxCON的12~11位决定,4、时钟可以是外部时钟也可以是内部时钟,一般用内部时钟,内部时钟是HSPCLK经过预分频后得到的。

由TxCON得5~4位决定,TxCON。

TCLKS1~TCLKS0=00选择内部时钟;预分频由TxCON得10~8位决定,CLK=HSPCLK/2的TxCON。

DSP实训程序

DSP实训程序

1.led1 1s啥闪烁led3 1.5s闪烁#include "DSP28_Device.h"#include "ext_inf.h"unsigned int Led_Flag;interrupt void ISRTimer2(void);void main(void){/*初始化系统*/InitSysCtrl();/*关中断*/DINT;IER = 0x0000;IFR = 0x0000;Led_Flag = 0;/*初始化PIE*/InitPieCtrl();/*初始化PIE中断矢量表*/InitPieVectTable();/*初始化外设*/InitPeripherals();EALLOW;PieVectTable.TINT2 = &ISRTimer2;EDIS;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 500000);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGM for(;;);}interrupt void ISRTimer2(void){CpuTimer2.InterruptCount++;if(CpuTimer2.InterruptCount==1){*LED3 = 0;//此行添加断点LED1_ON;}if(CpuTimer2.InterruptCount==2){*LED3 = 0;//此行添加断点LED1_ON;}if(CpuTimer2.InterruptCount==3){*LED3 = 0;//此行添加断点LED1_OFF;}if(CpuTimer2.InterruptCount==4){*LED3 = 1;//此行添加断点LED1_OFF;}if(CpuTimer2.InterruptCount==5){*LED3 = 1;//此行添加断点LED1_ON;}if(CpuTimer2.InterruptCount==6){*LED3 = 1;//此行添加断点LED1_ON;}if(CpuTimer2.InterruptCount==7){*LED3 = 0;//此行添加断点LED1_OFF;}if(CpuTimer2.InterruptCount==8){*LED3 = 0;//此行添加断点LED1_OFF;}if(CpuTimer2.InterruptCount==9){*LED3 = 0;//此行添加断点LED1_ON;}if(CpuTimer2.InterruptCount==10){*LED3 = 1;//此行添加断点LED1_ON;}if(CpuTimer2.InterruptCount==11){*LED3 = 1;//此行添加断点LED1_OFF;}if(CpuTimer2.InterruptCount==12){*LED3 = 1;//此行添加断点LED1_OFF;}}2.AD转换每次采集8个信号,去掉最高最低,取平均值#include <math.h>#include "DSP28_Device.h"#include "comm.h"///////////////////////////////////////////////////////////////////#define SAMPLERATE 4unsigned int SampleRate;unsigned int SampleLong=1024;///////////////////unsigned int i,j;unsigned int Ad_data[1536]={0};int q[8]={0};unsigned int k=0,p=0,temp;float s=0;//////////////////unsigned int convcount = 0;volatile unsigned int adconvover =0;// Prototype statements for functions found within this file.interrupt void ISRTimer2(void);interrupt void ad(void);void sequence(int a[],int n);/*****************************************************************************/ void main(void){/*初始化系统*/InitSysCtrl();#if SAMPLERATE==1SampleRate =ADSAMPL8K;#endif#if SAMPLERATE==2SampleRate =ADSAMPL44K;#endif#if SAMPLERATE==3SampleRate =ADSAMPL96K;#endif#if SAMPLERATE==4SampleRate =ADSAMPL16K;#endif/*关中断*/DINT;IER = 0x0000;IFR = 0x0000;/*初始化PIE中断*/InitPieCtrl();/*初始化PIE中断矢量表*/InitPieVectTable();//初始化cputimerInitCpuTimers();/*设置中断服务程序入口地址*/EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.TINT2 = &ISRTimer2;PieVectTable.ADCINT = &ad;EDIS; // This is needed to disable write to EALLOW protected registers/*开中断*/IER |= M_INT1;//ADC中断EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGM/*启动AD采样*//*AD采样率*/adconvover=0;switch( SampleRate){case ADSAMPL8K: //采样率为8kDINT;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 125);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT;InitAdc();SampleRate = 0;break;case ADSAMPL44K: //采样率为44kDINT;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 22);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT;InitAdc();SampleRate = 0;break;case ADSAMPL16K: //采样率为16kDINT;ConfigCpuTimer(&CpuTimer2,150,62);StartCpuTimer2();IER |= M_INT14;EINT;InitAdc();SampleRate = 0;break;case ADSAMPL96K: //采样率为96kDINT;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 10);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT;InitAdc96k();SampleRate = 0;break;default:break;}for(;;){if (adconvover==1){adconvover=0;}}}interrupt void ad(void){IFR=0x0000;PieCtrl.PIEACK.all=0xffff;q[k] = AdcRegs.RESULT0;k++;{k=0;sequence(q,7);for(p=1;p<7;p++)s=s+q[p];s=s/6;Ad_data[convcount]=s;s=0;convcount++;}if (convcount==(SampleLong+SampleLong/2)){convcount=0;adconvover=1;//接满标志}}interrupt void ISRTimer2(void){AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR=1;AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;}void sequence(int a[],int n){int i=0;int j=0;int temp=0;for(i=0;i<n;i++){for(j=i+1;j<=n;j++){if(a[i]>a[j]){temp=a[i];a[i]=a[j];a[j]=temp;}}}}#include "DSP28_Device.h"#define a 0x0003#define b 0x000c#define c 0x0030#define d 0x00c0/*定义扩展总线存储器空间页地址寄存器地址为0x004020*/ volatile unsigned int* p_ceselect=(volatile unsigned int *)0x004020; /*定义交通灯IO口的地址为0x80000*/volatile unsigned int* p_iodisable=(volatile unsigned int *)0x080007; //子函数声明interrupt void eva_timer1_isr(void);//全局中断计数变量int Direct1=0;int Direct2=0;Uint32 EvaTimer1InterruptCount;Uint32 i,j=0;Uint32 uart_sendtype;Uint32 Sci_VarRx[100];Uint32 flag=2;Uint32 Send_Flag;Uint32 speed=0xffff;Uint32 num=0;Uint32 NU=0;Uint32 table0[4]={0,0,0,0};Uint32 table1[4]={d,b,c,a};Uint32 table2[4]={a,c,b,d};Uint32 Q[5]={125,62,42,31,25};Uint32 q=0;Uint32 p=4;void main(void){/*初始化系统*/InitSysCtrl();/*关中断*/DINT;IER = 0x0000;IFR = 0x0000;//*p_ceselect =0x6 ;//打开ce3空间for(i=0;i<0x100;i++);*p_iodisable =0x1;//IO空间始能for(i=0;i<0x100;i++);/*初始化PIE控制寄存器*/InitPieCtrl();/*初始化PIE矢量表*/InitPieVectTable();/*初始化EV*/InitEv();InitSci();for(i = 0; i < 100; i++){Sci_VarRx[i] = 0;}i = 0;j = 0;Send_Flag = 0;//重新分配中断服务的中断向量EALLOW;PieVectTable.T1PINT = &eva_timer1_isr; //定时器1计数中断EDIS;//初始化变量EvaTimer1InterruptCount = 0;// 使能PIE 组 2 中断4 -- T1PINTPieCtrl.PIEIER2.all = M_INT4;// 使能CPU中断IER |= M_INT2 ;EINT;ERTM;for(;;){}}/**********************************************///EVGP1周期中断/**********************************************/interrupt void eva_timer1_isr(void){j++;if(j==Q[p]){j=0;EvaTimer1InterruptCount++;if(EvaTimer1InterruptCount==4){EvaTimer1InterruptCount=0;num++;}if(q==0)EvaRegs.ACTRA.all=table2[EvaTimer1InterruptCount]; if(q==1)EvaRegs.ACTRA.all=table1[EvaTimer1InterruptCount];}//使能中断EvaRegs.EV AIMRA.bit.T1PINT = 1;//清除中断标志EvaRegs.EV AIFRA.all = BIT7;//中断应答接收更多的PIE 组2的中断PieCtrl.PIEACK.all = PIEACK_GROUP2;}4.直流电机调速#include "DSP28_Device.h"int m=1;void xnitgpio(){EALLOW;GpioMuxRegs.GPEMUX.bit.XINT2_ADCSOC_GPIOE1=1;GpioMuxRegs.GPEQUAL.BIT.QUALPRD=0x0ff;XIntruptRegs.XINT2CR.bit.ENABLE=1;XIntruptRegs.XINT2CR.bit.POLARITY=0;EDIS;}void InitEvA(void){//设置GPIOEALLOW;GpioMuxRegs.GPAMUX.all=0x00ff;//GpioMuxRegs.GPAMUX.all=0x00fe;//GpioMuxRegs.GPADIR.bit.GPIOA0=1;//GpioDataRegs.GPADAT.bit.GPIOA0=1;EDIS;// 初始化定时器控制寄存器(EV A)EvaRegs.GPTCONA.all = 0;//设置定时器1// 设置定时器1的周期和比较;if(m==0){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x0000;} //0%if(m==1){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x15f9;} //75%if(m==2){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x1770;} //80%if(m==3){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x18e7;} //85%if(m==4){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x1a5e;} //90%if(m==5){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x1bd5;} //95%if(m==6){EvaRegs.T1PR = 0x1d4c;//(7500) 10khz; // 周期EvaRegs.T1CMPR = 0x1d4c;} //100%// 中断使能EvaRegs.EV AIMRA.bit.T1PINT = 1;EvaRegs.EV AIFRA.bit.T1PINT = 1;// 清除计数寄存器EvaRegs.T1CNT = 0x0000;// 设置定时器控制寄存器//EvaRegs.T1CON.all = 0x1042;EvaRegs.T1CON.all = 0x1040;//连续递增/递减计数,定时器使能,比较使能//设置定时器2// 设置定时器2的周期和比较;EvaRegs.T2PR = 0x1d4c;//0x0fff; // 周期EvaRegs.T2CMPR = 0x000; // 比较// 清除计数寄存器EvaRegs.T2CNT = 0x0000;// 设置定时器控制寄存器//EvaRegs.T2CON.all = 0x1042;EvaRegs.T2CON.all = 0x1040;EvaRegs.EV AIMRB.bit.T2PINT = 1;//定时器2周期中断允许EvaRegs.EV AIFRB.bit.T2PINT = 1;//清除标志//设置T1PWM和T2PWM//比较逻辑驱动T1/T2PWMEvaRegs.GPTCONA.bit.TCOMPOE=1;//EvaRegs.GPTCONA .bit .TCMPOE=1;//定时器1比较其极性设置为高电平有效EvaRegs.GPTCONA .bit .T1PIN =2;//定时器2比较其极性设置为高电平有效EvaRegs.GPTCONA .bit .T2PIN =2;//使能产生PWM1-PWM6的比较功能/*EvaRegs.CMPR1 =0x00c0;EvaRegs.CMPR2 =0x03c0;EvaRegs.CMPR3 =0x0fc0;*///比较方式控制//输出引脚1CMPR1-高有效输出引脚2CMPR1-低有效//输出引脚3CMPR2-高有效输出引脚4CMPR2-低有效//输出引脚5CMPR3-高有效输出引脚6CMPR3-低有效//EvaRegs.ACTRA .all=0x0666;//EvaRegs.DBTCONA.all=0x0Af8;//x/4,死区开,m=2,p=4,t=0.2us // CONA .all=0xA600;}。

CCSv5.5中DSPBIOS简单搭建例程

CCSv5.5中DSPBIOS简单搭建例程

添加 DSP/BIOS 配置到当前工程
1) 选择 File > New > DSP/BIOS v5.x Configuration File。
2) 检查 Filename 栏的 tcf 文件名是否和你的工程名一致。这里名为 test.tcf。点
击 Next 按钮。
3) 选择所属的器件型号平台,我的是 ti.platforms.evm6748,点击 Next 按钮。
void taskledoff() {
while(1) { SEM_pend(&SEM1, SYS_FOREVER); GPIOPinWrite(SOC_GPIO_0_REGS, 34,GPIO_PIN_HIGH); TSK_sleep(500); //Delay(5000000); SEM_post(&SEM0); LOG_printf(&trace, "Task ledoff DONE"); } }
}
void taskledon() {
while(1) { SEM_pend(&SEM0, SYS_FOREVER); GPIOPinWrite(SOC_GPIO_0_REGS, 34,GPIO_PIN_LOW); TSK_sleep(500); //Delay(5000000); SEM_post(&SEM1); LOG_printf(&trace, "Task ledon DONE"); } }
创建步骤 选择 TSK – Task Manager ,右键选择插入,并为每个任务起个名字,这里我命 名了两个名称分别为 TSK_ledon、TSK_ledoff 的任务。优先级分别为 2 和 3。两来就会看到 led 在闪 烁。

DSP例程

DSP例程
如果采用间接寻址并更新ARP的值,此时必须指定一 个shift(移位)操作数。如果不希望产生移位,则将0作为 操作数,例如ADD *+,0,AR2。
退出
第三章 TMS320LF240x的软件结构
通常,如果相加的结果产生进位时,C=1;不产生进 位时,C=0。但是,当左移16位进行相加时,如果相加的 结果产生进位,则C=1;不产生进位时,则C不受影响。 这样,在把32位数加到累加器时,可使累加器产生正确的 符号进位。
【例3-17 】 ADD 1,1 ;DP=6:地址0300h-037Fh
数据存储器 301h
ACC × C
执行指令前 1h 2h
数据存储器 301h
ACC 0 C
执行指令后 1h 4h
退出
第三章 TMS320LF240x的软件结构 【例3-18 】 ADD *+,0,AR0
指令中给出的操作数既不是立即数也不是直接地址,而 是将这个操作数做地址的内存单元的内容作为访问地址,即 指令中的操作数是一个间接地址。间接寻址为系统的编程带 来了很大的灵活性和方便性。
DSP芯片内有8个辅助寄存器AR0-AR7和辅助寄存器算术 单元ARAU,这些资源专用于间接寻址,它可以访问64KB的 寻址空间而不受数据页的限制。因此,DSP的间接寻址能力非 常灵活和强大,而且寻址的速度非常快。
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 0 1 1 1 0 11
k
RPT 操作代码
8 位常数=k
退出
第三章 TMS320LF240x的软件结构
【例2】 采用9位短立即数寻址的RPT指令,需要重复执行的 次数包含在指令操作码后。
RPT #k ;9位短立即数寻址

DSP开发环境和流程的简单例程

DSP开发环境和流程的简单例程
绝对列表器(absolute lister)它输入目标文件,输出.abs文件,通过汇编.abs文件可产生含有绝对地址的列表文件。如果没有绝对列表器,这些操作将需要冗长乏味的手工操作才能完成。
图1-3典型的软件开发流程图
1.2.3硬件仿真和实时数据交换
TI DSPs提供在片仿真支持,它使得CCS能够控制程序的执行,实时监视程序运行。增强型JTAG连接提供了对在片仿真的支持,它是一种可与任意DSP系统相连的低侵扰式的连接。仿真接口提供主机一侧的JTAG连接,如TI XSD510。为方便起见,评估板提供在板JTAG仿真接口。
图2-2装载程序
图2-3反汇编(Disassembly)窗口
现在可以开始运行我们的程序:在主菜单中单击“Debug”,选择“Go Main”,让程序从主函数开始执行。程序会停在main()处,并会有一个黄色的箭头标记当前要执行的C语言代码。如果希望同时看到C语言代码和对应编译生成的汇编代码,在主菜单中单击“View”,选择“Mixed Source/ASM”,此时会有一个绿色的箭头量标记当前要执行的汇编代码,如图2-4所示。
此时,在浅灰色显示的汇编指令上单击鼠标,然后按F1键,CCS会对该汇编指令进行搜索并弹出帮助窗进行解释。可以利用该功能来了解不熟悉的汇编指令。
在主菜单中单击“Debug”,选择“Run”,或单击工具条图标(Run),让程序全速执行。在主菜单中单击“Debug”,选择“Halt”,或单击工具条(Halt),让程序退出运行。
工程窗口用来组织用户的若干程序构成一个项目,用户可以从工程列表中选中需要编译和调试的特定程序。在源程序编译/调试窗口中用户既可以编译程序又可以设置断点、探针,调试程序。反汇编窗口可以帮助用户查看机器指令,查找错误。内存和寄存器显示窗口可以查看、编辑内存单元和寄存器。图形显示窗口可以根据用户需要直接或经过处理后显示数据。用户可以通过主菜单Windows条目来管理窗口。

DSP_BIOS简单实例教程

DSP_BIOS简单实例教程

Code Composer Studio 教程(二)——开发一个DSP/BIOS程序在此教程中,通过使用DSP/BIOS来优化hello程序。

此教程需要一个目标板,而且不可以用一软件模拟器来实现。

同时,此教程需要CCS的DSP/BIOS部分。

步骤1:创建一个配置文件另一种实现hello程序的方法是使用配有DSP/BIOS API的LOG模块(API——应用程序接口)。

你可以在加载入的程序中使用DSP/BIOS来提供基本的运行时间服务。

API模块使实时DSPs进行最优化。

不同于C库调用如puts(),DSP/BIOS在不暂停目标硬件的情况下进行实时分析。

另外,API代码占用更小的空间,同时比C标准的I/O运行更快。

一个程序可使用一个或更多的DSP/BIOS模块。

在此,修改hello 文件以使用DSP/BIOS API。

为应用DSP/BIOS API,一个程序必须拥有一个程序所使用的定义了DSP/BIOS对象的配置文件。

1)打开项目myhello.mak。

(在D:\han\study2目录下)2)File ——> New ——> DSP/BIOS Config。

3)选择对DSP板的类型,确定。

此时弹出一界面窗口。

4)右击LOG-Event Log Manager,并选择Insert LOG,这样建立一个名为LOG0的LOG对象。

5)右击LOG0,选择Rename,改名为“trace”。

6)File ——> Save。

保存于工作目录下,配置文件名为myhello.cmd。

保存此配置直接产生以下文件:①myhello.cdb:保存配置的设置。

②myhellocfg.cmd:连接器命令文件。

③myhellocfg.s62:汇编语言源文件。

④myhellocfg.h62:包含在myhellocfg.s62中的汇编语言头文件。

尽管这些文件拥有.s62和.h62的扩展名,它们也可应用在TMS320C6701中。

第四章DSP例程

第四章DSP例程

第四章 TMS320LF240x的片内外设 的片内外设 寄存器地址 7090h 7092h 7094h 7098h 709Ah 709Ch 709Eh 7095h 7096h 寄存器名称 MCRA MCRB MCRC PADATDIR PBDATDIR PCDATDIR PDDATDIR PEDATDIR PFDATDIR 功 能 I/O端口复用控制寄存器 端口复用控制寄存器A I/O端口复用控制寄存器A I/O端口复用控制寄存器B I/O端口复用控制寄存器B 端口复用控制寄存器 I/O端口复用控制寄存器 端口复用控制寄存器C I/O端口复用控制寄存器C A组数据和方向控制寄存器 B组数据和方向控制寄存器 C组数据和方向控制寄存器 D组数据和方向控制寄存器 E组数据和方向控制寄存器 F组数据和方向控制寄存器
退出
第四章 TMS320LF240x的片内外设 的片内外设
I/O端口的数据和方向控制寄存器 4.1.3 I/O端口的数据和方向控制寄存器
数据和方向控制寄存器PxDATDIR(x为 数据和方向控制寄存器PxDATDIR(x为A~F)共有6个,只 PxDATDIR(x F)共有6 共有 有当I/O端口被设置成一般的I/O功能时, I/O端口被设置成一般的I/O功能时 有当I/O端口被设置成一般的I/O功能时,数据和方向控制寄 存器才起作用。 存器才起作用。 6个数据和方向控制寄存器的格式基本相同,其高8位表 个数据和方向控制寄存器的格式基本相同, 示对应的低8位的数据输入输出方向, 位表示相应的I/O 示对应的低8位的数据输入输出方向,低8位表示相应的I/O 口的有效逻辑电平。 口的有效逻辑电平。 (1)A组端口PADATDIR (1)A组端口PADATDIR 组端口
第四章 TMS320LF240x的片内外设 的片内外设 位8:写1为CAP5/QEP4 ;写0为IOPF0 。 位7:写1为CAP4/QEP3 ;写0为IOPE7 。 位6:写1为PWM12 ;写0为IOPE6 。 位5:写1为PWM11;写0为IOPE5 。 ; 位4:写1为PWM10 ; 写0为IOPE4 。 位3:写1为PWM9 ;写0为IOPE3 。 位2:写1为PWM8 ;写0为IOPE2 。 位1:写1为PWM7 ;写0为IOPE1。 。 位0:写1为CLKOUT ;写0为IOPE0 。

典型dsp处理流程

典型dsp处理流程

典型dsp处理流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。

文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor.I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!深入理解典型DSP(数字信号处理)处理流程数字信号处理(Digital Signal Processing,简称DSP)是现代电子技术中的一个重要领域,它在通信、音频、图像、雷达等多个领域都有广泛的应用。

dsp实验程序

dsp实验程序

dsp实验程序外部中断#include "2407c.h"ioport unsigned int port8000;ioport unsigned int port8005;ioport unsigned int port8007;void interrupt xint(void);/* 中断服务程序,外部中断调用*/unsigned int uWork,nCount;int * pf;main(){int i;*WDCR=0x6f;*WDKEY=0x5555;*WDKEY=0xaaaa; /* 关闭看门狗中断*/*SCSR1=0x81fe; /* 设置DSP运行频率40m */(*MCRB)=0;asm(" setc INTM"); /* 关中断,进行关键设置时不允许发生中断,以免干扰*/uWork=(*MCRC); /* 将PWM12/IOPE6设置成通用I/O口,以控制实验箱上指示灯*/uWork&=0x0ffbf;(*MCRC)=uWork;*IMR=0x1; /* 使能中断(INT1) */*IFR=0xffff; /* 清除中断标志*/*XINT2CR=0x1; //使能外部中断2port8000=0; // 初始化ICETEK-CTRport8000=0x80;port8000=0;port8000=0x82;port8007=0; // 关闭东西方向的交通灯port8007=0x40; // 关闭南北方向的交通灯port8007=0xc8;//使能键盘外中断asm(" clrc INTM"); /* 开中断*/for(;;);}// 中断服务程序:响应INT2中断void interrupt xint(void) /* 中断服务程序定义,须使用interrupt声*/ {uWork=(*PIVR); /* 读外设中断向量寄存器*/switch(uWork){case 0x11:{*XINT2CR=0x8001;//清除中断标志位uWork=(*PEDA TDIR); /* 设置指示灯状态翻转一次*/uWork|=0x4000;uWork^=0x0040;(*PEDA TDIR)=uWork;break;}}}I\O管脚应用#include "2407c.h"ioport unsigned int port8000;ioport unsigned int port8005;ioport unsigned int port8001;ioport unsigned int port8002;ioport unsigned int port8003;ioport unsigned int port8004;ioport unsigned int port8007;#define CTRGR port8000#define CTRLCDCMDR port8001#define CTRKEY port8001#define CTRLCDCR port8002#define CTRCLKEY port8002#define CTRLCDLCR port8003#define CTRLCDRCR port8004#define CTRLA port8005#define CTRLR port8007void Delay(int nDelay); /* 延时子程序*/main(){unsigned int uWork;*WDCR=0x6f;*WDKEY=0x5555;*WDKEY=0xaaaa; /* 关闭看门狗*/*SCSR1=0x0202; /* DSP运行频率40m */(*MCRB)=0;uWork=(*MCRC); /* 将PWM12/IOPE6设置成通用I/O口*/ uWork&=0x0ffbf;(*MCRC)=uWork;CTRGR=0; // 初始化ICETEK-CTRCTRGR=0x80;CTRGR=0;CTRLR=0; // 关闭东西方向的交通灯CTRLR=0x40; // 关闭南北方向的交通灯CTRGR=2;while ( 1 ){uWork=(*PEDATDIR); /* PWM12/IOPE6的控制寄存器*/uWork|=0x4000; /* 输出*/uWork^=0x0040; /* 输出状态*/(*PEDATDIR)=uWork;Delay(256); /* 延时片刻*/}}void Delay(int nDelay){int i,j;unsigned int k;for ( i=0;i<="" p="">for ( j=0;j<64;j++ )k++;}定时器#include "2407c.h"#define T1MS 0x9c3f /* 9c3fH=40000-1 */ioport unsigned int port8000;ioport unsigned int port8005;ioport unsigned int port8007;void interrupt gptime1(void); /* 中断服务程序,定时器计数T1MS次时中断调用*/void gp_init(void); /* 定时器初始化*/unsigned int uWork,nCount;int * pf;main(){int i;*WDCR=0x6f;*WDKEY=0x5555;*WDKEY=0xaaaa; /* 关闭看门狗中断*/*SCSR1=0x81fe; /* 设置DSP运行频率40m */(*MCRB)=0;asm(" setc INTM"); /* 关中断,进行关键设置时不允许发生中断,以免干扰*/uWork=(*MCRC); /* 将PWM12/IOPE6设置成通用I/O口,以控制实验箱上指示灯*/uWork&=0x0ffbf;(*MCRC)=uWork;gp_init(); /* 设置定时器*/*IMR=0x2; /* 使能定时器中断(INT2) */*IFR=0xffff; /* 清除中断标志*/port8000=0; // 初始化ICETEK-CTRport8000=0x80;port8000=0;port8000=0x82;port8007=0; // 关闭东西方向的交通灯port8007=0x40; // 关闭南北方向的交通灯asm(" clrc INTM"); /* 开中断*/for(;;);}// 中断服务程序:响应INT2中断void interrupt gptime1(void) /* 中断服务程序定义,须使用interrupt声*/ {uWork=(*PIVR); /* 读外设中断向量寄存器*/switch(uWork){case 0x27: /* T1PINT,0x27为定时器1的周期中断的向量值*/ {(*EV AIFRA)=0x80; /* 清除中断标志T1PINT */nCount++;if ( nCount>=500 ) /* 计数500此=500ms=0.5秒*/{uWork=(*PEDA TDIR); /* 设置指示灯状态翻转一次*/uWork|=0x4000;uWork^=0x0040;(*PEDA TDIR)=uWork;nCount=0;}break;}}}void gp_init(void){*EVAIMRA = 0x80; /* 使能T1PINT即通用定时器1周期中断*/ *EVAIFRA = 0xffff; /* 清除中断标志*/*GPTCONA = 0x0000;*T1PR = T1MS; /* 周期寄存器=40000 */*T1CNT = 0; /* 计数初值=0 */*T1CON = 0x1040; /* 启动计数器*/}pwm#include "regs240x.h"main(){unsigned int uWork;asm(" setc INTM"); /* 关中断*/asm(" setc SXM"); /* 符号位扩展有效*/asm(" clrc OVM"); /* 累加器中结果正常溢出*/asm(" clrc CNF"); /* B0被配置为数据存储空间*/WDCR=0x6f;WDKEY=0x5555;WDKEY=0xaaaa; /* 关闭看门狗中断*/SCSR1=0x81fe; /* DSP工作在40MHz */IMR=0; /* 屏蔽所有可屏蔽中断*/IFR=0x0ffff; /* 清除中断标志*/uWork=WSGR; /* I/O引脚0等待*/uWork&=0x0fe3f;WSGR=uWork;MCRA=MCRA|0x0fc0; /* IOPA6-7被配置为基本功能方式,PWM1-2 */ACTRA=0x0666; /* PWM2低有效,PWM1高有效*/DBTCONA=0x00; /* 不使能死区控制*/CMPR1=0x1000; /* 比较单元1设置*/CMPR2=0x3000; /* 比较单元2设置*/CMPR3=0x5000;T1PER=0x6000; /* 设置定时器1的周期寄存器,以确定不同的输出占空比*/ COMCONA=0x8200; /* 使能比较操作*/T1CON=0x1000; /* 定时器1为连续增计数模式*/T1CON=T1CON|0x0040; /* 启动定时器1 */while ( 1 ){}}A D#include "2407c.h"#define ADCNUMBER 256void interrupt gptime1(void); /* 中断服务程序,用于设置保存标志*/void ADInit(void); /* 初始化A/D转换模块和通用定时器1 */ioport unsigned char port000c; /* I/O端口用于设置ICETEK-2407-A板上指示灯*/ unsigned int uWork,uWork1,nADCount,nLed,*pResult1,*pResult2;int nNewConvert,nWork;unsigned int nADCIn0[ADCNUMBER]; /* 存储区1,保存通道ADCIN0的转换结果,循环保存*/unsigned int nADCIn1[ADCNUMBER]; /* 存储区2,保存通道ADCIN1的转换结果,循环保存*/main(){asm(" CLRC SXM"); /* 清标志,关中断*/asm(" CLRC OVM");asm(" CLRC CNF");pResult1=RESULT0;pResult2=RESULT1;nNewConvert=0;*WDCR=0x6f;*WDKEY=0x5555;*WDKEY=0xaaaa; /* 关闭看门狗中断*/*SCSR1=0x81fe; /* 打开所有外设,设置时钟频率为40MHz */ uWork=(*WSGR); /* 设置I/O等待状态为0 */uWork&=0x0fe3f;(*WSGR)=uWork;ADInit(); /* 初始化A/D相关设备*/*IMR=2; /* 使能定时器中断*/*IFR=0xffff; /* 清所有中断标志*/asm(" clrc INTM"); /* 开中断*/while ( 1 ){if ( nNewConvert ) /* 如果保存标志置位,以下开始转换和保存转换结果*/{nNewConvert=0; /* 清保存标志*/uWork=(*pResult1); /* 取ADCINT0通道转换结果*/uWork>>=6; /* 移位去掉低6位*/nADCIn0[nADCount]=uWork;/* 保存结果*/uWork=(*pResult2); /* 取ADCINT1通道转换结果*/uWork>>=6; /* 移位去掉低6位*/nADCIn1[nADCount]=uWork;/* 保存结果*/nADCount++;if ( nADCount>=ADCNUMBER ) /* 缓冲区满后设置指示灯闪烁*/{nADCount=0; /* 中断位置*/nWork++;if ( nWork>=16 ){nWork=0;nLed++; nLed&=0x0f;port000c=nLed;}}}}}void ADInit(void) /* 初始化设置*/{int i;for ( i=0;i<="" p="" 缓冲区清0="">nADCIn0[i]=nADCIn1[i]=0;port000c=0; /* 关指示灯*/*ADCTRL1= 0x2f40; /* 设置连续转换模式*/*MAXCONV = 0x1; /* 每次完成转换两个通道*/*CHSELSEQ1=0xc4; /* 转换次序,先ADCIN4,再ADCIN11 */ *ADCTRL2= 0x2000; /* 启动转换*/nADCount=nLed=nWork=0;;/* 以下设置通用定时器参数*/*EVAIMRA = 0x80; /* 使能T1PINT */*EVAIFRA = 0xffff; /* 清中断标志*/*GPTCONA = 0x0100;*T1PR = 2000; /* 保存结果周期=2000*25ns=50us=20KHz */ *T1CNT = 0; /* 计数器从0开始计数*/*T1CON = 0x1040; /* 连续增计数方式,启动计数器*/}void interrupt gptime1(void){uWork1=(*PIVR);switch ( uWork1 ){case 0x27:{nNewConvert=1; /* 设置保存标志*/(*EV AIFRA)=0x80;/* 清中断标志位*/break;}} }。

DSP开发环境和流程的简单例程(精)

DSP开发环境和流程的简单例程(精)
十六进制转换公用程序(hex conversion utility)它把COFF目标文件转换成TI-Tagged、ASCII-hex、Intel、Motorola-S、或Tektronix等目标格式,可以把转换好的文件下载到EPROM编程器中,其细节参见TMS320C54x汇编语言工具用户指南。
交叉引用列表器(cross_reference lister)它用目标文件产生参照列表文件,可显示符号及其定义,以及符号所在的源文件,其细节参见TMS320C54x汇编语言工具用户指南。
绝对列表器(absolute lister)它输入目标文件,输出.abs文件,通过汇编.abs文件可产生含有绝对地址的列表文件。如果没有绝对列表器,这些操作将需要冗长乏味的手工操作才能完成。
图1-3典型的软件开发流程图
1.2.3硬件仿真和实时数据交换
TI DSPs提供在片仿真支持,它使得CCS能够控制程序的执行,实时监视程序运行。增强型JTAG连接提供了对在片仿真的支持,它是一种可与任意DSP系统相连的低侵扰式的连接。仿真接口提供主机一侧的JTAG连接,如TI XSD510。为方便起见,评估板提供在板JTAG仿真接口。
CCS提供了基本的代码生成工具,它们具有一系列的调试、分析能力。CCS支持如下所示的开发周期的所有阶段。
图1-1 CCS开发周期
1.2 CCS基本结构
1.2.1CCS构成及接口
CCS包括如下各部分:CCS代码生成工具、CCS集成开发环境(IDE)、DSP/BIOS插件程序和API、RTDX插件、主机接口和API。CCS构成及接口见图1-2。
归档器(archiver)允许你把一组文件收集到一个归档文件中。归档器也允许你通过删除、替换、提取或添加文件来调整库,其细节参见TMS320C54x汇编语言工具用户指南。

dsp原理与开发实例

dsp原理与开发实例

dsp原理与开发实例DSP(数字信号处理)是指对数字信号进行各种处理操作的技术。

它在包括通信、音频、图像、视频、雷达以及生物医学工程等领域有广泛的应用。

DSP的基本原理是将模拟信号经过采样、量化和编码转换为数字信号,然后利用算法对数字信号进行处理,最后再将数字信号转换为模拟信号。

下面是一些常见的DSP开发实例:1. 音频降噪:通过DSP技术,可以对音频信号进行降噪处理,消除噪声对音频质量的影响。

例如,在手机通话中,可以利用DSP技术降低环境噪声的干扰,提高通话质量。

2. 语音识别:DSP可以应用于语音识别领域,将语音信号转换为数字信号,并利用识别算法对语音信号进行分析和辨识。

语音识别技术在智能助理、语音控制和自动转写等场景中得到广泛应用。

3. 图像增强:DSP可以对图像信号进行增强,改善图像的质量。

例如,在数字摄影中,可以通过DSP技术增强图像的对比度、色彩和清晰度,提高图像的观赏性。

4. 视频编解码:DSP在视频编解码中有重要应用。

通过采用合适的编解码算法,可以将视频信号压缩存储,实现视频的传输和播放。

常见的视频编码标准如H.264、H.265等都是基于DSP技术的发展。

5. 数字滤波:DSP可以应用于数字滤波领域,对数字信号进行滤波处理,去除不需要的频率分量或噪声。

数字滤波器可以具备各种滤波特性,如低通、高通、带通、带阻等,可以应用于音频处理、图像处理等方面。

以上只是DSP的一小部分应用实例,实际上,DSP在各个领域都有着广泛的应用,无论是在通信、娱乐、汽车、医疗等行业,都可以找到DSP技术的身影。

通过利用DSP技术,可以对信号进行处理、分析和提取,实现更高质量、更高效率的信号处理和应用。

DSP系统设计实例

DSP系统设计实例
12
给定x(n),n=1,.....,N-1,其DCT变换为:
13
例六 DCT.c
#include <math.h> #include <stdio.h> #define pi 3.1415925 int i,k; int K=8; int n=8; float x[8],X[8];
main() {
36
计算其幅频特性: d=sqrt(pow(re,2)+pow(im,2)); db[k]=20.0*log10(d);
计算其相频特性: theta=arg(abs(re)/abs(im))
37
各种窗设计得到的幅频图:
矩形窗
巴特里特窗
汉宁窗
哈明窗
布莱克曼窗
38
各种窗设计得到的相频图:
矩形窗
巴特里特窗 汉宁窗
第五章 DSP系统设计实例
1
例一 堆栈的使用
MEMORY
{
PAGE 0:
。。。。。。
PAGE 1:
。。。。。。
DARAM:org=2000H
len=2000H
}
SECTIONS
{
。。。。。。
ห้องสมุดไป่ตู้
STK:>DARAM
PAGE 1
。。。。。。
}
2
例二 阶乘
.mmregs .global
start .data
离散余弦变换,尤其是它的第二种类型,经常被信号处 理和图像处理使用,用于对信号和图像(包括静止图像和运 动图像)进行有损数据压缩。这是由于离散余弦变换具有很 强的“能量集中”特性:大多数的自然信号(包括声音和图像) 的能量都集中在离散余弦变换后的低频部分,而且当信号具 有接近马尔科夫过程的统计特性时,离散余弦变换的去相关 性接近于K-L变换(Karhunen-Loève 变换--它具有最优的去 相关性)的性能。

DSP使用简易步骤

DSP使用简易步骤
果概不负责) 一、开启设备 1、 打开 DSP 开关,红灯闪烁表示可正常使用。 2、 连接数据传输线。 二、连接 DSP 型号设置 1、 打开 Setup CCS2(C600) ; 2、 点击 Clear 清除已连接 DSP,然后 Close; 3、 点击 File→Import,导入新的 DSP 型号,选择最后一个型号(本实验使用 6713); 4、 右击新添加的 DSP 型号,选择 Properties.在 Startup GEL Files 项目中 “CPU_1”项末尾 的浏览按钮,选择 C 盘中 ICETEK-C6713-EDULab 目录中的 ICETEK-C6713-A.gel 文 件,打开,Finish; 5、 保存后退出。 三、CCS 软件应用 1、 打开 CCS2; 2、 Project→New,新建工程,名称自定义(以 X 表示) ; 3、 把 D 盘中所用文件复制到新建工程的 X 文件夹中; 4、 右击新建的工程 X,选择 Add Files to Project,重复三次把 X 文件夹中的.c 与.cmd 文 件加入,将 C 盘中的 ti>C6000>cgtools>lib>rts6701.lib 的.lib 文件也添加到工程。展 开 project 可看到以添加内容; 5、 选择 Project 菜单下的 Build Options,将 Basic 中的 Target Version 项修改为“C671x (-mv6710)”;将 Linker 中的 Stack Size 项修改为 1024; 6、 在要求出设置断点; 7、 选择 Project 菜单下的 Build,编译文件; 8、 执行 File 下的 Load Program,加载编译生成的.out 文件(在 Debug 文件夹中) ; 9、 执行 File 下的 File I/O,点击 Add File 按钮将 Sine.dat 文件加入并 Replace;同时完成 Address:inp_buffer,Length:100,勾选 Warp around 设置。 10、执行 View 下的 Graph,Time/Frequency 修改相应属性;Start Address:inp_buffer, 然后依次 100, 2 ,100 ,16-bit signed integer。 11、运行,“Clear Display”,“Refresh Display”查看运行结果。

dsp经典实例

dsp经典实例

课程设计(综合实验)报告( 2009 -- 2010 年度第二学期)名称:DSP系统课程设计题目:液晶翻屏显示设计院系:电子与通信工程系班级:电子0702班学号:200703020201学生姓名:白羽峰指导教师:尚秋峰、姚国珍设计周数:1周成绩:日期:2010 年7 月液晶翻屏显示设计一、实验要求:使用基于C语言的软件编程,在实验板上的液晶上实现翻屏显示五屏不同画面,定义两个按键,实现翻屏控制。

二、实验目的:1、通过本次课程设计,要求基本掌握在CCS环境下进行编程及调试。

2、通过本次实验,了解和掌握5402芯片上外设(如配置IO口控制LED显示、了解7279芯片的功能及其结合数码管和编码键盘的编程、掌握LCD字符的写入等)的功能以及其编程应用。

三、实验思路:通过读入编码键盘键值(rece_buff)的不同进行上翻和下翻的判断并且执行相应操作,同时定义一个变量cont进行必要的计数(根据键值的不同),再通过摁键后对键值和cont值的同时判断,确定液晶上不同内容的输入,从而实现翻屏功能(翻屏后出现不同诗句)。

四、实验主要源代码如下:#include "DspRegDefine.h" //VC5402 寄存器定义#define UCHAR unsigned char#define UINT16 unsigned int#define UINT32 unsigned long#define TRUE 1#define FALSE 0//--------------- HD7279A指令-----------------------------#define CMD_RESET 0xa4 //复位#define CMD_TEST 0xbf //测试#define RTL_UNCYL 0xa1 //左移#define RTR_UNCYL 0xa0 //右移#define RTL_CYCLE 0xa3 //循环左移#define RTR_CYCLE 0xa2 //循环右移#define DECODE0 0x80 //下载数据按方式0译码#define DECODE1 0xc8 //下载数据按方式1译码#define UNDECODE 0x90 //下载数据但不译码#define BLINKCTL 0x88 //闪烁控制#define ACTCTL 0x98 //消隐控制#define SEGON 0xe0 //段点亮#define SEGOFF 0xc0 //段关闭#define CMD_READ 0x15 //读键盘数据//--------------- LCD 指令-----------------------------//基本指令集RE = 0#define CLEAR 0x0001 //清除显示0000 0000#define RESAC 0x0002 //位址歸位0000 0010#define SETPOINT 0x0006 //進入點設定,游標右移,DDRAM 位址計數器(AC)加1 0000 0110#define CURSOR 0x000F //整體顯示,游標顯示,游標位置反白0000 1111#define MCURSOR 0x0014 //游標向右移動,AC=AC+1 0001 0010#define FUCSET 0x0030 //功能設定,BIT MPU 控制界面,基本指令集,默认设置#define CGRAMAC 0x0040 //設定CGRAM 位址#define DDRAMAC 0x0080 //設定DDRAM 位址//擴充指令集RE=1#define IDLE 0x01 //待命模式#define CGRAMSET 0x02 //捲動位址或RAM 位址選擇#define REVERSE 0x04 //反白選擇#define SLEEP 0x0c //脫離睡眠模式#define EFUCSET 0x66 //擴充功能設定,8 BIT MPU 控制界面,為擴充指令集動作,繪圖顯示ON#define SISA0x40 //設定IRAM 位址或捲動位址#define SETGDRAM 0x80 //設定繪圖RAM 位址/* 端口定义*///---------------------------------------------------------ioport UINT16 port0004; //IO输出地址ioport UINT16 port0002; //串行数据地址//---------------------------------------------ioport UINT16 port0005; //方向控制ioport UINT16 port0006; //CS7279ioport UINT16 port0007; //CLK7279ioport UINT16 port0008; //DA TA7279ioport UINT16 port0009; //KEY7279//----------------------------------------------------------/* 全局变量定义*///---------------------------------------------------------char send_buff = 0x00; //发送缓冲char rece_buff = 0x00; //接收缓冲UINT16 data_buff = 0x0000; //数据缓冲UINT16 cont=0;UCHAR a=3;UINT16 show = 0x00aa;UINT16 temp7279;UINT16 key7279;UCHAR c1[10] = "白日依山尽";UCHAR c2[10] = "黄河入海流";UCHAR c3[10] = "欲穷千里目";UCHAR c4[10] = "更上一层楼";UCHAR c5[10] = "春眠不觉晓";UCHAR c6[10] = "处处闻啼鸟";UCHAR c7[10] = "夜来风雨声";UCHAR c8[10] = "花落知多少";UCHAR c9[10] = "锄禾日当午";UCHAR e1[10] = "汗滴禾下土";UCHAR e2[10] = "谁知盘中餐";UCHAR e3[10] = "粒粒皆辛苦";UCHAR e4[10] = "床前明月光";UCHAR e5[10] = "疑是地上霜";UCHAR e6[10] = "举头望明月";UCHAR e7[10] = "低头思故乡";UCHAR e9[10] = " ";UCHAR e8[10] = "唐诗学习机";UCHAR c0[10] = "欢迎您使用";UCHAR d1[5]="上翻:";UCHAR d2[5]="下翻:";********************************************************************** *************** 所使用的函数原型*************************************************************************************** void cpu_init(void); //初始化CPUvoid xint1_init(void); //外部中断1初始化子程序interrupt void int1(void); //中断1中断子程序extern void delay_8us(void); //8us延迟--T2\T3\T6\T7extern void delay_25us(void); //25us延迟--T4\T5extern void delay_50us(void); //50us延迟--T1void delay_1000ms(void); //25ms延迟--复位延迟void cs_high(void); //片选置高void cs_low(void); //片选置低void send(void); // 发送一个字节8BITchar receive(); // 接收一个字节8BITvoid Delay(UINT16 numbers); //长延迟************************************************************************ *********************** 函数定义****************************************************************************************** void SendByte(UCHAR dat){UCHAR i;UINT16 temp;for(i=0;i<8;i++){temp = port0004; //读IO 8007 SCLK="0";if(dat & 0x0080)port0002 = 0; //写IO 8006 SID="1",发送数据"1" MSB先发送elsetemp = port0002; //读IO 8006 SID="0",发送数据"0" MSB先发送port0004 = 0; //写IO 8007 SCLK="1";dat = dat<<1; //数据左移,移位到dat.7}temp = port0004 ; //读IO 8007 SCLK="0";}//--------------------------------------------------------------------// 函数名称: void SendCMD(UCHAR dat) 写指令寄存器// 函数说明: 写指令寄存器// 输入参数: 输入的命令字// 输出参数: 无//--------------------------------------------------------------------void SendCMD(UCHAR dat){SendByte(0x00F8); //1111 1,00,0 RW=0,RS=0 同步标志SendByte(dat & 0x00F0); //高四位SendByte((dat & 0x000F)<<4); //低四位}//--------------------------------------------------------------------// 函数名称: void SendDat(UCHAR dat) 写显示数据或单字节字符// 函数说明: 写数据寄存器// 输入参数: 输入的数据// 输出参数: 无//--------------------------------------------------------------------void SendDat(UCHAR dat){SendByte(0x00FA); //11111,01,0 RW=0,RS=1SendByte(dat & 0x00F0); //高四位SendByte((dat & 0x000F)<<4); //低四位}//--------------------------------------------------------------------// 函数名称: void Initlcm(void)// 函数说明: 初始化LCM// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------void Initlcm(){asm(" nop ");delay_1000ms();SendCMD(FUCSET); //功能設定,8BIT 并口,基本指令集delay_50us();SendCMD(FUCSET); //功能設定,8BIT 并口,基本指令集delay_50us();SendCMD(CURSOR); //整體顯示,游標顯示,游標位置反白delay_50us();SendCMD(CLEAR); //清除显示delay_1000ms();SendCMD(SETPOINT); //進入點設定,游標右移,DDRAM 位址計數器(AC)加1 delay_50us();}//--------------------------------------------------------------------// 函数名称: void cpu_init(void)// 函数说明: 初始化CPU// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------void cpu_init(void){asm(" nop ");asm(" nop ");asm(" nop ");*(unsigned int*)CLKMD=0x0; //switch to DIV mode clkout= 1/2 clkinwhile(((*(unsigned int*)CLKMD)&01)!=0);*(unsigned int*)CLKMD=0x07ff; //switch to PLL X 1 mode*(unsigned int*)PMST=0x3FF2;*(unsigned int*)SWWSR=0x7fff;*(unsigned int*)SWCR=0x0001;*(unsigned int*)BSCR=0xf800;asm(" ssbx intm "); //Disable all mask interrupts*(unsigned int*)IFR=0xffff;asm(" nop ");asm(" nop ");asm(" nop ");}//--------------------------------------------------------------------// 函数名称: void xint1_init(void)// 函数说明: 初始化XINT1// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------void xint0_init() //外部中断0初始化子程序{*(unsigned int*)IMR=0x0001; //使能int0中断asm(" rsbx INTM"); //开总中断}//--------------------------------------------------------------------// 函数名称: void delay_25ms(void)// 函数说明: 25ms延迟// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------void delay_1000ms(){UINT16 i,j;for(i=0;i<=1000;i++);for(j=0;j<=1000;j++); //延迟250*1000*CLKOUT=250000*CLKOUT//1/CLKOUT=0.1us}//--------------------------------------------------------------------// 函数名称: void cs_high(void)// 函数说明: 片选置高// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------void cs_high(){temp7279 = port0006;}//--------------------------------------------------------------------// 函数名称: void cs_low(void)// 函数说明: 片选置低// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------void cs_low(){port0006 = 0;}//--------------------------------------------------------------------// 函数名称: void send(void)// 函数说明: 发送一个字节8BIT,高位在前// 输入参数: 发送数据在全局变量send_buff中// 输出参数: 无//--------------------------------------------------------------------void send(){UINT16 i;cs_low(); //片选CS=0delay_50us(); //延时50usfor(i=0;i<8;i++){switch(send_buff&0x80){case 0x00:temp7279 = port0008; //7279data低break;case 0x80:port0008 = 0; //7279data高}port0007 = 0;//7279clk高delay_8us();temp7279 = port0007;//7279clk低delay_8us();send_buff<<=1;}//这时,7279CS=1,7279CLK=0 }//--------------------------------------------------------------------// 函数名称: void receive(void)// 函数说明: 接收一个字节8BIT,高位在前// 输入参数: 接收到的数据在全局变量rece_buff中// 输出参数: 无//--------------------------------------------------------------------//void receive()char receive(){UINT16 i;port0005 = 0; //DIR配置成输入asm(" nop");delay_50us();for(i=0;i<8;i++){//7279clk高port0007 = 0;delay_8us();key7279 = port0009& 0x0001;asm(" nop ");//接收到的数据在D0位data_buff=data_buff|(key7279<<(15-i));//7279clk低temp7279 = port0007;delay_8us();}asm(" nop "); //在这里设置断点观察data_buff中的值 rece_buff=(data_buff>>8) & 0x00ff; //接收到的数据右移给rece_buffdata_buff=0x0000; //清除data_bufftemp7279 = port0005;//DIR配置成输出return rece_buff;}//--------------------------------------------------------------------// 函数名称: void int1(void)// 函数说明: 中断1的子程序// 输入参数: 无// 输出参数: 无//--------------------------------------------------------------------interrupt void int0() //中断0中断子程序{*(unsigned int*)IFR = 0xFFFF; //清除所有中断标志,"写1清0"send_buff = CMD_READ; //读键值指令send();receive();asm(" nop ");send_buff = RTL_UNCYL; //数据左移指令send();send_buff = DECODE1;send();send_buff = rece_buff; //将接收到的键值送显示send();switch(rece_buff){case 0x0004 : a=1;break;case 0x0006 : a=0;break;}cs_high(); //7279CS置高asm(" rsbx INTM"); //开总中断return;}/************************************************************- 函数名称: void Delay(int numbers)- 函数说明: 延时- 输入参数: numbers- 输出参数: 无*********************************************************** */void Delay(UINT16 numbers){UINT16 i,j;for(i=0;i<40000;i++);for(j=0;j<numbers;j++);}/************************************************************* ****************** 主函数******************************************************************************* */void main(){ UINT16 temp;char i;//----------系统初始化-------------------------------asm(" nop ");cpu_init(); //初始化CPUasm(" nop ");//---------------------------------------------------//-----------LCD初始化--------------------------------asm(" nop ");Initlcm();//---------------------------------------------------temp7279 = port0005; //DIR =0 ,输出数据给7279//--------------ONLY FOR TEST--------------------------//-----------7279复位--------------------------------send_buff = CMD_RESET; //复位指令send();//-----------7279CS='1'-----------------------------cs_high();//-----------外部中断1初始化------------------------xint0_init(); //外部中断1初始化子程序asm(" nop ");//----------- 等待键盘中断--------------------------while(1){if(rece_buff==0x0004){if(cont==4){cont=0;}else{cont++;rece_buff=0x00;}}else if(rece_buff==0x0006){if(cont==0){cont=4;}else{cont--;rece_buff=0x00;}}switch(a){case 1: {SendCMD(0x0080); //设定DDRAM的地址在第一行80Hfor(i=0;i<5;i++){SendDat(d2[i]);delay_50us();asm(" nop ");}delay_50us();break;}case 0:{SendCMD(0x0080); //设定DDRAM的地址在第一行92Hfor(i=0;i<5;i++){SendDat(d1[i]);delay_50us();asm(" nop ");}delay_50us();break;}}a=3;switch(cont){case 0: {SendCMD(0x0083); //设定DDRAM的地址在第一行83Hdelay_50us();for(i=0;i<10;i++){SendDat(c0[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x0093); //设定DDRAM的地址在第二行93Hdelay_50us();for(i=0;i<10;i++){SendDat(e8[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x008B); //设定DDRAM的地址在第三行8BHdelay_50us();for(i=0;i<10;i++){SendDat(e9[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x009B); //设定DDRAM的地址在第四行9BHdelay_50us();for(i=0;i<10;i++){SendDat(e9[i]);delay_50us();asm(" nop ");}delay_50us();break;}case 1: {SendCMD(0x0083); //设定DDRAM的地址在第一行83Hdelay_50us();for(i=0;i<10;i++){SendDat(c1[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x0093); //设定DDRAM的地址在第二行93Hdelay_50us();for(i=0;i<10;i++){SendDat(c2[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x008B); //设定DDRAM的地址在第三行8BHdelay_50us();for(i=0;i<10;i++){SendDat(c3[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x009B); //设定DDRAM的地址在第四行9BHdelay_50us();for(i=0;i<10;i++){SendDat(c4[i]);delay_50us();asm(" nop ");}delay_50us();break;}case 2: {SendCMD(0x0083); //设定DDRAM的地址在第一行83Hdelay_50us();for(i=0;i<10;i++){SendDat(c5[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x0093); //设定DDRAM的地址在第二行93Hdelay_50us();for(i=0;i<10;i++){SendDat(c6[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x008B); //设定DDRAM的地址在第三行8BHdelay_50us();for(i=0;i<10;i++){SendDat(c7[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x009B); //设定DDRAM的地址在第四行9BHdelay_50us();for(i=0;i<10;i++){SendDat(c8[i]);delay_50us();asm(" nop ");}delay_50us();break;}case 3: {SendCMD(0x0083); //设定DDRAM的地址在第一行83Hdelay_50us();for(i=0;i<10;i++){SendDat(c9[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x0093); //设定DDRAM的地址在第二行93Hdelay_50us();for(i=0;i<10;i++){SendDat(e1[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x008B); //设定DDRAM的地址在第三行8BHdelay_50us();for(i=0;i<10;i++){SendDat(e2[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x009B); //设定DDRAM的地址在第四行9BHdelay_50us();for(i=0;i<10;i++){SendDat(e3[i]);delay_50us();asm(" nop ");}delay_50us();break;}case 4: {SendCMD(0x0083); //设定DDRAM的地址在第一行83Hdelay_50us();for(i=0;i<10;i++){SendDat(e4[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x0093); //设定DDRAM的地址在第二行93Hdelay_50us();for(i=0;i<10;i++){SendDat(e5[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x008B); //设定DDRAM的地址在第三行8BHdelay_50us();for(i=0;i<10;i++){SendDat(e6[i]);delay_50us();asm(" nop ");}delay_50us();SendCMD(0x009B); //设定DDRAM的地址在第四行9BHdelay_50us();for(i=0;i<10;i++){SendDat(e7[i]);delay_50us();asm(" nop ");}delay_50us();break;}}}}五、实验心得体会:通过本次课程设计的动手过程,我基本掌握了在CCS环境下进行编程及调试,进一步深刻了解和掌握了5402芯片上外设(如配置IO口控制LED显示、7279芯片的功能及其结合数码管和编码键盘的编程、LCD字符的写入等)的功能以及其编程应用。

DSP实例教程范文

DSP实例教程范文

DSP实例教程范文DSP(Digital Signal Processing,数字信号处理)是一种处理和分析数字信号的技术,广泛应用于音频处理、图像处理、通信系统、雷达系统等领域。

在本文中,我将为您介绍一些常见的DSP实例,并提供相应的教程。

希望这些实例能帮助您更好地理解和运用DSP技术。

一、音频降噪实例音频降噪是DSP应用中的一个重要领域。

它可以通过去除噪声信号,使得语音信号更加清晰和易于理解。

以下是一个音频降噪实例的教程:1.预处理:将音频信号通过快速傅里叶变换(FFT)转换为频域信号。

2.噪声估计:使用适当的算法(例如最小均方算法)估计噪声信号的频谱。

3.噪声抑制:将噪声频谱与音频信号频谱相减,得到降噪后的频谱信号。

4.反变换:将降噪后的频谱信号通过逆傅里叶变换(IFFT)转换为时域信号,得到降噪后的音频。

二、图像滤波实例图像滤波是图像处理中常用的技术,它可以去除图像中的噪声、增强图像的细节、平滑图像的纹理等。

以下是一个图像滤波实例的教程:1.空域滤波:选择适当的滤波器,如均值滤波器或高斯滤波器。

2.快速傅里叶变换:将图像信号转换为频域信号。

3.频域滤波:对频谱进行滤波处理,可以选择低通滤波器、高通滤波器、带通滤波器等。

4.逆变换:将滤波后的频域信号通过逆傅里叶变换(IFFT)转换回时域信号,得到滤波后的图像。

三、通信系统实例DSP在通信系统中也有广泛的应用,例如基带信号处理、调制解调、通道编码等。

以下是一个通信系统实例的教程:1.信号生成:生成待传输的数字信号,可以选择合适的调制方式(如调幅调制、调频调制)。

2.调制:将数字信号调制为模拟信号,可以选择适当的调制算法(如ASK、FSK、PSK等)。

3.信道编码:对调制后的信号进行编码,以提高传输的可靠性,可以选择适当的编码方式(如卷积码、纠错码)。

4.解调:将接收到的信号进行解调,以恢复原始的数字信号。

5.解码:对解调后的信号进行解码,以恢复原始的数据。

DSP应用技术-工程应用实例

DSP应用技术-工程应用实例

20 K
30 k
3C11
RXB
RX B
14
CLKFLTA D
1u CL K FL TA D 3
4
A V CC
AVCC 3R8
13 V+
IN CL K V-
ou t 11
op ou t op in
5 6
GND 12
3R9
20 K
2
3 3R10
+2 .5 V
U10 MA X 29 5EW E
31R020
NC NC
7 GND 16
AGND 27 AGND
3R3 10 k
3R6 10 k
15 D0 14 D1 13 D2 12 D3 11 D4 10 D5 9 D6 6 D7 5 D8 4 D9 3 D10 2 D11 1 28
TI
T
I
TQ
T
Q
D [0..1 1] D [0..1 1]
图7.7 模拟输入/输出通道电路
工程应用实例
1. 信号流程
(1) 接收信号流程 由射频部分送来的基带DQPSK调制信号 (f0=7.2 kHz),进入带通滤波器MAX295EWE,滤除带外噪声, 然后进入运算放大器(TL084)放大至适当电平(0~3 V变化范围)。 放大后的信号由模数转换器AD7862进行量化,量化后的数据进 入DSP芯片,通过软件编程进行DQPSK解调、维特比译码和解 交织等,得到原始信息码。DSP将该信息码送给Intel8251A,转 化成9.6 kb/s的UART数据流,最后经MAX232EESE转变成RS232电平(±12 V)送往数据终端。
7.6 DSP
工程应用实例

主 系 统 及 部 分 外 围 电 路

DSP入门小案例

DSP入门小案例

• • • • • • • • • • • • • • • • • •
void Gpio_example2(void) { // Example 2: // Toggle I/Os using SET/CLEAR registers for(;;) { GpioDataRegs.GPASET.all =0xAAAAAAAA; GpioDataRegs.GPACLEAR.all =0x55555555; GpioDataRegs.GPBSET.all =0x0000000A; GpioDataRegs.GPBCLEAR.all =0x00000005; delay_loop(); GpioDataRegs.GPACLEAR.all =0xAAAAAAAA; GpioDataRegs.GPASET.all =0x55555555; GpioDataRegs.GPBCLEAR.all =0x0000000A; GpioDataRegs.GPBSET.all =0x00000005; delay_loop(); } }
• void Gpio_select(void) • { • EALLOW; • GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO • GpioCtrlRegs.GPAMUX2.all = 0x00000000; // All GPIO • GpioCtrlRegs.GPBMUX1.all = 0x00000000; // All GPIO • GpioCtrlRegs.GPADIR.all = 0xFFFFFFFF; // All outputs • GpioCtrlRegs.GPBDIR.all = 0x0000000F; // All outputs • EDIS; • }
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

不知道你学过单片机没有。

37个寄存器是R1-R16.(当然,里面有很多是分几个模式的,所以总共有37个)
类似于单片机的R0-R7.
GPXCON,GPXDAT等等是另外的寄存器,应该叫,特殊功能寄存器,类似于单片机的P0,P1,TCON,等等。

GPXCON:是X管脚的控制寄存器,控制它们的模式,比如输出模式,输入模式……GPXDAT:是X管脚的数据寄存器,存储它们的数据,
比如:
在输出模式中,想在X管脚输出什么数据,就在这个寄存器里写入什么数据,
在输入模式中,这个寄存器中存储的就是外部输入的数据。

手把手教你找GPIO寄存器IODIR 定义
手把手教你找寄存器定义
一直就很纳闷,没有一个向c8051f410.h的头文件定义特殊功能寄存器,找不见定义,使用起来就无从下手,心里总是不舒坦;
从网上看了一些帖子,都说就是在头文件里(我也是这么认为的,肯定要有定义的,不然无法调用)
StartUp{
………..
……….
GEL_MapAdd(0x3400u,2,0x0400u,1,1); /* GPIO 1KW */
………..
}
这段映射0x3400u 为GPIO空间,其实只是表示这段i/o空间可读可写;
下面是我一步一步地追踪,这些都是要用到的宏定义;
#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) 从一个ioport Uint16*类型的地址中取出地址内容,就是IODIR寄存器的值了
#define _GPIO_IODIR_ADDR (0x3400u) //定义了IO地址常量
#define _GPIO_IODIR PREG16(_GPIO_IODIR_ADDR) //得到寄存器的地址
#define _IODIR _GPIO_IODIR 定义了 _IODIR 常量
#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR 两个变量合并
#define _PREG_SET(PregAddr, Val) PREG16(PregAddr) = (Uint16)Val
#define GPIO_RSET(Reg,Val) _PREG_SET(GPIO_ADDR(##Reg),Val)
从这个宏定义开始
1:GPIO_RSET(IODIR,1)
这句很明显了,把IODIR寄存器的值置1
2:_PREG_SET(GPIO_ADDR(##IODIR),1)
利用这两个宏
#define GPIO_RSET(Reg,Val) _PREG_SET(GPIO_ADDR(##Reg),Val)
#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR
分解的到
a:GPIO_ADDR(IODIR) _GPIO_##Reg##_ADDR
_GPIO_ IODIR _ADDR
b:_PREG_SET(_GPIO_ IODIR _ADDR,1)
3:接下来
#define _PREG_SET(PregAddr, Val) PREG16(PregAddr) = (Uint16)Val
PREG16(_GPIO_ IODIR _ADDR) =1;
4::#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) *
*(_GPIO_ IODIR _ADDR) = 1;
5:这句就简单了*(0x3400u) = 1;
一步一步顺藤摸瓜,总算摸到;但我们的问题,还是没讲清楚;
究竟IODIR 是在哪里定义的呢?
开始我也很迷惑,仔细想想后,惶然大悟,快乐!!
问题出在,这些都是宏语句,执行编译前,就已经把GPIO_RSET(IODIR,1) 翻译成*(0x3400u) = 1;
编译器不认识IODIR ,而IODIR在直到
#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR 两个变量合并
前就是个字符串,连个常量都算不上(不知道这么说确切不,完全是因为它在语句的位置,赋予了它意义)
跟单片机类比 SFR IODIR = 0X3400;
编译器绕了这么一大圈,其实做得工作太简单了,究竟为什么这么做,我还没来得及想。

总之这个问题已经很明白了;
数字地和模拟地
模拟和数字的概念要搞清楚,模拟是连续的,数字通常就是高低电平信号,之所以模拟地和数字地要分开原因就是担心两总信号之间的干扰。

举个例子说吧,你的耳机是就是由模拟信号来驱动的,它就有一个地,这个地就是模拟地,然后这个地要通过一个磁珠来和你解码芯片的地连接,这样你的输出音质才会好。

是模拟或者数字是由你的后端电路来决定的,而不是你稳压出的电压决定的!!!也就是说你稳压出的电压,可以用在模拟也可以用作数字。

相关文档
最新文档