发新帖本帖赏金 5.00元(功能说明)我要提问
返回列表
[DSP编程]

我的5509A之路

[复制链接]
楼主: wopt
手机看帖
扫描二维码
随时随地手机跟帖
wopt|  楼主 | 2015-3-10 22:07 | 显示全部楼层
本帖最后由 wopt 于 2015-3-11 18:42 编辑

2.8 McBSP
以McBSP实现UART为例。

McBSP概述
TM320C55x提供了可以与其他C55x、编解码器以及其他设备直接通信的多通道缓冲串口(McBSP)。
McBSP重要特性:
  • 全速双工通信。
  • 双缓存发送和三缓存接收数据寄存器,以支持连续传送。
  • 收和发使用独立的帧和时钟。
  • 直接与多媒体数字信号编解码器的工业标准接口,以及有模拟接口和与串行ADC/DAC的接口。
  • 外部变速时钟发生器,内部可编程时钟发生器。
  • 多通道收发,通道数达128。
  • 字宽可选: 8, 12, 16, 20, 24, and 32 bits
  • U-Law and A-Law 压缩与扩展
  • 帧信号与时钟信号极性可编程
  • 直接与下列格式接口
  • T1/E1 framers
  • MVIP switching compatible and ST-BUS compliant devices including:
           1)    MVIP framers
           2)     H.100 framers
           3)    SCSA framers
  • IOM-2 compliant devices
  • AC97 compliant devices
  • IIS compliant devices
  • SPI_ devices


McBSP控制寄存器

串口控制寄存器(SPCR1 和 SPCR2)
  • SPCR1设置McBSP串口的数字环回模式(DLB)、 接收符号扩展和调整方式(RJUST)、Clock Stop模式(RINTM and XINTM)、接收中断模式和硬仿真模式(FREE and SOFT)。
  • DX引脚延时开关(DXENA)
  • 检测接收和发送操作状态(RSYNCERR, XSYNCERR, RFULL, XEMPTY, RRDY, XRDY)
  • McBSP复位选项(RRST, XRST, FRST, GRST)

配置McBSP接收/发送器时的三步骤:
  • 置McBSP接收/发送器为复位状态
  • 配置McBSP接收/发送器寄存器
  • 开启McBSP接收/发送器


接收控制寄存器(RCR1 和 RCR2)
  • Specify one or two phases for each frame of receive data (RPHASE),确定接收数据每一帧是一个阶段还是两个阶段。
  • Define two parameters for phase 1 and (if necessary) phase 2: the serial word length (RWDLEN1, RWDLEN2) and the number of words (RFRLEN1, RFRLEN2),定义阶段的字长和帧长。
  • Choose a receive companding mode, if any (RCOMPAND),选择压扩模式。
  • Enable or disable the receive frame-sync ignore function (RFIG),接收帧同步忽略方法,形象化的描述在TI官方手册McBSP的11.2章节中。
  • Choose a receive data delay (RDATDLY),接收数据延时。


发送控制寄存器(XCR1 和 XCR2)
  • Specify one or two phases for each frame of transmit data (XPHASE)
  • Define two parameters for phase 1 and (if necessary) phase 2: the serial word length (XWDLEN1, XWDLEN2) and the number of words
  • (XFRLEN1, XFRLEN2)
  • Choose a transmit companding mode, if any (XCOMPAND)
  • Enable or disable the transmit frame-sync ignore function (XFIG)
  • Choose a transmit data delay (XDATDLY)
ps..我好懒啊,翻译都不好好写,嘿嘿。  


采样率发生器寄存器(SRGR1 和 SRGR2)
  • Select the input clock source for the sample rate generator (CLKSM, in conjunction with the SCLKME bit of PCR)
  • Divide down the frequency of CLKG (CLKGDV),分频产生波特率,参考文档中的采样率发生器原理框图。
  • Select whether internally-generated transmit frame-sync pulse are driven by FSG or by activity in the transmitter (FSGM).
  • Specify the width of frame-sync pulses on FSG (FWID) and specify the period between those pulses (FPER),设置帧正脉冲宽度。


When an external source (via the CLKS, CLKR, or CLKX pin) provides the input clock source for the sample rate generator(外部时钟源):
  •  If the CLKS pin provides the input clock, the CLKSP bit in SRGR2 allows you to select whether the rising edge or the falling edge of CLKS triggers CLKG and FSG. If the CLKX/CLKR pin is used instead of the CLKS pin, the polarity of the input clock is selected with CLKXP/CLKRP of PCR.
  • The GSYNC bit of SRGR2 allows you to make CLKG synchronized to an external frame-sync signal on the FSR pin, so that CLKG is kept in phase with the input clock.



引脚控制寄存器(PCR)
PCR设置McBSP传输帧同步模式、接收帧同步模式、发送时钟模式、接收时钟模式、发送帧同步信号的极性、接收帧同步信号的极性、发送时钟极性、接收时钟极性,并给出CLKS、DX、DR脚的状态。此外PCR还定义发送和接收部分在复位时相应引脚是否配置为通用 I/O。
  • XIOEN和RIOEN = 0表示DX,FSX,CLKX,DR,FSR,CLKR,CLKS都配置为串口而非通用I/O引脚。
  • FSXM = 1表示发送帧同步由采样率发生器产生(请参考SRGR2寄存器的FSGM位)。
  • FSRM = 0 表示接收帧同步由外部提供。
  • CLKXM = 1 表示发送时钟由内部采样率发生器产生。
  • CLKRM = 0 表示接收时钟由外部提供,同样因为CLKRM与CLKXM连在一起。
  • FSXP = 1 表示发送帧同步低有效。
  • FSRP = 1 表示接收帧同步低有效。
  • CLKXP = 1 表示CLKX的上升沿发送数据 。
  • CLKRP = 0 表示CLKR的下降沿接收数据。


还有多通道控制寄存器,哎!算了,整个我觉得没必要复制然后翻译上来,自己看更能理解。
Multichannel Buffered Serial Port (McBSP) Reference Guide.pdf (1.26 MB)

使用特权

评论回复
wopt|  楼主 | 2015-3-10 22:11 | 显示全部楼层
zhangmangui 发表于 2015-3-10 21:24
希望能在TI DSP版块同时分享

你帮我转过去吧!:)

使用特权

评论回复
wopt|  楼主 | 2015-3-11 11:20 | 显示全部楼层
本帖最后由 wopt 于 2015-3-12 10:50 编辑

3.9 Flash
Flash驱动一般都差不多,会一种,其它也就会了。
Am29LV800b:8 Megabit (1 M x 8-Bit/512 K x 16-Bit),CMOS 3.0 Volt-only Boot Sector Flash Memory。
5509_1_9.png

随板例程的Flash读写操作
#include <csl.h>
#include <csl_pll.h>
#include <csl_emif.h>
#include <csl_chip.h>

#define CESECT1 0x200000
#define CESECT2 0x400000
#define CESECT3 0x600000

Uint16 x;
Uint32 y;
CSLBool b;

unsigned int datacount = 0;
unsigned int databuffer[1000] ={0};
int *souraddr,*deminaddr;
int *fwaddr, *fraddr;
Uint16 addbias;
Uint16 fstatus, fstatus2;
Uint16 success;

/*锁相环的设置*/
PLL_Config  myConfig      = {
  0,    //IAI: the PLL locks using the same process that was underway
                //before the idle mode was entered
  1,    //IOB: If the PLL indicates a break in the phase lock,
                //it switches to its bypass mode and restarts the PLL phase-locking
                //sequence
  12,    //PLL multiply value; multiply 12 times
  1             //Divide by 2 PLL divide value; it can be either PLL divide value
                //(when PLL is enabled), or Bypass-mode divide value
                //(PLL in bypass mode, if PLL multiply value is set to 1)
};
/*SDRAM的EMIF设置*/
EMIF_Config emiffig = {
  0x221,         //EGCR  : the MEMFREQ = 00,the clock for the memory is equal to cpu frequence
                          //                  the WPE = 0 ,forbiden the writing posting when we debug the EMIF
                          //        the MEMCEN = 1,the memory clock is reflected on the CLKMEM pin
                          //        the NOHOLD = 1,HOLD requests are not recognized by the EMIF
  0xFFFF,        //EMI_RST: any write to this register resets the EMIF state machine
  0x3FFF,        //CE0_1:  CE0 space control register 1
                          //        MTYPE = 011,Synchronous DRAM(SDRAM),16-bit data bus width
  0xFFFF,   //CE0_2:  CE0 space control register 2
  0x00FF,   //CE0_3:  CE0 space control register 3
                          //        TIMEOUT = 0xFF;
  0x1FFF,        //CE1_1:  CE0 space control register 1
            //        Asynchronous, 16Bit
  0xFFFF,        //CE1_2:  CE0 space control register 2
  0x00FF,        //CE1_3:  CE0 space control register 3

  0x1FFF,        //CE2_1:  CE0 space control register 1
            //        Asynchronous, 16Bit
  0xFFFF,        //CE2_2:  CE0 space control register 2
  0x00FF,        //CE2_3:  CE0 space control register 3

  0x1FFF,        //CE3_1:  CE0 space control register 1
            //        Asynchronous, 16Bit
  0xFFFF,        //CE3_2:  CE0 space control register 2
  0x00FF,        //CE3_3:  CE0 space control register 3

  0x2911,   //SDC1:   SDRAM control register 1
                          //                  TRC = 8
                          //        SDSIZE = 0;SDWID = 0
                          //        RFEN = 1
                          //        TRCD = 2
                          //        TRP  = 2
  0x0410,        //SDPER : SDRAM period register
                          //                  7ns *4096
  0x07FF,    //SDINIT: SDRAM initialization register
                          //        any write to this register to init the all CE spaces,
                          //        do it after hardware reset or power up the C55x device
  0x0131        //SDC2:          SDRAM control register 2
                          //        SDACC = 0;
                          //        TMRD = 01;
                          //        TRAS = 0101;
                          //        TACTV2ACTV = 0001;
  };

void delay(Uint16 k)
{
        while(k>0)
        {
                k--;
        }
}

void ddelay(Uint16 kt)
{
    Uint16 jj,kk;
        for(jj=0;jj<65535;jj++)
        {
                kk = kt;
                while(kk>0)
                {
                        kk--;
                }
        }
}

/*************以下内容为AM29LV800BT的读写等函数**************/
/* 参考:AM29LV800BT的芯片手册
         TMS320VC5509 DSP External Memory Interface (EMIF) Reference Guide
                 HX-5509A 开发板使用手册
*/
void Flash_CS()
{
        deminaddr = (int *)CESECT2;
        *deminaddr = 0x00fd;
    deminaddr = (int *)CESECT3;
        *deminaddr = 0x0040;
        deminaddr = (int *)CESECT2;
        *deminaddr = 0x00ff;
}

void Flash_disCS()
{
        deminaddr = (int *)CESECT2;
        *deminaddr = 0x00fd;
    deminaddr = (int *)CESECT3;
        *deminaddr = 0x00c0;
        deminaddr = (int *)CESECT2;
        *deminaddr = 0x00ff;
}

void Flash_Reset()  //AM29LV800复位
{
        deminaddr = (int *)CESECT2;
        *deminaddr = 0x00fd;
    deminaddr = (int *)CESECT3;
        *deminaddr = 0x0000;
        delay(1000);
        *deminaddr = 0x0040;
        *deminaddr = 0x00c0;
        deminaddr = (int *)CESECT2;
        *deminaddr = 0x00ff;
}

Uint16 Flash_Erase_all()  //AM29LV800芯片擦除
{
    Flash_CS();

        deminaddr = (int *)CESECT1;
        addbias = 0x0555;
        *(deminaddr+addbias) = 0x00aa;
        addbias = 0x02aa;
        *(deminaddr+addbias) = 0x0055;
        addbias = 0x0555;
        *(deminaddr+addbias) = 0x0080;
        addbias = 0x0555;
        *(deminaddr+addbias) = 0x00aa;
        addbias = 0x02aa;
        *(deminaddr+addbias) = 0x0055;
        addbias = 0x0555;
        *(deminaddr+addbias) = 0x0010;
        delay(100);
        fstatus = *(deminaddr+addbias);
        fstatus &= 0x0040;
        fstatus2 = *(deminaddr+addbias);
        if((fstatus&fstatus2)!=0)
        {
                Flash_disCS();
                return 0;
        }
        else
        {
                while(fstatus!=0x00ff)
            {
                        ddelay(500);
                        fstatus = *(deminaddr+addbias);
                        fstatus &= 0x00ff;
            }
                Flash_disCS();
                return 1;
        }
}

Uint16 Flash_Erase_sector()  //AM29LV800分段擦除
{
        return 1;
}

void Flash_Write_init()  //AM29LV800烧写初始化
{
        Flash_CS();

        deminaddr = (int *)CESECT1;
        addbias = 0x0555;
        *(deminaddr+addbias) = 0x00aa;
        addbias = 0x02aa;
        *(deminaddr+addbias) = 0x0055;
        addbias = 0x0555;
        *(deminaddr+addbias) = 0x0020;
}

Uint16 Flash_Write(Uint16 waddr, Uint16 wdata) //AM29LV800烧写
{
    *(fwaddr+waddr) = 0x00a0;
        *(fwaddr+waddr) = wdata;
        delay(10000);
        fstatus = *(fwaddr+waddr);
    while(fstatus!=wdata)
        {
                delay(10000);
                fstatus = *(fwaddr+waddr);
        }
        return 1;
}

void Flash_Write_end()  //AM29LV800烧写结束
{
        deminaddr = (int *)CESECT1;
        *deminaddr = 0x0090;
        *deminaddr = 0x0000;

        Flash_disCS();
}

Uint16 Flash_Read(Uint16 raddr)  //AM29LV800读
{
        Uint16 frtemp;
        frtemp = *(fraddr+raddr);
        return frtemp;
}

main()
{
        /*初始化CSL库*/
    CSL_init();

    /*EMIF为全EMIF接口*/
    CHIP_RSET(XBSR, 0x0201);

    /*设置系统的运行速度为144MHz*/
    PLL_config(&myConfig);

    /*初始化DSP的外部SDRAM*/
    EMIF_config(&emiffig);

    Flash_Reset();

        //Flash_Erase_all运行大约为14s以上,为节约时间注释掉,用户可自行根据需要取消注释
        success = Flash_Erase_all();


        //以下程序为烧写AM29LV800
        Flash_Write_init();
        fwaddr = (int *)CESECT1;  //地址首先指向5509的CE1空间(AM29LV800所在)
        fwaddr += 0x10000;        //指向AM29LV800的1扇区
        for(datacount=0;datacount<1000;datacount++)
        {
                success = Flash_Write(datacount, datacount);
        }
        Flash_Write_end();

        //以下程序为读AM29LV800
        for(datacount=0;datacount<1000;datacount++)
        {
                databuffer[datacount]=0;
        }
        Flash_CS();
        fraddr = fwaddr;
        for(datacount=0;datacount<1000;datacount++)
        {
                databuffer[datacount] = Flash_Read(datacount);
        }
        Flash_disCS();

        //运行到此处,在view--memory里查看databuffer开始地址的数据,看是否所写即所读
    while(1);
}


使用特权

评论回复
zhangmangui| | 2015-3-11 22:59 | 显示全部楼层
等兄弟更新完了  我转过去

使用特权

评论回复
wopt|  楼主 | 2015-3-12 11:20 | 显示全部楼层
本帖最后由 wopt 于 2015-3-13 21:35 编辑

2.10 USB
USB模块硬件结构分析
VC5509A的USB模块有16个端点(endpoint)。其中有两个控制端点,输入端点0和输出端点0;14个通用端点,输入端点1~7和输出端点1~7[3]。USB接口的数据传输的方向可以分为Out传输(由主机到USB设备)和In传输(由USB设备到主机)[1]。In传输时,CPU或者USB DMA控制器将数据放在Buffer RAM中,进而数据通过UBM(USB Buffer Manager)到达SIE(串行接口引擎),由SIE负责将片内的并行数据转换成串行数据后通过USB接口输出。Out传输与之方向相反,原理和传输路径相同。


USB的固件设计与实现
使用VC5509A DSP芯片的USB接口,DSP系统对外部而言可以看作一个USB设备。USB设备作为一个完整的硬件设备,是由硬件和固件两部分组成的。固件包括有关系统的配置、模块初始化以及USB协议栈三部分。其中,系统配置是在芯片上电就完成的,与具体系统实现的功能密切相关。因此对于VC5509A来说,固件设计需要实现的主要功能可分为两部分:
  • USB设备的初始化与配置:告知主机设备的能力和特性,并为设备分配地址。
  • USB1.1的标准的协议的应答(即实现固件协议栈),并以批量(BULK)方式通过InEndpoint2与OutEndpoint2完成DSP与PC机的数据交换。



初始化配置
VC5509A的USB固件设计中,初始化配置是很重要的一环。对于55xx系列的DSP芯片,TI在其开发环境CCS中带有芯片支持库CSL(chip support library),CSL以函数或者宏的形式提供一系列DSP硬件操作接口。使用CSL可以使USB模块驱动的编写变得方便快捷[2]。编写通信接口固件可以通过CSL对USB模块进行配置,具体步骤:
  • 初始化应用函数接口向量指针,USB_setAPIVectorAddress()函数使得使用者可以通过函数调用表来访问芯片支持库CSL的USB应用函数API。
  • 初始化USB时钟产生器以产生USB模块所需要的48MHz时钟。USB模块需要48MHz时钟驱动,CLKIN的时钟可以不等于48MHz,但必须通过USB时钟产生器产生48MHz时钟。可以通过USB_initPLL()函数来完成。该函数有三个参数,第一个是输入频率,第二个是输出频率,第三个是输入时钟分频数。
  • 初始化函数USB_init()初始化USB模块。该函数有三个参数,第一个是USB设备号,第二个指向一个以NULL结束的初始化端点目标的句柄组成的数组,第三个是帧预起始定时器的计数值。

当USB模块初始化完成后,通过USB_devConnect函数,使USB模块与总线联接,发送和接收USB源数据。USB模块与主机的相连接,需要在DSP上运行相应的代码,以支持USB协议。如果没有USB协议处理代码,DSP将不能处理接受到的数据,导致DSP被主机挂起。

USB模块配置与初始化代码如下:
CSL_init();                                /* 初始化片上支持库 */
USB_setAPIVectorAddress();     /* 初始化应用函数接口向量指针 */
USB_disconnectDev(USB0);      /* 将USB模块与总线断开,保证配置正确进行 */
USB_initPLL(12,48,0);         /* 产生48MHz时钟 */
……/* 创建端点对象,并初始化端点对象 */
USB_EpHandle hEpObjArray[]= {&EndptObjOut0,&EndptObjIn0,……,NULL};



传输方式的实现
USB总线上的信息包括差模数据线上的包以及一些有特殊意义的数据线上的信号,如设备唤醒、复位等等。根据USB总线传输的不同数据,USB定义了四种传输方式[1]:控制传输、中断传输、批量传输、同步传输。四种传输方式分别对应于不同的传输环境要求。USB协议栈应该能够识别不同的数据,并用不同的传输类型并对它们进行相应的处理。
控制传输是最为复杂的传输类型,也是最重要的传输类型,是USB枚举阶段最主要的数据交换方式。主机一旦发现USB设备连接到总线上,就通过控制传输来交换信息:设置设备地址、读取设备描述符和选择配置。下面重点分析在VC5509A上实现控制传输的方法。中断传输、批量传输和同步传输较之控制传输要简单,可以在控制传输的基础上实现。
控制传输中的硬件操作接口可以通过片上支持库CSL中的两个的API函数实现:

接收Setup包函数USB_getSetupPacket()和传输函数 USB_postTransaction()。前者可以由数据缓冲区中读取Setup包,后者通过端点发送和接收USB数据。当USB设备初次联接到总线上时,DSP通过USB_getSetupPacket()函数来交换信息、设备地址和读取设备的描述符。
USB_SetupStruct USB0_SetupPkt; /*定义承载Setup包的USB_SetupStruct型变量*/
void USB_Endpt0EventHandler(void) /*控制端点0的中断服务程序*/
{ if(USB_getEvents(EndptObjIn0) & USB_EVENT_SETUP) /*判断Setup事件发生*/
{ if(USB_getSetupPacket(USB0, USB0_SetupPkt) == USB_TRUE)
/*由数据缓冲区中读取Setup包并保存在变量USB0_SetupPkt中 */
{
/*―― 以下分析由主机传送过来的setup包,并作相应处理,完成总线枚举――*/
switch(USB0_SetupPkt.bRequest)
case GET_STATUS: //获取状态请求(2byte)
case CLEAR_FEATURE: //清除特性请求
case SET_FEATURE: //设置特性请求
case SET_ADDRESS: //设置地址请求
case GET_DESCRIPTOR: //获取描述符请求
case SET_DESCRIPTOR: //设置描述符请求
case GET_CONFIGURATION: //获取配置请求
case SET_CONFIGURATION: //设置配置请求
case GET_INTERFACE: //获取接口请求
case SET_INTERFACE: //设置接口请求
case SYNCH_FRAME: //同步帧请求
/*―――――――――――――END――――――――――――――― */
}
} return;
}

以上利用控制传输实现控制端点0的中断服务程序,完成USB标准请求命令。



设备固件协议栈
USB设备固件协议栈以设备端点的使用和管理作为基础和核心,而编写USB中断服务程序是整个设备端固件编写的主要内容。固件协议栈主要完成以下功能:
1) 设备上电复位,系统初始化,并使能中断。
2) 系统等待,直到将Setup包接收到端点0缓冲区为止。
3) 应答设备请求,完成设备枚举。
4) 等待USB中断,有中断发生则进入中断服务程序,完成系统要求。


参考程序见帖子首页“论坛资源”

Universal Serial Bus (USB) Module Reference Guide.pdf (761.89 KB)

使用特权

评论回复
wopt|  楼主 | 2015-3-12 11:20 | 显示全部楼层
本帖最后由 wopt 于 2015-3-17 17:02 编辑

TMS320C55x DSP Library
TMS320C55x DSPLIB is an optimized DSP Function Library for C programmers on TMS320C55x devices。DSPLIB——免费使用、修改和散布。


3.1 基本算数运算

3.1.1 add
函数 ushort oflag = add (DATA *x, DATA *y, DATA *r, ushort nx, ushort scale) 定义在add.asm中。
  • *r = *x + *y
  • nx—输入和输出向量的元素数目(>3)
  • scale—防溢出选择
  • oflag—32位溢出标志

3.1.2 sub
函数 short oflag = sub (DATA *x, DATA *y, DATA *r, ushort nx, ushort scale) 定义在sub.asm中。
  • *r = *x - *y
  • nx—输入和输出向量的元素数目(>3)
  • scale—防溢出选择
  • oflag—32位溢出标志


3.1.3 mul32
函数 ushort oflag = mul32 (LDATA *x, LDATA *y, LDATA *r, ushort nx) 定义在mul32.asm中。
  • *r = *x * *y
  • nx—输入和输出向量的元素数目(>3)
  • scale—防溢出选择
  • oflag—32位溢出标志


3.14 ldiv16
函数 void ldiv16 (LDATA *x, DATA *y, DATA *r, DATA *rexp, ushort nx)定义在ldiv16.asm中。
  • *r = *x / *y
  • rexp—输出缓冲区指数
  • nx—输入和输出向量的元素数目(>3)


除法涉及到的Q-value见楼下。


使用特权

评论回复
wopt|  楼主 | 2015-3-12 11:22 | 显示全部楼层
本帖最后由 wopt 于 2015-3-17 21:08 编辑

3.2 Q-value

3.2.1 浮点型

在定点运算中,小数点是在一个特定的固定位置。例如,如果一个32-bit的数把小数点放在最高有效位(也就是符号位)之后,那么就只有分数(绝对值小于1)才能被显示。在定点运算系统中,虽然在硬件上实现简单,但是表示的操作数的动态范围要受到限制。使用浮点数,可以避免这个困难。
一个浮点数由尾数m、基数b和指数e三部分组成。即:
                                              m*(b^e)
下图举例说明了IEEE标准里的浮点数表示方法。这个格式用带符号的表示方法来表示尾数,指数含有127的偏移。在一个32-bit表示的浮点数中,第一位是符号位,记为S。接下来的8-bit表示指数,采用127的偏移格式(实际是e-127)。然后的23-bit表示尾数的绝对值,考虑到最高一位是符号位,它也应归于尾数的范围,所以尾数一共有24-bit。
1 8 23
S Biased  Exponent -e Mantissa  -f

比如说:十进制数-29.625可以用二进制表示为-11101.101B,用科学计数法表示为  -1.1101101*24,其指数为127+4=131,化为二进制表示为10000011B,故此数的浮点格式表示为11000001111011010000000000000000,转换成16进制表示为0xC1ED0000。又如在下面程序中将要使用的浮点数12.0,用二进制表示为1100B,用科学记数法表示为1.1*23,其指数部分为127+3=130,化为二进制表示为10000010B,因此该数的浮点数格式为01000001010000000000000000000000,转换成16进制表示为0x41400000。浮点数144.0,用二进制表示为10010000B,科学记数法记为1.001*27,指数部分为127+7=134=10000110B,该数的浮点数格式为01000011000100000000000000000000,转换成16进制表示为41300000H。



3.2.2 Q-Value
VC5509A是一款定点处理芯片,处理定点数据可以,但是难处理浮点数据。所以引入了Q格式进行浮点数据到定点的转化,节约CPU时间。Q格式表示为:Qm.n,表示数据用m比特表示整数部分,n比特表示小数部分,共需要m+n+1位来表示这个数据,多余的一位用作符合位。
例如:Q0:小数点在第0位的后面,即我们一般采用的方法。Q15 小数点在第15位的后面,0~14位都是小数位。
Q表示    S表示    十进制数表示范围
Q15       S0.15    -1≤x≤0.9999695
Q14       S1.14    -2≤x≤1.9999390
Q13       S2.13    -4≤x≤3.9998779
Q12       S3.12    -8≤x≤7.9997559
Q11       S4.11    -16≤x≤15.9995117
Q10       S5.10    -32≤x≤31.9990234
Q9         S6.9      -64≤x≤63.9980469
Q8         S7.8      -128≤x≤127.9960938
Q7         S8.7      -256≤x≤255.9921875
Q6         S9.6      -512≤x≤511.9804375
Q5         S10.5    -1024≤x≤1023.96875
Q4         S11.4    -2048≤x≤2047.9375
Q3         S12.3    -4096≤x≤4095.875
Q2         S13.2    -8192≤x≤8191.75
Q1         S14.1    -16384≤x≤16383.5
Q0         S15.0    -32768≤x≤32767

将小数表示成定点数形式的方法
  • 选择合适的Q值
  • 将小数x2^Q,然后取整数部分
以Q = 15为例:
  • 0.54321 x 2^15 = 17799.90542
  • 17800 = 0x4588 = (0100010110001000)b = 0.543212890625

以Q = 13为例:
  • -2.5467 x 2^13 = -20862.5664
  • -20863 = 0xAE81 = (1010111010000001)b = -2.5467529296875

  浮点数与定点数的转换关系可表示为:
        浮点数(x)转换为定点数(xq):xq=(int)x *  (2^Q)
        定点数(xq)转换为浮点数(x):x=(float)xq / (2^Q)

Q-Value参考资料如下

维基百科

TMS320C55x DSP Library Programmer’s Reference 附录A

DSPLIB关于Q-Value的函数
| -----------------------functions-----------------------|-------------------Description--------------|
| ushort q15tofl (DATA *x, float *r, ushort nx)   |      Q15 to floating-point conversion  |
| ushort fltoq15 (float *x, DATA *r, ushort nx)   |      Floating-point to Q15 conversion |







使用特权

评论回复
wopt|  楼主 | 2015-3-17 20:23 | 显示全部楼层
本帖最后由 wopt 于 2015-3-21 20:25 编辑

3.3 sine
TI官方文档SPRU442J的第127页中,关于sine函数Arguments介绍中x[nx]的举例应该为 0.25 = 0x2000 in q15.

方法一
泰勒级数
55_3_3_1.png
其中Rn(x)为皮亚诺余项.
sine实现的方法就是利用了泰勒级数。
55_3_3_2.png
不过后面对sin泰勒级数进行了优化。此处共享一些代码。
float abs(float x) 
{
    if(x<0) x=0-x;
    return x;
}


float sin(float x)

{

const float B = 1.2732395447;
const float C = -0.4052847346;
const float P = 0.2310792853;//0.225;
float y = B * x + C * x * abs(x);
y = P * (y * abs(y) - y) + y;
return y;
}


float cos(float x)
{
  const float Q = 1.5707963268;
  const float PI =3.1415926536;
  x += Q;

  if(x > PI)
    x -= 2 * PI;

return( sin(x));
}


float sqrt(float a)
{
   double x,y;
   x=0.0;
   y=a/2;
   while(x!=y)
   {
     x=y;
     y=(x+a/x)/2;
   }
   return x;
}


float pow(float a,int b)
{
    float r=a;
    if(b>0)
    {
      while(--b)
         r*=a;

    }
    else if(b<0)
    {
        while(++b)     r*=a;
         r=1.0/r;
    }
    else r=0;
    return r;
}

DSPLIB中sine实现的过程如下:
sin(x) = c1*x + c2*x^2 + c3*x^3 + c4*x^4 + c5*x^5
c1 = 3.140625x
c2 = 0.02026367
c3 = − 5.3251
c4 = 0.5446778
c5 = 1.800293
x为第一象限角(0—pi/2)。


利用DSPLIB提供的sine函数进行实验。库中提供的数据是随机的,不能很形象的描述sine函数。所以本次利用matlab获取一些数据。
>>x = -1 : 0.05: 1;
>>y = x.*(2^15);
>>fid = fopen('test.txt', 'wt+');
>>fprintf(fid, '%d,\n', round(y));
>>fclose(fid);
运行可以得出仿真结果如下图。
5509_3_3_4.png


方法二
sine实现的另一种方法是利用Z变换。sin(nωT)u(n)的Z变换如下
5509_3_3_3.png
其中,A=2cosωT, B=-1, C=sinωT。设初始条件为0,上式的反Z变换为:y[k]=Ay[k-1]+By[k-2]+Cx[k-1]。
设振荡器的频率为2kHz,采样率为40kHz(通过定时器设置,每隔25us中断一次,即产生一个y[n]),则递归的差分方程系数为:
A=2cosωT=2cos(2*PI*2000/40000)= 2*0.95105652
B=-1
C=sinωT=sin(2*PI*2000/40000)= 0.30901699
为了便于定点DSP处理,我们将所有的系数除以2,然后用Q15格式表示为:
A/2 = 0x79BC         B/2 = 0xc000             C/2 = 0x13C7









使用特权

评论回复
zhangmangui| | 2015-3-17 21:11 | 显示全部楼层
楼主可以出书了

使用特权

评论回复
wopt|  楼主 | 2015-3-17 21:17 | 显示全部楼层

...这个帖子都没有详细讲清楚,只是一个大概,dsp涉及的内容太广了。

使用特权

评论回复
wopt|  楼主 | 2015-3-17 21:21 | 显示全部楼层
本帖最后由 wopt 于 2015-3-21 20:21 编辑

3.4 FFT
推荐一篇**【完整版】如果看了此文你还不懂傅里叶变换,那就过来掐死我吧
傅立叶变换的物理意义是将一个在时间域当中的信号所包含的所有频率分量(主要指其各频率分量的幅度和相位)用一个以角频率为自变量的函数表示出来,称其频谱。但是并不是所有的信号都能取傅氏变换(例如当该信号不满足狄利特里条件时),所以在傅氏变换的积分函数中的积分因子上乘以一个exp(a),使之满足可积条件,是为拉氏变换。傅里叶变换是拉氏变换的特例,相当于S平面虚轴上的拉氏变换。一个信号的抽样取拉氏变换与相应的离散信号与Z变换的作用是等效的。Z变换与拉氏变换之间是一对多的映射关系,Z平面上的单位圆对应于S平面上的虚轴;Z平面上的单位圆内部分对应于S平面上的左半平面;此外,S平面是直角坐标平面,Z平面则是极坐标平面。离散傅里叶变换相当于是Z变换在Z平面单位圆上的情况(即是Z变换的特例)。

离散傅里叶变换是一种用复指数序列表示离散信号的方法,它通过频率响应函数H(exp(jw))将系统函数表示在频域中。系统对任意绝对收敛的输入序列x(n)的响应都可以表示成其变换X(exp(jw))和频率响应H(exp(jw))的乘积形式,可以方便地在频域中计算。但是傅里叶变换有两个缺点:其一,在实际中许多有用的信号,例如u(n),n*u(n)等,它们的离散傅里叶变换不存在;其二,系统对初始化条件的暂态响应,或由时变输入引起的系统响应,都无法用离散傅里叶变换方法来计算。为了克服上述两个缺点,要把离散傅里叶变换方法进行推广,推广后的方法成为Z变换。它的单边变换形式可用获得初始条件和时变输入引起的系统响应;它的双边Z变换形式提供了另一个领域,可对更多类型的序列和系统进行分析。

傅立叶变换-->非周期连续信号
傅立叶级数-->周期连续信号

时域                     频率
周期     <<--->>  离散
非周期 <<--->>  连续
离散     <<--->>  周期
连续     <<--->>  非周期

在看看两种离散序列的傅里叶变换:离散时间傅里叶变换(DTFT)和离散傅里叶变换(DFT)(全国研究生入学复试环节的面试中也会经常提这两种的区别)。前者(DTFT)用以求出离散信号的连续频谱,其定语“离散时间”意味着仅在时域离散,在频率是连续的。后者(DFT)用以求出连续频谱上的离散样本点,相当于对连续频谱进行等间隔采样,所以在时域和频域都是离散的,离散傅里叶变换由此得名。对于计算机进行实际计算,必然要把连续信号离散化,也必然要把无限长信号变成有限长信号。
名称变换
时域
频域
(连续)傅里叶变换(CFT)
连续信号
连续频谱
(连续)傅里叶级数(CFS)
周期性,连续信号
离散频谱
离散时间傅里叶变换(DTFT)
离散信号
周期性,连续频谱
离散傅里叶级数(DFS)
周期性,离散信号
周期性,离散频谱
离散傅里叶级数(DFT)
有限长离散信号(隐含周期)
有限长离散频谱(隐含周期)

FFT的位倒序: x[k1k2k3……Kn] <----->  x[Kn……K3K2K1]。
FFT的算法还是看相关教材吧。 公式太难输入了。

在DSP芯片开发系统中,FFT也都是标准的固件(函数库)。一般工程人员对FFT物理掌握的意义远大于计算。一般地,我们没有自己编写FFT程序的必要。另外,自己编的也必然远比不上官方给的程序。重要的是会应用系统中的FFT程序来解决实际问题。不是说理论无用,理论是必须要掌握的,没有理论就难以创新(N为复合数的FFT算法——混合基算法)。
以下给出DSPLIB中FFT算法的函数。
FFT
Functions Description
void cfft (DATA *x, ushort nx, type)
Radix-2 complex forward FFT − MACRO
void cfft32 (LDATA *x, ushort nx, type)
32-bit forward complex FFT
void cifft (DATA *x, ushort nx, type)
Radix-2 complex inverse FFT − MACRO
void cifft32 (LDATA *x, ushort nx, type)
32-bit inverse complex FFT
void cbrev (DATA *x, DATA *r, ushort n)
Complex bit-reverse function
void cbrev32 (LDATA *a, LDATA *r, ushort)
32-bit complex bit reverse
void rfft (DATA *x, ushort nx, type)
Radix-2 real forward FFT − MACRO
void rifft (DATA *x, ushort nx, type)
Radix-2 real inverse FFT − MACRO
void rfft32 (LDATA *x, ushort nx, type)
Forward 32-bit Real FFT (in-place)
void rifft32 (LDATA *x, ushort nx, type)
Inverse 32-bit Real FFT (in-place)

以函数void cfft (DATA *x, ushort nx, type);(defined in cfft.asm)为例

Arguments
                x [2*nx]                   Pointer to input vector containing nx complex elements (2*nx   
                                                real elements) in normal order. On output, vector contains      
                                                the nx complex elements of the FFT(x) in bit-reversed order.
                                                Complex numbers are stored in interleaved Re-Im format.
                                                输入向量x包含nx个顺序排放的复数(2*nx个实数)。输出x
                                                包含nx个位倒序排放的复数。

                nx                            Number of complex elements in vector x. Must be between 8
                                                and 1024.
                                                复数的个数,必须在8到1024之间。

                 type                        FFT type selector. Types supported:
                                                     If type = SCALE, scaled version selected
                                                     If type = NOSCALE, non-scaled version selected

Description              Computes a complex nx-point FFT on vector x, which is in normal order. The
                               original content of vector x is destroyed in the process. The nx complex elements
                               of the result are stored in vector x in bit-reversed order. The twiddle table
                               is in bit-reversed order.


说的不好,还是参考相关书籍吧。程序在DSPLIB中都有,就不举例了。


使用特权

评论回复
wopt|  楼主 | 2015-3-20 19:57 | 显示全部楼层
本帖最后由 wopt 于 2015-4-2 20:40 编辑

3.5 FIR
窗函数设计法
设计FIR滤波器的任务就是找到有限个傅里叶级数系数,以有限项傅里叶级数去近似代替无限项傅里叶级数。窗函数也称为傅里叶级数法。
常见的窗函数:矩形窗、三角形窗、汉林窗、哈明窗、布莱克曼窗、凯泽窗。
用窗函数设计FIR滤波器的步骤:
  • 选择窗函数的类型并估计窗口长度N(或阶数M=N-1)。
  • 根据待求滤波器的理想频率响应求出单位脉冲响应。
  • 计算滤波器的单位脉冲响应。
  • 验算技术指标是否满足要求。
  • 如果不满足,重复上述步骤。

用一个例子(摘自《数字信号处理教程》):
FIR低通滤波器:通带Wp=0.2pi, 阻带Ws=0.3pi, 通带波动Rp=0.25dB, 阻带衰减As=50dB。M文件
wp = 0.2*pi; ws = 0.3*pi;  deltaw= ws - wp;                % 过渡带宽Δω的计算
N0 = ceil(6.6*pi/ deltaw) + 1;        % 按哈明窗计算所需的滤波器阶数N0
N=N0+mod(N0+1,2);                % 为了实现第一类偶对称滤波器,应使其长度N为奇数
wdham = (hamming(N))';        % 求窗函数
wc = (ws+wp)/2        ;                % 截止频率取为两边界频率的平均值
hd = ideallp(wc,N);                % 求理想脉冲响应        
h = hd .* wdham;                % 设计的脉冲响应(即系数)为理想脉冲响应与窗函数乘积
[db,mag,pha,grd,w] = myfreqz(h,[1]);        % 对设计结果进行检验
dw = 2*pi/1000;
Rp = -(min(db(1:wp/dw+1)))                % 检验通带波动
As = -round(max(db(ws/dw+1:501)))         % 检验最小阻带衰减
以上仅仅针对学习而言,针对工程直接用fdatool实现即可。
另一个例子在matlab的命令窗口输入fdatool。
3_4_2.png
Targets-->Filter Design-->Code composer Studio IDE。
3_4_1.png
Generate头文件fdacoefs.h
const int BL = 14;
const int16_T B[14] = {
     -128,    215,   -339,    114,   1127,  -4694,  20089,  20089,  -4694,
     1127,    114,   -339,    215,   -128
};
上述数组用于DSPLIB库中ushort oflag = fir (DATA *x, DATA *h, DATA *r, DATA *dbuffer, ushort nx, ushort nh)函数中的*h。



频率样本法(略)

最优设计法
(略)



使用特权

评论回复
zhangmangui| | 2015-3-20 21:37 | 显示全部楼层
wopt 发表于 2015-3-12 11:20
2.10 USB
USB模块硬件结构分析
VC5509A的USB模块有16个端点(endpoint)。其中有两个控制端点,输入端点0和 ...

USB一直没搞懂

使用特权

评论回复
wopt|  楼主 | 2015-3-21 20:14 | 显示全部楼层

我也没搞懂:lol

使用特权

评论回复
cdf1214| | 2015-3-30 10:19 | 显示全部楼层
TMS320VC5509APGE含税价51.5
本公司主营TI. NXP. IR. ON. SiLicon                                                                                                       等著名世界品牌产品。
MSP430F一系列TI储存芯片 微控处理器
MSP430F149 169 249 449 1611 5438 5438AIPZR  等。
C8051F 一系列SILICON 单片机 微控处理器
C8051F020 021 022 023 040 120 310 320 330 340 350等
LPC一系列NXP单片机  
LPC2132FBD64 LPC2134FBD64 LPC2214FBD144  
LPC2378FBD144 LPC2292FBD144等一系列供应
专营:低压差 基准源 三 五 七端稳压 二三极管 场效应 快恢复 肖特基二极管 可控硅 达林顿 整流桥 TVS管 光藕 MAX AD 集成电路 
                                   销售:陈冬锋
                                     QQ:2850327057
                      电话:15711002528,13641144498

使用特权

评论回复
mobilefone| | 2015-3-31 13:15 | 显示全部楼层
点赞

期待楼主的更新

使用特权

评论回复
wopt|  楼主 | 2015-4-2 14:47 | 显示全部楼层
mobilefone 发表于 2015-3-31 13:15
点赞

期待楼主的更新

已经好久没有更新了,学车去了。 学完车就不想动。 今晚开始。

使用特权

评论回复
七颗咖啡豆| | 2015-4-2 17:00 | 显示全部楼层

使用特权

评论回复
wopt|  楼主 | 2015-4-2 17:04 | 显示全部楼层

USB作为一个外设,还是看下《圈圈教你USB》。我对USB的开发不够深入。

使用特权

评论回复
wopt|  楼主 | 2015-4-2 20:30 | 显示全部楼层
本帖最后由 wopt 于 2015-4-6 10:59 编辑

3.5 IIR
IIR滤波器设计的基本技术是利用复变函数映射把模拟滤波器转换成数字滤波器。两种设计方法:
  • 模拟低通滤波器设计-->模拟频带变换(LPF-->BPF or HPF)-->模拟变为数字-->IIR滤波器
  • 模拟低通滤波器设计-->模拟变为数字-->数字频带变换(LPF-->BPF or HPF)-->IIR滤波器

IIR滤波器设计技术是从已知的低通模拟滤波器开始设计的。常见的模拟滤波器:巴特沃斯、切比雪夫和椭圆。
椭圆滤波器提供了最优的平方幅度响应,但通带上的相位响应非线性较大。巴特沃斯滤波器的幅度响应是单调的,为了得到相同的阻带指标,它需要更高的阶数(更多的极点),然而它在通带上具有相当线性的相位响应。切比雪夫滤波器的相位特征介于两者之间。
复变量s到复变亮z之间的映射,必须满足一下三条基本要求:
  • s平面的虚轴必须映射到z平面的单位圆上,也就是频率抽要对应。
  • s平面的左半平面必须映射到z平面单位圆的内部。
  • 变换前后的滤波器在时域或频率的主要特征应尽可能接近。

模拟滤波器-->数字滤波器的两种方法:双线性变换法和脉冲响应变换法

DSPLIB库中,
Function ushort oflag = iir32 (DATA *x, LDATA *h, DATA *r, LDATA *dbuffer, ushort nbiq,  ushort nr)

Arguments
                          x [nr]                  Pointer to input data vector of size nr // 输入数据                                                   
                          h[5*nbiq]           Pointer to the 32-bit filter coefficient vector with the // h[n]                                                   
                                                    以下的b21...a12与IIR的结构有关,看下IIR的表达式就豁然开朗了。
                                                    following format. For example for nbiq= 2, h is equal
                                                    to:
                                                    b21 – high         beginning of biquad 1
                                                    b21 – low
                                                    b11 – high
                                                    b11 – low
                                                    b01 – high
                                                    b01 – low
                                                    a21 – high
                                                    a21 – low
                                                    a11 – high
                                                    a11 – low
                                                                              
                                                    b22 – high        beginning of biquad 2 coefs
                                                    b22 – low
                                                    b12 – high
                                                    b12 – low
                                                    b02 – high
                                                    b02 – low
                                                    a22 – high
                                                    a22 – low
                                                    a12 – high
                                                    a12 – low

                      r[nr]                      Pointer to output data vector of size nr. r can be equal or less than x.// 输出数据
                     dbuffer[2*nbiq+2] Pointer to address of 32-bit delay line dbuffer. Each biquad has 3 consecutive delay line elements. For example for nbiq = 2:
                                                   数据缓冲区,每一个二阶有3个连续的延迟单元。                           
                                                   d1(n−2) − low        beginning of biquad 1
                                                   d1(n−2) − high
                                                   d1(n−1) – low
                                                   d1(n−1) – high

                                                   d2(n−2) − low       beginning of biquad 2
                                                   d2(n−2) − high
                                                   d2(n−1) – low
                                                   d2(n−1) – high

In the case of multiple-buffering schemes, this array should be initialized to 0 for the first block only. Between consecutive blocks, the delay buffer preserves the previous elements needed. Memory alignment: none required for C5510. This is a group of circular buffers. Each biquad’s delay buffer is treated separately. The Buffer Start Address (BSAxx) updated to a new location for each biquad.

                  nbiq                         Number of biquads
                  nr                            Number of elements of input and output vectors
                  oflag                        Overflow flag. // 溢出标志
                                                 If oflag = 1, a 32-bit overflow has occurred
                                                 If oflag = 0, a 32-bit overflow has not occurred


性能上:IIR滤波器 优点是存储单元少、效率高。缺点是相位非线性。对于同样指标的滤波器FIR滤波器所要求的阶数比IIR滤波器高,导致的结果就是信号延时大,但是FIR滤波器却可以得到严格的线性相位。

结构上:IIR滤波器采用递归结构配置结点,无限长冲激单位响应。
              FIR滤波器采用非递归结构,有限长冲激单位响应。所以较IIR不存在稳定性问题,频率特性误差小。


应用上:IIR在对相位要求不敏感的场合,例如语音通信等。 对于图像信号处理、数据传输等以波形携带信息的系统,则对线性相位要求高。


使用特权

评论回复
发新帖 本帖赏金 5.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则