This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

【活动结束】别等了! 快来参与!!! 免费工具等你拿!

Other Parts Discussed in Thread: TMS320F2812, TMS320F28335, ADS805, CONTROLSUITE, SPRC087, CCSTUDIO, ULN2003A, TMS320F2808, LAUNCHXL-F28027, TMS320F28035, TPS3307, LM258, TMS320F28027, TMDSHVBLPFCKIT, TLV320AIC1106, ADS8482, TMS320LF2407A, LM393

为配合C2000 DAY的强势推出,2012 10 8  11 9 ,我们诚邀您来分享您在学习或工作中关于应用 TI C2000 产品的设计心得

我们相信业内同仁的分享和交流为彼此提供宝贵的经验借鉴,同时真诚希望 TI 官方社区成为大家共同学习和探讨技术的一个网上家园!

发贴要求(不符合下面要求将不具备获奖资格)

- 每篇有关C2000的主题不少于 300

- 内容要求必须清晰详细写出设计心得的具体过程(例如设计中使用哪款产品碰到的问题及其解决的方法和步骤。)

- 发表以跟贴形式,需为原创贴 (最好同时配上合适的图片或视频)

奖项设置
征文奖交由 TI 技术专家团队评选,TI拥有最终解释权!
优秀分享奖(封顶50名): LAUNCHXL-F28027  和 TMDX28069USB  各一个
阳光普照奖 (封顶100):LAUNCHXL-F28027 一个
每个ID只有一次获奖机会
每周做一次审核。先到先得!
  • TI  C2000学习分享

    一.C2000全套软硬件资料

    controlSUITE软件是TI针对C2000推出的可支持实时控制应用的软件,相较于传统的MCU,controlSUITE软件可为简化评估、应用调适、除错、测试及重复使用,提供内容及必要的内容管理。除包含一般免费软件产品常见的简单范例外,还为马达控制等应用,提供可做为真正开发系统使用的全面开放原始码数据库与范例。此外,全新安装程序还可消除版本更新与依赖性等问题,并让开发人员能够于同一地方获得完整的软件产品。

    下载链接:http://www.ti.com.cn/tool/cn/controlsuite

    通过controlSUITE,工程师可以获得C2000全套的、开源的软硬件资料。以下为升级后的目录参考,大家可以下载此软件后,自动在线升级。

     

     

    二.TI C2000的系列

     

    二.C2000的应用

     

    三.C2000 Piccolo LaunchPad LAUNCHXL-F28027

     

    四.编程开发环境

    Code Composer Studio:集成型开发环境 (IDE)

     

    五.学习TI提供的例程

    这里面有中英文显示的,大家可以自己选择

    这是Piccolo F2802x0系列工程的例子工程

    点击此处打开例子目录,我们可以复制其例子

     

    1.在其中controlSUITE软件的中文显示不知为何为乱码

     

    可以是翻译的问题或者为中文的简体与繁体的转换问题

    2.CCS软件的使用

    在用CCS前需要选择相应的芯片,这个和用Keil uVision4一样,软件的使用也是类似的。

     

     老是编辑不好,见附件里的文本吧。呵呵

    菜鸟,望大家见谅。呵呵

     

     

    TI C2000学习分享.pdf
  • 中午休息,分享一下我自己在学TMS320F2812DSP遇到的一些小问题。纯粹自己理解,错误之处望见谅,多指正。

    首先,是延迟函数的使用:在做电机调速时,发现自己用C简单编写的延迟delay函数,会出现实际延迟时间与程序设定时间误差较大的情况,查阅一些资料,发现可以利用例程里已有的延迟汇编文件,编写较为准确的延迟函数DELAY-US(),且调用简单可靠。具体步骤如下:1,下载DSP281x_usDelay.asm文件,将内容改为

    extern void DSP28x_usDelay(Uint32 Count);

    .def _DSP28x_usDelay

    .sect "ramfuncs"

    .global __DSP28x_usDelay

    _DSP28x_usDelay:

    SUB ACC,#1

    BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0

    LRETR

    放于工程的source中;

    2,在MOTOR.H文件中定义

    #define CPU_RATE 6.667L // for a 150MHz CPU clock speed (SYSCLKOUT)

    #define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    3,在GlobalPrototypes.h中定义

    extern void DSP28x_usDelay(Uint32 Count);

    4, 在程序中直接调用DELAY_US(A),例如 DELAY_US(1000L);,表示延迟1ms 。

    其次,是2812flash烧写的问题,具体步骤如下:(1) 下载烧写FLASH配套CMD文件、LIB文件以及起始代码asm文件。

    CMD文件名称:DSP281x_Headers_nonBIOS.cmd

    CMD文件名称:Flash.cmd

    LIB文件名称:rts2800_ml.lib

    ASM文件名称:DSP281x_CodeStartBranch.asm

    (2)配置C文件

    配置好主程序的C文件,才能将FLASH成功烧录,并且将FLASH中的文件拷贝到RAM中运行。

    关于C文件的配置。

    首先在F2812.CMD文件中,我们可以看到有关于加载FLASH到RAM的内容:

    ramfuncs : LOAD = FLASHD,

    RUN = RAML0,

    LOAD_START(_RamfuncsLoadStart),

    LOAD_END(_RamfuncsLoadEnd),

    RUN_START(_RamfuncsRunStart),

    PAGE = 0

    以及在C文件中调用FLASH 到RAM的函数memcpy,将它放在系统初始化(InitSystem();)之后即可:

    InitSystem();

    memcpy(&RamfuncsRunStart,

    &RamfuncsLoadStart,

    &RamfuncsLoadEnd - &RamfuncsLoadStart);

    Initflash();

    关于ramfuncs,则在系统初始化中定义即可。如:sysctrl.c中

    #pragma CODE_SECTION(InitFlash, "ramfuncs");

    (3)我们需要定义所用变量:

    extern Uint16 RamfuncsLoadStart;

    extern Uint16 RamfuncsLoadEnd;

    extern Uint16 RamfuncsRunStart;

    我的这些定义都是:DSP281x_GlobalPrototypes.h 当中,当然,也可以放在其他系统初始化的地方。

    Memcpy这个函数应该是rts2800_ml.lib库文件中自带的,不需要我们定义。

    (4)烧写成功后的注意事项:

    1. 一定要拔除仿真器(JTAG端),给电路板重新上电,方能实现FLASH启动。

    2. 注意MP/MC引脚的电压。0为方式MC来作为计算机模式启动,3.3V为方式MP作为微处理器模式启动。

    3. 由于GPIO引脚的F4\F12\F3\F2决定了DSP2812的启动顺序,而从FLASH必须要在F4(SCITXDA)为1,而F12\F3\F2随意的状态下启动。请大家启动前确认F4引脚电压。

  • DSP开发中,中断处理对数据的影响.

    我一直在工业控制领域做开发,其中,TI的DSP应用在多种设备上,无论人们怎么说使用arm去替代这些DSP,结果还是继续使用它。我开发时候使用的是2406,现在TI已经不建议用户去使用这个产品去做研发了。当时使用的还是3.0的版本,这个版本的flash烧写需要单独一个软件,直到3.3才把这个软件集成到CCS里面。硬件平台使用的TMS320LF2406AP。

    在开发时候,需要大量的浮点运算,急的找运算库,很快就在CCS里面发现浮点运算库。

    我们需要做一个转速检查的卡件,也就是一般人说的测速功能了,这个是对每个采样信号进行频率分析,计算出总平均,开发过程很顺利,最后进入测试阶段,我们发现一个问题,就是总是有0.5-1转的误差,现场要求的误差是最大0.5转,这需要马上改进,检查所有代码和过程没有发现那里出了问题,验算了算法也没有出现漏子,检查了波形发现非常nice,最后终于在中断处理中发现有可能的问题,也就是由中断进行的采样处理过程中,进出中断处理需要时间,虽然很小,但是在成千上万次采样中,由于累积误差的产生,就发生了上述情况。我及时添加了校验系数,测试结果和测试平台要求达到一致。

    在现场实施中,又产生一个问题,就是当设备没有开动时候,上位机显示为有数值,几个人忙活半天,由总线检查到机柜,上位机都进行检查,最终发现是因为在测试卡件的计算中,频率和转速是倒数关系,因为添加了矫正系数,当没有输入时候,频率是有数值的,频率为0 时候矫正系数的出现造成异常数值的出现。后来对矫正参数进行分段处理,解决了问题。

    在DSP中,经常需要对中断读取的数值进行平均统计,由于dsp的高速处理过程,很多时候会忽略中断进入和退出是有时间积累的,从而造成积累误差对精度的影响。

    当然在dsp开发中还有其他各式各样的事情,比如我是用汇编进行dsp和单片机编程的,这个过程中最难过的就是背诵指令,真的很晕的,还有内存的页面读取,对于在多种单片机上做过汇编的我来讲,DSP的内存访问确实是很痛苦、很纠结的事情。

    这几年面临很多芯片停产问题,比如我们以前用的AM79C874、Net50,而且同时进行了大量的移植工作,如果不是参加这个活动,我也不是很清楚2406也有停产问题,又要面对移植,移植的路是漫漫修远,希望以后用CCS5的DSP开发可以让我无扰进行移植工作。

     

  • 经过本周FAE的评估,下面的朋友们获得优秀分享奖:

    chun liang yang;   yy vu;   zhilong ding;   jiangwei zhou;   yinyue;    billjing;    tihan li;   feifei zhuang;    zhiguang li ;   hwang ce;

    此外,符合评奖资格的朋友们获得阳光普照奖。我们物流公司会尽快与上述朋友联络。

  • 第一周落榜了  还得加油啊

  • 感谢TI,很是激动呀!!!!!!!!!!!!!!

  • 看到这个活动很激动,我也贴一个我刚开始接触DSP遇到的一个问题,感谢发达的网络,我终于锁死的芯片解锁了,现在开始讲解如何操作的吧!

    关于装载DSP程序到FLSH中误锁的解决办法

             对于很多刚入门的朋友来说,装载DSP的程序进入FLASH是一件十分谨慎的事,因为很有可能因为操作不当,而把芯片锁死。当很多朋友会

              根据得到的.out文件,通过hex2000.exe来得到相应的ASCII码文件,文件中 00 08 00 3F 7F F8 EE EE FF FF FF FF FF FF FF FF FF FF FF FF FF FF 为密码区,其中00 08 00 3F 7F F8为密码区地址,后面16组为实际密码,LSB到HSB。

    需要:对应的.out 和.map文件,分别用来生成hex文件和查看链接关系。

         配置:build.bat 批处理文件,用windows的命令提示符来得到所需要的hex文件,编码为ASCII;用记事本打开 内填写hex2000.exe在你电脑中的目录 build.cmd 命令文件,采用hex2000.exe程序选项命令来得到所需文件。

          具体命令 : -memwidth 16 设定存储器格式为16bit ,不用管 -romwidth 16 设定rom格式为16bit&,不用管 -a 设定输出文件格式,填写你的.OUT名如我的是Tlv320aic23x.out -o 设定输出文件名,随便起个名字,是你得到密码的文件名 -map 设定输出映射文件,填写你的.map名 如我的是Tlv320aic23x.map -boot 设定引导数据流,不做操作 hex2000.exe 程序文件, ccs自带的,路径为..\C2000\cgtools\bin\hex2000.exe 更多有关此程序的命令选项请参考相关资料。 00 3F 7F F8 这段数字后的数据为地址003f7ff8中的内容,也即密码区的首字节,根据前面得到的ascii格式的文本文件,搜索3F 7F数据组合,然后其后的就是实际烧进去的数据。如果是错误烧写锁定DSP的话,则把后续的指令代码作为密码写进去即可,一般为32bit,程序长跳转二进制代码。如果是自己烧写了代码,则后续的16组数据即为所设密码。 具体写的是什么,可以参考对应的.map文件,其中列出了所有symble,以及他们的输入输出段,可以看到003f7ff8地址中对应的是那个symble和所占字节数。

    33753132Flash-.rar
  •  

    基于TMS320F2812的平动电机的控制系统设计             

           这个课题是上研究生的时候进行的一个课题 采用了TI C2000系列中的2812控制芯片

            主要研究了基于TMS320F2812PGFA的DSP数字信号处理器的驱动程序开发与平动电机控制系统的开发,并实际开发了电机的驱动系统。包括:平动电机控制研究,平动电机驱动系统的研究,传感器信号处理硬件研究,DSP芯片内部核心技术研究,芯片驱动程序编写,控制系统控制软件编写,上位机控制程序的编写等。

    一、下面首先为大家介绍一下平动电机的基本知识:

     

              平动式啮合电动机突破了传统旋转电动机的设计理念,属于集电机、减速机于一体的低速电动机。电机转子相对于定子只有平动没有转动,从而避免了传统电机转子相对定子旋转一周而造成作用距离长、响应速度慢、低速工况不稳定、输出扭矩小等弱点。采用机电一体化设计,将电机的转子内圈设计成永磁体,并与定子磁场相互作用产生平动公转的驱动力,同时将转子外圈设计成齿轮与电机最外圈的定轴齿轮啮合起减速作用,最后通过电机最外圈齿轮输出低转速大扭矩。它的核心思想是通过外层齿轮啮合与内层定转子间的电磁作用力相配合,缩短定子与转子间的作用距离,增大作用力,使减速机和电动机真正成为一个整体。该电机轴向尺寸小、结构简单紧凑、无间隙传动、启动快、并具有一定自锁功能。目前在国内外报道中还没有见过具有相同设计思想和结构的电动机,它可以应用于工业机器人、航空航天业领域等对空间尺寸和重量要求严格、以及要求较高输出力和锁止功能的工业领域。

     

    二、设计初期采用了2407作为控制芯片,熟悉了之后换为2812,下面说一下2407和2812的区别:


    TMS320LF2812芯片工作频率比TMS320LF2407高,而且TMS320LF2812有专门的中断控制系统是中断控制更加灵活。28x系列芯片能够向下兼容24x系列的代码,在系统升级的时候可以利用以前的代码,避免重复性工作。

    三、串行通信部分


    在计算机测控系统中,数据通讯主要采用异步串行通讯方式。在设计接口时,必须根据需要选择标准接口,并考虑传输介质、电平转换和通讯控制芯片等问题,以保证通讯的可靠性、通讯速度、通讯距离和抗干扰能力。RS232是异步串行通讯中应用最广泛的标准总线,它包括了按位串行传输的电气和机械方面的规定。由于TMS320LF2812PGFA芯片采用的是CMOS工艺制造,使用+3.3供电,而上位机PC机是RS.232标准的电气,两者互不兼容,所以在设计两者接口时,必须进行电平转换。下面是原理图:

    四、JTAG仿真接口部分:



    JTAG最初是用来对芯片进行测试的,基本原理是在器件内部定义一个TAP(TestAccess Port:测试访问口)通过专用的JTAG测试工具对进行内部节点进行测试。JTAG测

    试允许多个器件通过JTAG接口串联在一起,形成一个JTAG链,能实现对各个器件分别测试。现在,JTAG接口还常用于实现ISP,对FLASH等器件进行编程。JTAG编程方式是在线编程,传统生产流程中先对芯片进行预编程现再装到板上因此而改变,简化的流程为先固定器件到电路板上,再用JTAG编程,从而大加快工程进度。JTAG接口可对PsD芯片内部的所有部件进行编程。

    下面是jtag仿真接口的原理图:

    五、DSP软件流程


    本系统整个软件采用模块化设计,由各个功能相对独立的子程序有序地组成一个完整的控制系统软件,其中主程序采用中断的方式进行子程序调用。控制系统软件的主要子程序有:1、功率保护中断服务子程序,2、定时器中断服务子程序,3、加转换子程序,4、串口通信子程序,5、CAN接口程序,6、电PWM脉冲输出子程序。主程序的作用是完成处理器(TMS320F2812)的初始化,包括设定管脚功能、中断设置、事件管理器的初始化、变量初始化等,主要是为随后的子程序创造环境。

    下面是软件的流程图部分:

    六、课题总结


    本课题主要是以平动啮合电机为控制对象、以数字信号处理器TMs320F2812PGFA为控制核心,对平动电机控制系统的结构、软硬件设计和CAN现场总线通讯等方面对全数字交流传动系统进行了深入的研究,取得了一些有意义的成果。

    由于本课题设计初期选用了2407作为控制芯片来熟悉TI的DSP芯片 但是做了开发板下面将其与大家一起分享:

    照片可以见附件

     

     

     

  • 首先非常感谢TI和deyisupport一直以来给我们学习者和开发者提供这么多机会!

    学习DSP有一段时间了!一直都是借用的TI 以TMS320F2812为主芯片的一块板子上实现的,因为使用时间不能保障,学习进度有点慢,

    前一段时间主要熟悉了存储器映射结构,GPIO的控制,看门狗,ADC,SPI,学习中是通过在线,在RAM中运行的。

    做完上面后,需要将程序固化,就要用到FLASH操作了!

    了解一下TMS320F2812的存储模式:采用哈佛总线结构,具有统一的存储模式,包括4M 可寻址程序空间和4M 可寻址数据空间。同时片内具有128 ×16 位的FLASH 存储器和18K ×16 位的SRAM,以及4K×16 位的引导ROM。最大支持外扩512K×16 位的SRAM 和512K×16 位的FLASH。具有两个事件管理器(EVA、EVB)以及外设中断模块(PIE),最大支持96 个外部中断。TMS320F2812 的外部存储器接口(XINTF)被映射到5 个独立的存储空间。所以感觉Flash这一块肯定是一个很可玩的一部分!

    在写FLASH的时候还发生了一个很悲剧的事情!

    因为不小心在工具少些的时候碰到板子,造成复位,flash被锁死了,暂时没有找到解锁的办法,只好买了一块!

    查看TI的文档,原来在擦除flash阵列前后,不能时进行复位,这样会使pwl中的值为0,导致flash被锁死,所以每次往flash里面写东西都很担心,后来发现只要在擦出前后不断电,基本上不会发生问题,这样写了很多次都是OK的!

    2812烧写flash后让程序运行在RAM中的方法

    F2812的程序在仿真状态下调试好了以后,要移植到脱机运行并不难,一个很简单的方法,打开外围接口例程中的FLASH工程,把文件添加到这个工程中去,用F2812.CMD更换原来你的程序里面的CMD.编译通过后,通过烧写插件下载,就可以脱机运行了。

    接口链接图:

     

    烧写流程:

     2812烧写flash后让程序运行在RAM中的方法

    1、CMD文件:需要开一个专用的RAM区(如RAML1)用来放程序代码,开一个专用的flash区(如FLASH_4)放置这些关键代码;具体如下:
    ramfuncs:      LOAD = FLASH_4            PAGE = 0
                      RUN = RAML1                PAGE = 1
                      RUN_START(_RAM_RAMFUN_BEGIN),    /*Define the run_Begin Adrress*/
                      LOAD_START(_FLASH_RAMFUN_BEGIN),
                      LOAD_END(_FLASH_RAMFUN_END)
    2、FLASH到RAM转移代码:
    void InitRamFuncs(void)
    {
            // Copy the Codes from the Flash to the Ram Sections.
     memcpy((void*)&RAM_RAMFUN_BEGIN,(void*)&FLASH_RAMFUN_BEGIN,&FLASH_RAMFUN_END-&FLASH_RAMFUN_BEGIN); 
    }
    在初始化完芯片后运行这段程序就可以跑起来了。

    注:在F2812烧写flash时 .cmd文件中需要将.text分配在FLASH中

    学习总结:

    多查找资料,TI官方,还有网友提供很多相关的资料!可以在第下模块动手前好好先一下手册和例程;

     再次感谢!资料完善中!

    C2000+FLASH.doc
  • 随着电子技术的不断进步,特别是3C(计算机、通信、消费电子)的飞速发展,电子设备日趋数字化、小型化和集成化,嵌入式芯片逐渐成为设计开发人员的首选。DSP作为嵌入式芯片的典型代表之一,在信息产业领域得到了广泛应用。 

           DSP
    虽然为3C产品的开发提供了很好的硬件支撑平台,但设计者仍得花费一定的时间去掌握DSP内部各种寄存器的正确设置、软件编程方法以及控制算法设计,这必然会增大产品开发难度,延长产品开发周期,从而影响开发效率。Matlab公司最新推出的针对DSP应用控制系统而开发的嵌入式目标模块Embedded Target for TI C2000 DSP即可解决上述问题,用户通过使用该模块,不仅可以进行电路的系统级仿真,还可编译生成相应的C语言代码,并下载到目标板,直接运行程序,进行算法的探索与设计思路的验证,提高开发效率.

    嵌入式目标模块在DSP系统开发中的应用.doc
  • 1C2000具体这个东西是干什么用的 有什么功能

    答:  C2000 没什么神奇的,就是单片机而已。C2000 一般用在光伏逆变器、数字电机控制、数字电源等领域。相比于其他 MCU 来说,C2000 的核心是 DSP 核心,所以数学运算能力强,适合于运算各种复杂的控制算法;其次它的中断响应速度快,可以快速进入中断处理突发事件,也就是实时性好。 F28069 在 Piccolo 系列中算是高端产品了,带浮点运算能力,80Mhz 的主频,PWMADC 等外设一应俱全,详细的信息可以上 TI 网站上看看。 比较典型的应用就是电机控制,众所周知,DSP 最早就是为了控制电机而诞生的。到目前为止,电机的控制算法越来越复杂,对计算能力要求也相应提高,在同档次的 MCU 中(如 C2000M4),C2000 比较受亲睐,一是因为它已经诞生许久,稳定性好,其次性能确实强,M4 等后起之秀性能也绝对不差,但还没有收到市场的考验。

    2现在要做TI DSP TMS320F28035的开发,需要购买仿真器,想采用TI原装XDS100V2,可是看说明不支持RTDX(实时数据交换),不知道这个对项目开发有影响吗?

    答:这个特性是用于把目标板上的数据通过JTAG传递到开发环境,如果你不用bios操作系统的话就用不到。

    3C2000系列DSP采用什么总线结构?

    答:增强的哈佛架构

    4主程序里面,有这么一句,求解释,是调用函数,还是定义什么数据,结构体,共用体?

    答: main函数完成的功能是device configuration and initializationthen wait for interrupt pwm是一个结构体或是一个类,它的作用是产生PWM(脉宽调制)波形输出(个人猜测),initpwm结构体/类中的一个成员函数,它的作用是对pwm进行初始化。pwm.init(&pwm) 的作用就是调用pwm的成员函数init,并对pwm结构体/类初始化。

    5DSP输出PWM的程序,程序能使用调节占空比。谢谢大家帮帮忙吧?

    答:  占空比可以调节,SPWM就是占空比不断变化的PWM波形。你可以用EV事件管理器来做,比较寄存器通过中断不断的读取新的值,这样就可以实现占空比的调节。

    6ti公司DSP C2000系列中有个概念老是搞不明白:里面很多次都提到数据程序这两个词,也分有数据存储区和数据存储区,请问到底什么是程序,什么是数据啊?

    答:数据指的是DSP运行中,处理器中计算、处理的数据,它是动态的;程序指的是用户编写的程序,用来控制程序的运行,指导数据的计算和处理。数据存储区用来存储数据,可以读写;程序存储区用来存已编好的程序,只读不能写。

    C2000问题集锦.doc
  • 在TI C2000定点DSP的快速实现取整函数的一点心得

    floor与ceil函数都是C语言的标准库函数,在<math.h>头文件引用之后一般即可直接调用。在浮点DSP上,通过TI 的FastFPU库,此类浮点函数一般可以通过查ROM的方法快速计算得到。但在定点的DSP,比如C2000中常用的TMS320F2812上,则需做一定的处理,以提高执行效率。我们知道,在浮点DSP上一般有专门的浮点协处理器FPU来完成浮点运算,而在定点DSP上直接计算浮点运算需要消耗大量的处理能力,将浮点运算转换为定点来计算是唯一的选择。
    在一个用到floor与ceil函数的具体实验中,我采用了TI公司的TMS320F2812定点DSP,采用C语言编程并使用TI公司定点处理智能数学运算(IQmath)。以对Vrab求取floor与ceil值为例,得到以下代码

    /*floor and ceil calculation*/

    _iq Uab,temp;

    Uint16 fab,cab;

    if(Uab>=0) {

    fab=_IQint(Uab);

    temp=_IQfrac(Uab);

    cab=(temp||0)+fab;

    }

    else{

    cab=_IQint(Uab);

    fab=cab-1;

    }

    经测试,若采用C语言的标准库函数ceil与floor,计算六次floor与ceil与值需要耗费4118个时钟周期,而改写之后,求取六个值只需要137个周期,大大节省了计算时间;以DSP的时钟周期为例,则执行时间从4118*6.67ns=27.47us,缩短到了137*6.67ns=0.91us,运算速度得到极大的提高。

    在此,顺便讲一下CCS中如何计算程序的执行时间:

    首先是打开ccs,建立工程,编译程序,解决错误。。。这个过程不多讲,最后自然是下载程序。

    其次,在ccs的工具栏中点击Profile---Clock---View,就可以在ccs的左下角看到时钟周期数了。。然后还需要再来一遍Profile---Clock---Enable,则使能了时钟评估这个选项。

    其次,在需要被测试的程序两端加入断点,然后运行程序。。程序运行到第一个端点停止后,双击一下右下角的计数值,则它就能清零了。然后再运行一下程序,此时程序运行到第二个端点停止,这时的右下角的数值就是执行这段程序所用的时钟周期数。当然,考虑上插入断点所带来的处理器开销,实际的执行时钟周期要稍微小于所显示的值。

  • TMS320F2812的C语言心得记录

    如何把自己所定义的结构体放在一个主程序中使用

    我原打算定义一个结构体方便自己对一些变量方便使用,下面是我对定义体的总结:

    首先,应该把该头文件加入到DSP_28Device.h的头文件当中去,再到DSP28_GlobalVariableDefs.c文件中写入相应的定义段,并在CMD文件中定义一个区域就可以使用了,针对我自己的结构体(见如下定义所写的),我所写的定一段是

    #pragma DATA_SECTION(BaseRegs,"BaseRegFile");

    volatile struct BASE_REGS BaseRegs;    

    以下是我在一个".h"文件中定义的一个结构体:

    ////////////////////////数字输入输出功能定义的结构体////////////////////////////////

    struct PARAMETER{

     Uint16 VALUE;    

     Uint16 DEFAULT ;

     Uint16 INDEX ;  // can be saved to EEPROM by this

     Uint16 TYPE ;  // 0: cann't be modified when motor running 1: can be modified in anytime

     Uint16 SCALE ;  // 0: VALUE need not recalculate when using  ; >0 Real Value = (VALUE / SCALE);

    };

    struct DIO_REG{

     struct PARAMETER DIProp; //F3.16,输入端子极性设定

     struct PARAMETER DI1;  //F3.8,输入端子X1功能选择

     struct PARAMETER DI2;  //F3.9,输入端子X2功能选择

     struct PARAMETER DI3;  //F3.10,输入端子X3功能选择

     struct PARAMETER DI4;  //F3.11,输入端子X4功能选择

     struct PARAMETER DI5;  //F3.12,输入端子X5功能选择

     struct PARAMETER DI6;  //F3.13,输入端子X6功能选择

     struct PARAMETER DI7;  //F3.14,输入端子X7功能选择

     struct PARAMETER DI8;  //F3.15,输入端子X8功能选择

     struct PARAMETER DOProp; //F3.25,输出端子极性设定

     struct PARAMETER DO1;  //F3.17,输出端子Y1功能选择

     struct PARAMETER DO2;  //F3.18,输出端子Y2功能选择

     struct PARAMETER DO3;  //F3.19,输出端子Y3功能选择

     struct PARAMETER DO4;  //F3.20,输出端子Y4功能选择

     struct PARAMETER DO5;  //F3.21,输出端子Y5功能选择

     struct PARAMETER DO6;  //F3.22,输出端子Y6功能选择

     struct PARAMETER DO7;  //F3.23,输出端子Y7功能选择

     struct PARAMETER DO8;  //F3.24,输出端子Y8功能选择

    };

    struct USERDIO_BITS{

     Uint16 bit00:1;

     Uint16 bit01:1;

     Uint16 bit02:1;

     Uint16 bit03:1;

     Uint16 bit04:1;

     Uint16 bit05:1;

     Uint16 bit06:1;

     Uint16 bit07:1;

     Uint16 bit10:1; //  0: low level active 1: high level active

     Uint16 bit11:1; //  0: low level active 1: high level active

     Uint16 bit12:1; //  0: low level active 1: high level active

     Uint16 bit13:1; //  0: low level active 1: high level active

     Uint16 bit14:1; //  0: low level active 1: high level active

     Uint16 bit15:1; //  0: low level active 1: high level active

     Uint16 bit16:1; //  0: low level active 1: high level active

     Uint16 bit17:1; //  0: low level active 1: high level active

    };

    union USERDI_REG

    {

     Uint16 word;

     struct USERDIO_BITS bit;

    };

    union USERDO_REG

    {

     Uint16 word;

     struct USERDIO_BITS bit;

    };

    struct UserDIO_REGS

    {

     union USERDI_REG UserDI_reg;

     union USERDO_REG UserDO_reg;

     struct DIO_REG DIO_reg;

     Uint16 RUN;   //数字输出功能表中,变频器正在运行的标志位

     Uint16 FG;    //数字输出功能表中,频率到达信号的标志位

     Uint16 FGT1;   //数字输出功能表中,频率水平检测信号1的标志位

     Uint16 FGT2;   //数字输出功能表中,频率水平检测信号2的标志位

     Uint16 OL;    //数字输出功能表中,过载信号的标志位

     Uint16 UV;    //数字输出功能表中,欠压脉冲封锁的标志位

     Uint16 EF;    //数字输出功能表中,外部故障停机的标志位

     Uint16 UF;    //数字输出功能表中,到达频率上限的标志位

     Uint16 BF;    //数字输出功能表中,到达频率下限的标志位

     Uint16 STANDBy; //数字输出功能表中,变频器准备好运行的标志位

     Uint16 Fault;  //数字输出功能表中,变频器故障的标志位

    };

    extern volatile struct UserDIO_REGS UserDIORegs;

    void Figure_InputFunction(void); //数字输入函数

    void Figure_OutputFunction(void); //数字输出函数

    //////////////////////////////////////////////////////////////////////////////

    定义完后还需要在DSP28_GlobalVariableDefs.c中加入的语句是:

    #pragma DATA_SECTION(UserDIORegs,"UserDIORegFile");

    volatile struct UserDIO_REGS UserDIORegs;

    然后在".cmd"文件中加入的区间定义:

    UserDIORegFile   :> PAR_REG, PAGE = 1

    **************************************************************************************************************

  • DSPdigital signal processor)是一种独特的微处理器,是以数字信号来处理大量信息的器件。它不仅具有可编程性,而且其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器,是数字化电子世界中日益重要的电脑芯片。

          DSP虽然为3C(计算机、通信、消费电子)产品的开发提供了很好的硬件支撑平台,但设计者仍得花费一定的时间去掌握DSP内部各种寄存器的正确设置、软件编程方法以及控制算法设计,这必然会增大产品开发难度,延长产品开发周期,从而影响开发效率。Matlab公司最新推出的针对DSP应用控制系统而开发的嵌入式目标模块Embedded Target for TI C2000 DSP即可解决上述问题,用户通过使用该模块,不仅可以进行电路的系统级仿真,还可编译生成相应的C语言代码,并下载到目标板,直接运行程序,进行算法的探索与设计思路的验证,提高开发效率。

      图1 Embedded Target for TI C2000应用流程示意图

          TI C2000 DSP的特点及开发应用流程

      作为一种专用的集成开发环境,Matlab公司最新推出的Embedded Target for TI C2000 DSP 开发平台能够让设计人员直接进行()实物仿真、算法的探索与研究,以及产品可靠性的验证,从而有效地减少了设计开发过程中的消耗,加快了原型开发的速度。该平台有如下几个优点:

      1) TI C2000 DSP 上自动测试、执行Simulink仿真模型;

      2) 提供模块化的系统和功能,比如PWMADCCAN以及目标板载内存等;

      3) 生成文档化的易读可编辑的C语言代码,并生成Code Composer Studio项目文件;

      4) F2407 eZdsp评估板和F2812 eZdsp评估板上进行自动化实时测试;

      5) TI推出的IQmath Library提供模块化的支持,可以用于仿真和代码生成;

      6) 可以进行定点系统的设计、仿真、自动定标和代码生成工作。

          Embedded Target for TI C2000 DSP提供了将MATLABSimulinkTI eXpressDSP工具、TI C2000 DSP控制器集成在一起进行系统开发的手段。通过Real-Time WorkshopTI的开发工具将Simulink模型转变为实时C代码,这样就可以利用这些产品在TI C2000 DSP系统上(F2812 eZds评估板和F2407 eZdsp评估板等)实现自动代码生成、产品原型和嵌入式系统实现,并可实时进行算法验证,极大地提高了开发效率。另外,该模块还有强大的可扩充能力,用户可以增加自己的代码、中断服务程序、IO设备驱动到CCS(Code Composer Studio)的工程项目中,这样就可以直接驱动自行开发研制的控制板卡或第三方的硬件设备板卡,完成产品的设计。采用该平台,开发人员不用编写一行代码,就可以完成几乎所有设计、仿真和编程下载的工作,整个开发流程如图1所示。

     

          2 DSP逆变控制器接口示意图

      图3 MatlabDSP应用模块仿真及下载示意图

          应用实例

          下面以一个基于DSP TMS320F2812芯片的带CAN2.0B网络接口的数字逆变控制器的设计为例,介绍利用Embedded Target for TI C2000 DSP模块,与MatlabSimulink产品中的其他模块结合,实现对该逆变控制器进行仿真和编程下载的应用。

          数字式逆变器采用单相半桥逆变结构,逆变控制器核心芯片选用TMS320F2812,输出两路SPWMEXB841模块作为SPWM信号的驱动放大器,控制开关采用全控器件IGBT,输入电压311V,输出电压为100V(有效值),开关频率为10kHz,逆变输出电压频率为50Hz。逆变控制器的系统原理及接口框图如图2所示,逆变系统的电流和电压通过电压霍尔传感器和电流采样电路分别检测出来,送入模拟信号处理电路中进行模拟滤波处理和幅值调整,处理后的信号送入DSP芯片之中,经过DSP片内的12A/D转换模块,变为数字信号,DSP对信号进行数字滤波后,判断单相半桥的输出电压、电流是否过压或过流,并采取相应的保护措施;再根据控制算法进行处理,通过DSP片内的PWM输出模块,得到所需要的两路SPWM波形信号,经过EXB841驱动放大模块进行处理,最后对IGBT逆变半桥进行控制,从而实现直流-交流的逆变。同时还利用DSP片内的CAN2.0B模块,保留一个对外的CAN网络接口,便于使用网络通信对数字逆变控制器进行实时控制和监测。

      图4 CCS中自动生成的

      C语言项目框架图

      在Matlab下输入c2000lib命令,可以显示Embedded Target for TI C2000 DSP目前所能够支持的各种DSP功能模块及相关信息。仿真时,主要利用Embedded Target for TI C2000 DSP所提供的C28X ADCC28X PWM以及Mailbox子模块。如图3所示,系统利用A/D转换模块,将采集到的逆变电流和电压作为SPWM输出的控制源。并通过CAN通道1A/D转换值以及PWM输出占空比输送出来,同时还可以通过CAN通道0接收来自于网络上的通信命令,执行相应的子程序。C28X ADC模块在功能上完全等同于TMS320F281212A/D转换模块,可以选择合适的模拟输入通道。C28X PWM模块在功能上完全等同于TMS320F2812事件管理器中带死区的全比较单元模块,同样可以选择定时器、PWM输出单元、PWM引脚极性以及设置死区时间。

      编程下载之前,先要对F2812 eZdsp模块进行编译属性、目标板和仿真器的选择设置,以及Real-Time Workshop的属性设置,具体步骤如下:

      1. 打开CCS2.20,选择合适的硬件仿真器,此处选择F2812 XDS510 Emulator,打开DSP软件集成开发环境。

      2.Matlab下输入ccsboardinfo命令显示出来,查看Embedded Target for TI C2000 DSP所支持的板卡及驱动,如用户升级仿真器或更换板卡,则需安装相应的驱动程序,才能支持对应的物理设备。

      3. 右键点击F2812 eZdsp,对评估板硬件链接模块进行编译、链接和运行等选项的设置。注意,在设置BuildOptions属性时,若没有连接目标板或仿真器,则BuildAction只选择Build,可编译生成C代码;若有目标板及仿真器,则可选择Build_and_execute,实现C代码的编译下载及实时运行。

      4. DSPBoard选项中选择与目标板一致的DSP芯片类型,并更改DSP板标号,如F2812 PP Emulator等,本文改为F2812 XDS510 Emulator

      5. 设置Real-Time Workshop的相关属性,可以根据个人的习惯进行定制。

      经过上述设置步骤之后,可以选择工具菜单内的Real-Time Workshop下的Build Model生成仿真模型对应的C语言代码,MatlabCommand窗口会显示后台处理的详细过程,代码的编译及链接过程在CCS中也会有显示。最后,CCS会自动打开Matlab所生成的软件项目代码,CCS中显示出来的SPWM项目的框架(F2812_SPWM.pjt)如图4所示,一共有F2812_SPWM_ main.c14C语言子程序、SPWM.cmd文件和一些头文件。所生成的逆变控制器C代码,保留了模型中相应的变量名,具有良好的可读性和可维护性,其中所生成CAN通信的主要源代码如下:

      /* CAN 邮箱发送子程序*/

      {

      ECanaMboxes.MBOX1.MDL.word. LOW_WORD=F2812_SPWM_B.R eadMsgADValueDutyCycle;

      ECanaMboxes.MBOX1.MSGC TRL.bit.DLC = 2;

      ECanaRegs.CANTRS.bit.TRS1 = 1; // set eCAN Transmit Request Set register

      while(ECanaRegs.CANTA.bit.TA1 != 1 ) {} // check eCAN Transmit Acknowledge register

      ECanaRegs.CANTA.bit.TA1 = 1; // clear eCAN Transmit Acknowledge register

      }

          另外,用Embedded Target for TI C2000 DSP所提供的Build/Reload/Run模块,可以一步到位地将Matlab生成的C语言代码直接转为COFF文件下载到DSP逆变控制器的目标板中,不需作两个开发平台下的程序移植。如有特殊需求,还可以自行增加一些代码。这样就可以避开繁琐的编程步骤,直接进行在线算法验证,最终获取最优的控制程序实现。

  • 怎么不能显示图片,那我就再传个word吧

    新建 Microsoft Word 文档.doc
  • 图 可详见附件

    基于DSP2802 的控制系统设计

     

     控制系统的硬件构成

    1  硬件框图

    1 所示为控制系统硬件框图,整个系统分为3 个部分: 中央处理单元、模拟信号检测与调理单元、驱动单元。中央处理单元由DSP 以及构成数字控制系统所必需的晶振、复位及存储器扩展等外围电路组成;模拟信号检测与调理单元完成对主电路中电压、电流信号的检测及后期调理功能; 驱动单元负责对DSP 输出的PWM 信号进行隔离、放大,并产生驱动IGB T 器件的驱动信号。

     

    1

    2 电源电路

    F28027 采用高性能静态CMOS 技术,低功耗,由双路电源供电:内核是1. 8 V 供电, I/ O端口是3. 3 V 供电。因此供电方案采用了TI 公司的双路输出低压差线性稳压器TPS767D318 ,能够提供一路恒定的3. 3 V 电压和一路恒定的1. 8 V 电压,每路输出电流为01 A ,当输出电路为1 A ,

    电源跌落典型值为350 mV。电源电路如图2 所示, 为了保证F28027在上电过程中内部所有模块能够得到正确的复位状态,要求所有3. 3 V 供电管脚先上电,然后才能给所有1. 8 V 供电管脚上电。上电过程中,首先是TPS767D318 的第2 路输出电压(3. 3 V) 上电,3. 3 V 电压上升到使得N 沟道场效应管BSS138 的栅极电压达到阈值电压( 典型值为1. 2 V) ,BSS138 导通,使得TPS767D318 的第1 路输出电压允许信号为低电平,从而允许1. 8 V 上电,保证了F28027对于上电时序的要求。

    2

    3 电源监控与复位电路

    电源监控与复位电路对于微处理器来说至关重要,在设计中采用了TI 公司的集成微处理器监

    控芯片TPS3307218 ,具有上电复位、手动复位、电源监控等功能,可以同时为微处理器提供3 路电压监控。复位电路如图3 所示, F28027的复位引脚接有上拉电阻,TPS3307218 芯片发出复位信号后, F28027的复位引脚电平被拉低,从而使F28027复位。TPS3307218 芯片中的MR 引脚为手动复位输入,低电平有效,芯片内部具有上拉电阻。由于F28027的复位管脚不仅是输入口,同时又是内部看门狗(Watchdog) 复位输出口(漏极开路输出) ,所以在TPS3307218 芯片的复位输出引脚与F28027的复位信号之间连接了一个电阻,防止F28027内部看门狗复位时与TPS3307218 的复位输出脚短路。

     

    3

    4 晶振电路

    F28027的晶振电路可以采用无源晶体和有源晶振2 种方式,由于有源晶振具有工作稳定、抗干扰能力强的优点,所以晶振电路设计采用了3. 3 V电源供电的有源晶振系统,如图4 所示。外部时钟频率为30 MHz ,经过F28027内部的锁相环( PLL) 倍频后得到芯片所需的各时钟信号。因为F28027的振荡器输入管脚X1/XCL KIN 接收的是1. 8 V 电平的输入信号,所以将有源晶振的输出经过阻容滤波送入由1. 8 V 电压供电的单门施密特反相器74LVC1G14 ,3. 3 V 电平的有源晶振输出转变为1. 8 V 电平信号,再经电阻送到F28027的振荡器输入管脚X1

     

    4

    5 实时时钟和EEPROM接口电路

    实时时钟完成时钟功能,可以通过软件编程查询和校正当前的年、月、日、星期、时、分、秒等时间信息,因此可以用于获得系统启动或停止的时间、系统发生故障的准确时间等,有利于系统工作状况及故障信息的记录。EEPROM 为非易失性存储器,能够在系统掉电情况下保存系统的运行参数、故障原因及故障时刻等信息。实时时钟和EEP2ROM 接口电路如图5 所示。实时时钟芯片选取了XICOR 公司的X1226 ,I2 C 总线接口,供电电源范围2. 75 V ,工作电流典型值为1. 25μA ,具有后备电池输入接口和内置电源自动切换电路。BA T1 为后备电池,用于在系统电源掉电情况下给X1226 供电, X2 为外接32. 768 kHz的晶体。EEPROM 存储器采用美国Ramt ron 公司的铁电存储器FM24CL64 ,支持I2 C总线数据传输协议,存储空间大小为8 192 字节,页面大小为32 字节,供电电源范围2. 73. 6 V ,进行读写操作时,工作电流典型值为75μA ,数据保存时间大于10 年。铁电存储器的最大优点是没有一般EEPROM 存储器( A TMEL 公司的A T24C64) 的写入等待周期(典型值为10 ms) ,可以实现连续写入及写入后马上读取等功能,SRAM 一样操作方便,在掉电情况下保证大于10 年的数据保持时间,已足够满足一般应用要求。

     

    5

     

    6 模拟信号的调理电路

    主要用于对传感器输出信号进行采样、滤波、限幅保护以及电平变换等处理, 以满足F28027ADC 模块对输入采样信号的要求。图6 为直流模拟信号的调理电路原理图。R0为采样电阻,将传感器输出的电流信号转化为合适的电压信号。从抗干扰的角度来看,由于传感器和控制电路之间有一定的距离,因此希望传感器的输出电流大一些,能够提高反馈信号的信噪比,从而增强控制系统的抗干扰能力。这也就是说希望采样电阻上的输入电压V in 电平较高, 而由于F28027ADC 模块输入电平范围为03 V ,电压比较低,这就与系统抗干扰的出发点形成了矛盾。所设计的电阻分压电路即为解决这一问题, R1 R2 组成了分压电路,分压比例为V f / V in =R2 / ( R1 + R2 ) ; R1 C1 组成滤波电路,对采样后的电压信号进行低通滤波,去除反馈信号上的尖峰与毛刺,滤波时间常数τ= R1 C1 ;运算放大器LM258组成电压跟随器,输出电压与输入电压同相,利用其输入阻抗高、输出阻抗低的特性用作缓冲电路,再经过R3 C2 构成的再次低通滤波以及由低导通压降的肖特基二极管构成的钳位电路,最后送入F28027ADC 模块。

    6

    基于DSP28027 的控制系统设计.doc
  • 这是我使用C2000的一些感受,希望能借助这个平台,与同行一起交流与学习

    TI C2000心得.doc
  • 抢一个,学习一下

  • C2000 一般用在光伏逆变器、数字电机控制、数字电源等领域。相比于其他 MCU 来说,C2000 的核心是 DSP 核心,所以数学运算能力强,适合于运算各种复杂的控制算法;其次它的中断响应速度快,可以快速进入中断处理突发事件,也就是实时性好。C2000系列DSP采用增强的哈佛架构总线结构。在TI C2000定点DSP的快速实现取整函数的一点心得:floor与ceil函数都是C语言的标准库函数,在<math.h>头文件引用之后一般即可直接调用。在浮点DSP上,通过TI 的FastFPU库,此类浮点函数一般可以通过查ROM的方法快速计算得到。但在定点的DSP,比如C2000中常用的TMS320F2812上,则需做一定的处理,以提高执行效率。在浮点DSP上一般有专门的浮点协处理器FPU来完成浮点运算,而在定点DSP上直接计算浮点运算需要消耗大量的处理能力,将浮点运算转换为定点来计算是唯一的选择。在一个用到floor与ceil函数的具体实验中,我采用了TI公司的TMS320F2812定点DSP,采用C语言编程并使用TI公司定点处理智能数学运算。

  • 分享一下我用TMS320F28027我正在做的毕业设计的心得
    一,我的总体设计
      我的毕业设计是用F28027做的心电图,用F28027设计10阶
    的FIR滤波器,把来自经过仪用放大器,反向运放反大电路,再
    经过隔离放大器,总共500倍增益的心电信号,用F28027的
    12位ADC以512HZ的速度(2ms)采样心电信号,F28027通过
    epwm触发ADC的采样,把10个ADC采样结果数据当做一组,用
    有限冲击滤波器算法,把x[9]*h[0]+x[8]*h[1]+....+x[0]*h[9]
    的结果作为滤波输出,FIR代码:

    float FIR()
    {
     float fSum;
     fSum=0;         //输出清零
     for ( i=0;i<FIRNUMBER;i++ )//FIRNUMBER滤波器的阶数
     {
      fSum+=(fXn[FIRNUMBER-i]*fHn[i]);//卷和
     }
     return(fSum);
    }

    h[n]的系数需要通过使用MATLAB里面的工具箱的FDATOOL来设计FIR
    滤波器.由于人体相当于天线,接收到大量的共模干扰,尤其是50HZ的
    工频干扰,需要设计一个截止频率为30HZ的低通滤波器.通过FDATOOL计算
    出h[n]的归一化后为5225, 5175, 7255, 9453, 11595, 13507, 15016,
     15983, 16315.由于计算出来的结果可能很大从而溢出,所以fSum=fSum>> 15;
    把结果缩小到适合DAC输出.输出的效果见视频,可能是示波器的问题,对干扰
    过于敏感,而用模拟的示波器就看不到毛刺,数字示波器的效果就不好,还是
    算法问题?我会找出原因的.

    二,TMS320F28027心电图制作中遇到的困难
      由于我也是第一次用c2000的芯片,虽然用过51,arm,avr等等,但首次
    接触DSP的我对cmd文件的编写,数据段,代码段等等都不熟悉,好在TI的
    支持文档很多,而且有很多都是中文的(我还没过4级压力很大),又花了
    几个月把寄存器搞明白,对着TI的代码例子,学呀学呀.开始遇到的问题
    就是不知道ADC的采样要epwm的触发,就是漏了对epwm的初始化,程序调
    试了很多次,又苦于没有XDS100调试,只有改代码,再串口下载.后来看了
    TI的代码例子才发现问题,最后碰碰跌跌地终于调试成功.再把F28027
    外接的12位DAC输出(FIR滤波后DA转换还原心电)接上示波器,当时用看
    到几个月的成果,激动得快哭了出来.

    三,经验心德总结
      通过用TMS320F28027做心电图,了解TI的c2000的架构,CCS的使用,
    c2000的编程,FIR滤波器的设计和在c2000中是如何实现FIR的.我还学
    会了要多看user guid 代码例子,上deyisupport问问题,参加
    TI的活动等等.

    这是我希望分享给都在学,在用c2000朋友的一些小小心得,谢谢!
    附:用示波器看到的心电图视频
    http://v.youku.com/v_show/id_XNDYyODE3OTIw.html

  • DSP开发入门之经验分享

     

    DSP是Digital Signal Processing(数字信号处理)或Digital Signal Processor(数字信号处理器)的缩写。这一章中我们要讲的内容是,如何开始采用一个或多个数字信号处理芯片对输入信号(数字信号)进行分析、处理。所以在你进行DSP开发之前,你应该明确以下几个问题:

    (1).你是否应该或需要使用DSP?

    (2).你应该选择哪个型号的DSP?

    (3).你熟悉你即将使用的DSP吗?包括它的硬件结构、外设控制、指令系统、寻址方式以及开发环境(工具)?

    1-1为什么要采用数字信号处理?

    (1)灵活性

    在模拟处理系统,当需要改变一个模拟系统的应用时,你可能不得不修改硬件设计,或调整硬件参数。而在数字处理系统,你可以通过改变数字信号处理软件来修改设置,以适应不同的需要。

    (2)精度

    在模拟处理系统,系统精度受元器件影响,同一批次产品可能有不同的性能。而在数字处理系统中,精度仅与A/D的位数和计算机字长、算法有关,它们是在设计系统是就已经决定了的。

    (3)可靠性和可重复性

    模拟系统易受环境温度、湿度、噪声、电磁场等的干扰和影响,而数字系统的可靠性和可重复性好。

    (4)大规模集成

    模拟系统尽管已有一些模拟集成电路,但品种较少、集成度不高、价格较高。而数字系统中DSP体积小、功能强、功耗小、一致性好、使用方便、性能/价格比高。

    (5)虚拟特性与升级

    一模拟系统系统只能对应一种功能,升级意味着新型号的系统的研制。而数字系统中一套系统对应多种功能,只要装上不同的软件即可。

    图1:软件使得数字系统更加灵活
    图1:软件使得数字系统更加灵活

    (6)特殊应用:有些应用只有数字系统才能实现

    例如:信息无失真压缩(LOSSLESS COMPRESSION)、V型滤波器(NOTCH FILTER)、线性相位滤波器(LINEAR PHASE FILTER)等等.

    但数字信号处理也有局限性:

    (1) 实时性

    模拟系统中除开电路引入的延时外,处理是实时的。而数字系统:由计算机的处理速度决定。

    (2)高频信号的处理:

    模拟系统可以处理包括微波毫米波乃至光波信号,而数字系统:按照奈奎斯特准则的要求,受S/H、A/D和处理速度的限制。

    (3)模拟与数字信号的转换

    现实世界的信号绝大多数是模拟的(温度、速度、压力等),转换成的电信号也是模拟的(电流、电压等)。要实现数字处理,就必须进行转换。所以一般在一个DSP系统中都有数/模或模/数转换电路,这也限制了DSP的应用。下面是一个采用DSP做信号处理的典型框图:

    采用DSP做信号处理的典型框图
    采用DSP做信号处理的典型框图

    1-2 DSP的发展与特点

    DSP的特点

    (1)哈佛结构

    程序与数据存储空间分开,各有独立的地址总线和数据总线,取指和读数可以同时进行,从而提高速度。

    (2)用指令流水线

    (3)硬件乘法/累加器

    在卷积、数字滤波、FFT、相关、矩阵运算等算法中,都有∑SA(k)B(n-k)一类的运算,其中包含大量重复乘法和累加。在通用计算机的乘法用软件实现,需要用若干个机器周期。而DSP有专用的硬件乘法器,使用MAC指令(取数、乘法、累加),可以在单周期内完成。

    (4)多种寻找方式

    循环寻址(Circular addressing),位倒序(bit-reversed)等特殊指令,使FFT、卷积等运算中的寻址、排序及计算速度大大提高。1024点FFT的时间己小于1ms。

    (5)独立的DMA总线和控制器

    有一组或多组独立的DMA总线,可以与CPU的程序、数据总线并行工作。在不影响CPU工作的条件下,DMA速度已达800Mbyte/s以上。(6)多处理器接口现在的DSP中大多都提供了串口和并口,使多个处理器可以很方便的并行或串行工作。如TMS320C40有6个8-bit的接口,VC5420提供MsBSP和16位的并口,ADI的ADSP21160也有类似的结构。

    (7)所有DSP芯片都包含JTAG(Joint Test Action Group)标准测试接口(IEEE 1149标准接口),便于对DSP作片上的在线仿真和多DSP条件下的调试。

    DSP的发展

    更高的运行速度和信号处理速度

    多DSP协同工作

    更方便的开发环境

    大量专用DSP的出现(DSP核)

    更低的价格,或更高的性能/价格比

    更广泛的应用(每年以30%增长)

    更低的功耗(55X 0.05mw/MIPS)

    1-3 TI的DSP系列

    DSP的主要供应商

    目前市场上的主要DSP生产商包括TI,ADI,Motorola,Lucent和Zilog等,其中TI占有最大市场份额。作为第一片DSP产品TMS32010的生产商和DSP行业的领头者,TI公司的产品包括从低端的低成本低速度DSP到高端大运算量的DSP产品。

    TI的三大主力DSP产品

    C5000系列:C54X,C54XX,C55X(低功耗)

    C2000系列:C20X,F20X,F24X,F24XX(控制器)

    C6000系列:C62XX,C67XX,C64X(高性能)

    TI其他DSP产品

    C3X系列(浮点):C30,C31,C32,VC33

    C2x和C5x系列:C20,C25,C50等

    C4X、C8X系列

    1.4 TI的DSP系列介绍

    目前,广泛使用的TI的DSP有三个系列:C2000,C5000和C6000,C3X也有使用,而其他型号都基本淘汰。需要提醒注意的是,同一系列中不同型号的DSP一般都具有相同的DSP核,相同或兼容的汇编指令系统;而它们的差别仅在于片内存储器的大小,外设资源(如定时器、串口、并口等)的多少。不同系列的DSP它们的汇编指令系统不兼容,但汇编语言的语法非常相似。除了汇编语言外,TI还为每个系列都提供了优化c编译器,方便用户使用c(使用ANSI的标准c)语言进行开发,效率可以做到手工汇编的90%甚至更高。下面我们简单介绍这个常用系列:

    1.C2000系列:

    C2000系列是一个控制器系列,全部为16位定点DSP。该系列中的一些型号具有片内FLASH RAM,如TMS320F24x,TMS320LF240x等。TI所有DSP中,也只有C2000有FLASH。作为控制器,C2000系列除了有一个DSP核以外,还有大量的外设资源,如A/D、定时器、各种串口(同步或异步)、WATCHDOG、CAN总线、PWM发生器、数字IO脚等等。特别是C2000的异步串口可以与PC的UART相连,也是TI所有DSP中唯一具有异步串口的系列。

    图2 : C2000系列DSP的型号
    图2 : C2000系列DSP的型号

    2.C5000系列:

    C5000系列是一个定点低功耗系列,特别适用于手持通讯产品,如手机、PDA、GPS等。目前的处理速度一般在80MIPS一400MIPS。C5000系列主要分为C54xx和C55XX两个系列。两个系列在执行代码级是兼容的,但他们的汇编指令系统却不同。目前TMS320VC5402的零售价在¥60一¥80元,性价比极高。C5000包含的主要外设有McBPS同步串口,HPI并行接口,定时器,DMA等。其中C55XX提供EMIF外部存储器扩展接口,允许用户直接使用SDRAM、SBSRAM、SRAM、EPROM等各种存储器。而C54XX没有提供EMIF,所以只能直接使用静态存储器SRAM和EPROM。另外,C5000系列一般都使用双电源供电,其I/0电压和核电压一般不同,而且不同型号也有差别。不过,TI提供了全系列的DC—DC变换器可以解决DSP的电源问题。

    C5000系列一般都提供PGE封装,便于PCB板的制作。

    图3: C5000系列DSP
    图3: C5000系列DSP

    3.C3X系列:

    C3X系列虽然不是目前TI的主流产品,但作为一个32位的低价位浮点DsP,仍然被广泛使用。其中,TMS320VC33的价格大约在¥200元左右,其最高处理速度为150MFLOPs。C3X系列的结构比较简单,外设也比较少,主要有同步串口,DMA通道,定时器,能用于数字I/O的引脚也只有2条。下面是VC33的简单情况:

    高品质的浮点DSP,13ns和17ns指令周期

    34Kx32Bit片内RAM

    X5 PLL时钟产生器

    低功耗,<200mv@150MFLOPS

    16/32bits整数和32/40bits浮点数运算

    32位指令字,24bits地址线

    具有BOOTLOADER。一个串口,两个32位的定时器和DMA

    八个扩展精度寄存器,R0,R1,。。R7

    双电压共电,1.8V核电压和3.3V的I/O电压

    支持JTAG调试标准。四个简单、高效的预译码信号

    4.C6000系列:

    C6000系列是一个32位的高性能的DSP芯片,目前处理速度从800MIPS一2400MIPS,而且还在不断提高。其中,C62XX为定点系列,C67XX和C64XX为浮点系列。同C55XX一样,C6000也提供EMIF扩展存储器接口,方便用户使用各种外部扩展存储器,如SBSRAM、SDRAM、SRAM、EPROM。C6000提供的主要外设有McBPS同步串口,HPI并行接口,定时器,DMA等。另外,在C6000的一些型号中还提供了PCI接口。C6000几乎都只提供BGA球形封装,在PCB板制作时需要多层板,增加了开发和调试的难度。另外,C6000系列的功耗较大,需要仔细考虑DSP与系统其他部分的电力分配,选择适当的DC—DC转换器。


  •  

    关于DSP的一些反正切查表算法的编写

    一直在拿TMS20F28335做电机控制,也从早前的简单寄存器IO口配置时代过渡到了真正的算法时代,很不适应,起初去查各种书籍,网上搜索各种网站,发现书本上讲的很多都是快速傅里叶啊啥的,找不到很原始的像啥低通滤波器,正弦,正切这些函数的编写。

    起初写程序发现,C2000的库里支持啥正弦函数,浮点预算,反正弦函数,开根运算等算法,好兴奋。用了才知道,太慢了,根本没法用在工程上。

    关于三角函数的编写,其实都是利用查表发,查表法大家应该都懂。这个就不再赘述,怎样去查一个正弦表呢?这里做一个基本的介绍。

    首先,你可以自己写一个查表数组,也可以在程序初始化生成一个。

    Eg:

    void SinCOS_TAB(void)

    {

        unsigned char i;

        float Theta;

        for(i=0;i<TAB_Max;i++)    // #define   TAB_Max           180

        {

        Theta = i * Step_Angle;   // Step_Angle=1.74532925E-02

        Sin_tab[i] =sin(Theta);  // 生成正弦表数组,利用了库里现成的SIN函数

        Cos_tab[i] =cos(Theta);  // 生成余弦表数组

        }

    }

    为啥我的数组里面只有180个元素呢?一:我的精度要求不高,我是一度一个步进角的,如果你要更高的精度,你可以选择容量更大的数组。二:我不想因为庞大的浮点数组占据太大的存储空间,所以我利用了奇函数,偶函数的原理

    再次,就进入正题写查表程序,就我们初中数学所知,正弦函数是奇函数,余弦函数是偶函数,所以我只用了360角度中的一半。

    下面为正弦查表程序:

    /*Refer to the truth that DSP use some SinCos operation will use six or more command

     * periods , So I look up the pre_generate SINCOS_TAB to speed up the Execution speed*/

    float SinF(float single)

    {

        int i=(int)(single*180/pi);

        float value=0;

        if(i<0)

         value = -Sin_tab[i];

        else

         value = Sin_tab[i];

        return value;

    }

    看起来应该很简单吧,余弦,正切,余切的编写和上面基本相似。

    下面来探讨一下反正弦,反正切函数的编写

    我在网上查了一下,运用函数库的反正弦,正切指令计算一个至少需要400以上各时钟周期,网上也有很多方法,看了有些能看懂,但大多看了头疼。自己呢,还是从正切函数的曲线出手,利用单调递增写了一个查表函数,已在MATLAB上实验过。

    一次函数线性逼近正弦函数

    这是我算法在MATLAB上面实验的程序:

    function single = tanflook( a )

    %UNTITLED Summary of this function goes here

    %   Detailed explanation goes here

    global theta;

    %global single;

    global Actan_tab;

    global x;

    global res;

    theta=-90:90;

    theta=theta*3.141596/360;

    Actan_tab=1000*tan(theta);

     

    pi

    z=input('the Z scale is :');

    y=input('the Y scale is :');

    a=(z+y>=0);

    a

    b=(z-y<=0);

    b

    if((a==b))

      single = z/y;

    else

      single = y/z;

    end

    tab =fix(single*99-8)+90;

    tab

    comp=fix(single*1000);

        for i=tab:181

            if(comp>=Actan_tab(i))&&(comp<Actan_tab(i+1))

               break;

           % else

           % i=i+1;

            end

        end

        i

        c = (i>90);

        c

        single= (i-90)/360*pi;

        x=2*b+a;

       % x=2;

        switch x

            case 0

                single=-pi/2-single;%break;             %case 0:single=single;break;

            case 1

                 ;%break;

            case 2

                single=pi+single-2*pi*c;%break;

            case 3

                single=pi/2-single;%break;

        end

                x

            disp('the single value is ');

            disp(180*single/3.141596);

    End

     

    讲讲原理吧,感觉还是有点东西,还是从那个一次函数线性逼近正弦函数的地方说起,为什么要这样了,因为我们从图上可见发觉,每一个正弦值其实都在某段线性函数包围之间,我们已知了正切值,利用正切函数的线性递增原理,可以大致推断出他所处的大概位置,然后再查建立好的表,这里就不要再用处理器去生成了,查表时应尽量避免浮点数运算来节约时间,我们就可以精确的算法所对应的角度。试验了一下,最差的情况下差不多要消耗40个时钟周期。

    关于上面几个CASE的推导,可以仿造SVPWM里面推导CASE的方法,感兴趣的可以推导一下,还是蛮有意思的,千万不要糊涂。

    东西感觉不是很多,主要自己会的比较少,希望对大家有帮助,如果那个地方讲的不对,还请大神能及时指出,与我进行交流,我很喜欢和别人探讨

     

     

     

    关于DSP的一些反正切查表算法的编写.docx
  • 附件是我的设计文档,这里我也贴出一些TI公司在各论坛中的 活动链接,我感觉这都初学者很受用,21电子工程师C2000视频介绍,http://bbs.21ic.com/frame.php?frameon=yes&referer=http%3A//bbs.21ic.com/icnewest.html

    MSP430如何培训   DC2DC基础知识培训

    http://bbs.21ic.com/frame.php?frameon=yes&referer=http%3A//bbs.21ic.com/icnewest.html

    这些活动都很不错的,可以看看,或到TI官网www.ti.com搜集资料,都是很不错的学习方式

    数控直流电源.wps
  • 28335利用PSIM9.0 生成SPWM (不用敲一行代码!!!)

    本人喜欢模型设计和自动代码生成,matlab的嵌入式工具箱的C2000生成的代码,比较麻烦.
    最近想搞APF,手动代码太耗时间,bug也不少.
    下面介绍用pism9.0 搭建模型自动生成CCS可调用的工程,使28335产生SPWM波形.
    整个过程不需要敲一行代码 @_@
    说明:用的是研旭的开发板实验


    1.打开psim9.0 绘制以下仿真图,双击设置28335参数,如箭头所示 



     

     
    2.,点击仿真时钟,设置仿真参数,选28335在RAM Debug 模式



     
    3.点击simulate 下的 Generate Code 生成CCS的代码 



     

     

     4.查看生成的代码 


    5.用CCS打开仿真目录下的工程文件 



    6.编译该工程 


    7.下载代码 


    8.下载后的实验效果


  •    大家好,首先我是一名大二的学生,对于DSPc200还不是太熟悉。从大一到现在,我学习的是了一些单片机,其中也包块在假期参加TI比赛过程中学习了TI公司的msp430单片机,现在我很想学习一下c2000,希望得到优秀分享奖。

       因为是初学者,处在刚刚入门的阶段,所以只能给大家分享一下我所看到的文档,希望大家不要介意。

      DSP是一种独特的微处理器,是以数字信号来处理大量信息的器件。它不仅具有可编程性,而且其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器,是数字化电子世界中日益重要的电脑芯片。

          DSP虽然为3C(计算机、通信、消费电子)产品的开发提供了很好的硬件支撑平台,但设计者仍得花费一定的时间去掌握DSP内部各种寄存器的正确设置、软件编程方法以及控制算法设计,这必然会增大产品开发难度,延长产品开发周期,从而影响开发效率。Matlab公司最新推出的针对DSP应用控制系统而开发的嵌入式目标模块Embedded Target for TI C2000 DSP即可解决上述问题,用户通过使用该模块,不仅可以进行电路的系统级仿真,还可编译生成相应的C语言代码,并下载到目标板,直接运行程序,进行算法的探索与设计思路的验证,提高开发效率。

      图1 Embedded Target for TI C2000应用流程示意图

          TI C2000 DSP的特点及开发应用流程

      作为一种专用的集成开发环境,Matlab公司最新推出的Embedded Target for TI C2000 DSP 开发平台能够让设计人员直接进行()实物仿真、算法的探索与研究,以及产品可靠性的验证,从而有效地减少了设计开发过程中的消耗,加快了原型开发的速度。该平台有如下几个优点:

      1) TI C2000 DSP 上自动测试、执行Simulink仿真模型;

      2) 提供模块化的系统和功能,比如PWMADCCAN以及目标板载内存等;

      3) 生成文档化的易读可编辑的C语言代码,并生成Code Composer Studio项目文件;

      4) F2407 eZdsp评估板和F2812 eZdsp评估板上进行自动化实时测试;

      5) TI推出的IQmath Library提供模块化的支持,可以用于仿真和代码生成;

      6) 可以进行定点系统的设计、仿真、自动定标和代码生成工作。

          Embedded Target for TI C2000 DSP提供了将MATLABSimulinkTI eXpressDSP工具、TI C2000 DSP控制器集成在一起进行系统开发的手段。通过Real-Time WorkshopTI的开发工具将Simulink模型转变为实时C代码,这样就可以利用这些产品在TI C2000 DSP系统上(F2812 eZds评估板和F2407 eZdsp评估板等)实现自动代码生成、产品原型和嵌入式系统实现,并可实时进行算法验证,极大地提高了开发效率。另外,该模块还有强大的可扩充能力,用户可以增加自己的代码、中断服务程序、IO设备驱动到CCS(Code Composer Studio)的工程项目中,这样就可以直接驱动自行开发研制的控制板卡或第三方的硬件设备板卡,完成产品的设计。采用该平台,开发人员不用编写一行代码,就可以完成几乎所有设计、仿真和编程下载的工作,整个开发流程如图1所示。

     

          2 DSP逆变控制器接口示意图

      图3 MatlabDSP应用模块仿真及下载示意图

          应用实例

          下面以一个基于DSP TMS320F2812芯片的带CAN2.0B网络接口的数字逆变控制器的设计为例,介绍利用Embedded Target for TI C2000 DSP模块,与MatlabSimulink产品中的其他模块结合,实现对该逆变控制器进行仿真和编程下载的应用。

          数字式逆变器采用单相半桥逆变结构,逆变控制器核心芯片选用TMS320F2812,输出两路SPWMEXB841模块作为SPWM信号的驱动放大器,控制开关采用全控器件IGBT,输入电压311V,输出电压为100V(有效值),开关频率为10kHz,逆变输出电压频率为50Hz。逆变控制器的系统原理及接口框图如图2所示,逆变系统的电流和电压通过电压霍尔传感器和电流采样电路分别检测出来,送入模拟信号处理电路中进行模拟滤波处理和幅值调整,处理后的信号送入DSP芯片之中,经过DSP片内的12A/D转换模块,变为数字信号,DSP对信号进行数字滤波后,判断单相半桥的输出电压、电流是否过压或过流,并采取相应的保护措施;再根据控制算法进行处理,通过DSP片内的PWM输出模块,得到所需要的两路SPWM波形信号,经过EXB841驱动放大模块进行处理,最后对IGBT逆变半桥进行控制,从而实现直流-交流的逆变。同时还利用DSP片内的CAN2.0B模块,保留一个对外的CAN网络接口,便于使用网络通信对数字逆变控制器进行实时控制和监测。

      图4 CCS中自动生成的

      C语言项目框架图

      在Matlab下输入c2000lib命令,可以显示Embedded Target for TI C2000 DSP目前所能够支持的各种DSP功能模块及相关信息。仿真时,主要利用Embedded Target for TI C2000 DSP所提供的C28X ADCC28X PWM以及Mailbox子模块。如图3所示,系统利用A/D转换模块,将采集到的逆变电流和电压作为SPWM输出的控制源。并通过CAN通道1A/D转换值以及PWM输出占空比输送出来,同时还可以通过CAN通道0接收来自于网络上的通信命令,执行相应的子程序。C28X ADC模块在功能上完全等同于TMS320F281212A/D转换模块,可以选择合适的模拟输入通道。C28X PWM模块在功能上完全等同于TMS320F2812事件管理器中带死区的全比较单元模块,同样可以选择定时器、PWM输出单元、PWM引脚极性以及设置死区时间。

      编程下载之前,先要对F2812 eZdsp模块进行编译属性、目标板和仿真器的选择设置,以及Real-Time Workshop的属性设置,具体步骤如下:

      1. 打开CCS2.20,选择合适的硬件仿真器,此处选择F2812 XDS510 Emulator,打开DSP软件集成开发环境。

      2.Matlab下输入ccsboardinfo命令显示出来,查看Embedded Target for TI C2000 DSP所支持的板卡及驱动,如用户升级仿真器或更换板卡,则需安装相应的驱动程序,才能支持对应的物理设备。

      3. 右键点击F2812 eZdsp,对评估板硬件链接模块进行编译、链接和运行等选项的设置。注意,在设置BuildOptions属性时,若没有连接目标板或仿真器,则BuildAction只选择Build,可编译生成C代码;若有目标板及仿真器,则可选择Build_and_execute,实现C代码的编译下载及实时运行。

      4. DSPBoard选项中选择与目标板一致的DSP芯片类型,并更改DSP板标号,如F2812 PP Emulator等,本文改为F2812 XDS510 Emulator

      5. 设置Real-Time Workshop的相关属性,可以根据个人的习惯进行定制。

      经过上述设置步骤之后,可以选择工具菜单内的Real-Time Workshop下的Build Model生成仿真模型对应的C语言代码,MatlabCommand窗口会显示后台处理的详细过程,代码的编译及链接过程在CCS中也会有显示。最后,CCS会自动打开Matlab所生成的软件项目代码,CCS中显示出来的SPWM项目的框架(F2812_SPWM.pjt)如图4所示,一共有F2812_SPWM_ main.c14C语言子程序、SPWM.cmd文件和一些头文件。所生成的逆变控制器C代码,保留了模型中相应的变量名,具有良好的可读性和可维护性,其中所生成CAN通信的主要源代码如下:

      /* CAN 邮箱发送子程序*/

      {

      ECanaMboxes.MBOX1.MDL.word. LOW_WORD=F2812_SPWM_B.R eadMsgADValueDutyCycle;

      ECanaMboxes.MBOX1.MSGC TRL.bit.DLC = 2;

      ECanaRegs.CANTRS.bit.TRS1 = 1; // set eCAN Transmit Request Set register

      while(ECanaRegs.CANTA.bit.TA1 != 1 ) {} // check eCAN Transmit Acknowledge register

      ECanaRegs.CANTA.bit.TA1 = 1; // clear eCAN Transmit Acknowledge register

      }

          另外,用Embedded Target for TI C2000 DSP所提供的Build/Reload/Run模块,可以一步到位地将Matlab生成的C语言代码直接转为COFF文件下载到DSP逆变控制器的目标板中,不需作两个开发平台下的程序移植。如有特殊需求,还可以自行增加一些代码。这样就可以避开繁琐的编程步骤,直接进行在线算法验证,最终获取最优的控制程序实现。

       TI一向支持学生的学习,希望可以给我这次获得优秀分享奖的机会,最口预祝TI越来越好,可以多多举办电子方面的比赛,这样我们大学生可以在比赛中提高自己的知识和动手能力。

  • 首先非常感谢TI和deyisupport一直以来给我们学习者和开发者提供这么多机会!

    我是一个大三学生,大二学了半年430mcu,这学期刚刚接触c2000系列,由于多人共用一块板子,进度不是很快,前一段时间主要熟悉了存储器映射结构,GPIO的控制,看门狗,ADC,SPI,学习中是通过在线,在RAM中运行的。

    做完上面后,需要将程序固化,就要用到FLASH操作了!

    在这里分享一个在Matlab/Simulink环境下,用图形化的方式设计 DSP程序的文档。

            先了解一下TMS320F2812的存储模式:采用哈佛总线结构,具有统一的存储模式,包括4M 可寻址程序空间和4M 可寻址数据空间。同时片内具有128 ×16 位的FLASH 存储器和18K ×16 位的SRAM,以及4K×16 位的引导ROM。最大支持外扩512K×16 位的SRAM 和512K×16 位的FLASH。具有两个事件管理器(EVA、EVB)以及外设中断模块(PIE),最大支持96 个外部中断。TMS320F2812 的外部存储器接口(XINTF)被映射到5 个独立的存储空间。所以感觉Flash这一块肯定是一个很可玩的一部分!

    Matlab/Simulink环境下,用图形化的方式设计 DSP程序,可简化程序的设计。利用 Embedded Targetfor T1 C2000 DSP工具包,设计 DSP的 ADC转换程序;利用 Simulink的数字信号处理工具包,设计 FIR滤波嚣进行滤波处理;给出在修改生成的 C语言程序时如何使 DSP能正确运行。设计的程序在 TM$320LF2407A处理器上运行正确。

      1) 在TI C2000 DSP 上自动测试、执行Simulink仿真模型;

      2) 提供模块化的系统和功能,比如PWM、ADC、CAN以及目标板载内存等;

      3) 生成文档化的易读可编辑的C语言代码,并生成Code Composer Studio项目文件;

      4) 在F2407 eZdsp评估板和F2812 eZdsp评估板上进行自动化实时测试;

      5) 对TI推出的IQmath Library提供模块化的支持,可以用于仿真和代码生成;

      6) 可以进行定点系统的设计、仿真、自动定标和代码生成工作。

    基于Matlab的TMS320LF2407程序快速设计.pdf
  • 两夜的经验之谈,总结了两晚上

    C2000.zip
  • 太多的东西,一篇写不开,但是多个附件不会传,所以建了一个压缩包,里面有8篇word,希望对大家有所帮助,写的可能有点急,内容不全面请大家见谅,两晚上总结了一些以前的学习问题,自我感觉还是不错的!!嘿嘿

  • 鉴于我这两晚上的工作,希望大TI能送一块TMDX28069USB,方便以后开发,thank you

  • 德州仪器C2000 是专为实时控制量身打造的,支持高性能集成外设的 32 位微控制器。其数学优化型内核可为设计人员提供能够提高系统效率、可靠性以及灵活性的方法。C2000 器件具有功能强大的集成型外设,是理想的单芯片控制解决方案。C2000 开发工具策略及软件 (controlSUITE) 可创建开放式平台,不但可最大限度地提高可用性,同时还可最大限度地缩短开发时间。

    C2000广泛的实时控制应用

    TI 为设计人员提供了广泛的解决方案,涉及数字电机控制,可再生能源系统,数字电源转换,自适应照明系统,汽车电子,PLC等应用,帮助设计人员解决所面临的任何设计难题。

    C2000 硬件开发工具

    C2000 可提供各种硬件平台,以加速采用 TMS320C2000 微控制器的项目开发进程。从低成本 USB 型 controlSTICK 到用于太阳能、电机控制、照明和数字电源的全功能应用开发者平台,C2000 可提供一系列旨在帮助开发使客户更快推向市场的硬件开发工具。

     controlSTICK—controlSTICK 是独立的低成本 USB 驱动型工具,它可以实现即时评估。借助板载仿真器、访问引脚和示例项目,新用户只需几分钟的时间即可立即运行 C2000 器件,并且无硬件故障。

     controlCARD—用于 TMS320C2000 的 controlCARD 可在一个标准的引脚兼容型 DIM 插槽子卡中高度整合微控制器和所有必需的支持器件。controlCARD 具备插入式通用兼容接口,用户仅需插入新的 controlCARD 即可快速试用我们应用开发套件中的各种 TMS320C2000 MCU。除 controlSTICK 平台以外的所有 TMS320C2000 开发者套件均采用 controlCARD。

     实验套件—用于 TMS320C2000 的实验套件具备与 controlCARD 相兼容的扩展基座,能够轻松访问大部分的 controlCARD 引脚,同时提供用于 TMS320C2000 微控制器的原型设计平台。

     外设学习套件 (Explorer Kit)—外设开发套件可帮助 TMS320C2000 用户和大学生轻松学习如何在 TMS320C2000 微控制器上使用所有高级外设。这些套件兼容 controlCARD,具有的板载硬件和软件示例项目专用于在试验 TMS320C2000 MCU 上找到的外设。

     应用套件—为电机控制、数字电源、太阳能和 LED 照明等重要应用领域提供全面的参考和学习平台。专为具备应用知识且希望了解 TMS320C2000 如何改进目标应用的工程师而设计。该套件提供具有图形用户界面的快速入门指南(通常提供套件及其功能的简介)。了解更多高级开发、更多示例项目和用户指南(帮助用户了解运行和开发套件)。

    C2000应用套件参考设计案例

     高电压电机控制和 PFC 开发者套件

    高压 PFC 和电机控制开发者套件提供了简单的开放源码来评估高压环境下的 Piccolo 微处理器和 TI 模拟。单个 Piccolo MCU 可以控制功率因数校正 (PFC) 级和电机控制级。PFC 将线路电平 AC 输入(~110 至 ~240VAC)和输出升高至 700 瓦功率,采用闭环控制调节。电机驱动器级可以从 PFC 或独立功率级驱动,输入高达 400V,输出高达 1 千瓦功率。电机驱动器级能够驱动三种最常见的无刷电机,即 AC 感应电机、无刷直流电机和永久磁性同步电机。Piccolo 微处理器采用闭环、无传感器控制来控制各类电机。PFC 级和各类电机的套件随附完整的软件包。套件的软件和硬件全部是开放源码。电机软件主要针对各类电机的闭环控制,各类电机将由 TI 直接提供。

    特性:

    • 基于 Piccolo 的功率因素校正 (PFC) 和电机控制集成到一个开发平台中

    • 支持三种无刷电机类型,即 AC 感应电机、永久磁性

    • 同步电机、无刷直流电机

    • 1 千瓦电机驱动器级

    • 700W 功率因数校正级

    • 用于功率因数校正级的开放源码软件

    • 用于控制全部三类电机的开放源码软件

    • 开放源码软件,包括原理图、BOM 和光绘文件

    • 各类电机由 TI 直接提供。

     HV 移相全桥开发者套件

    C2000TM 高电压移相全桥开发者套件设计用于向用户演示如何快速实施数字控制移相全桥拓扑 DC/DC 转换器。此设计还支持带斜率补偿的峰值电流模式控制,且无需外部电路。这是一个高电压套件,用于支持广泛用于终端设备设计的电压电平,为开发者提供使用多种控制方法进行试验的机会。此套件是初级侧 TMDSHVBLPFCKIT 和 TMDSHVPFCKIT 的最佳配套器件,为功率因素校正的 AC 输入级到高效 DC/DC 输出级提供完整的评估平台。此 EVM 另外还具有板载 USB JTAG 仿真,从而无需外部 JTAG 仿真器。EVM 基于 controlCARD 平台,包含一个 F28027 controlCARD 和一个快速入门实验板 GUI。该套件还包含 ControlSUITE、32KB CCS V4 受限版本以及完整的硬件和硬件文档。

    特性

    • 高电压移相 DC/DC 转换器基于 controlCARD 的 EVM

    • 支持峰值电流模式控制(使用斜率补偿)

    • 快速入门图形用户界面

    • 380V 至 400V DC 输入,500W 12V 稳压 DC 输出

    • 多种实验反馈方法

    • 用于故障保护的无损电流感应电路

    • 板载 USB JTAG 仿真

    • 带完整文档的开放源码硬件和软件

    • 详细研究和 PSFB 原理讨论。

     C2000 Piccolo MCU AC LED 照明和通信套件

    C2000 Piccolo MCU LED 照明和通信套件使开发者能够开始进行照明和照明通信的数字控制的设计。凭借 Piccolo MCU 的电源、照明和通信数字控制,开发者可以快速开始智能照明设计。开发板具有高达 250W 的输出,可支持 6 串 LED 和 DALI、DMX512 及电力线通信(PLC,单独出售)等可选智能通信。该集成电源是与 Piccolo MCU 相连的全交流电源,可控制高效隔离谐振 LLC DC/DC 电源拓扑。

    在 controlSUITE、C2000 的 MCU 软件门户中,开发套件具有详细介绍数字电源、照明和通信控制的完整示例项目。从简单的开环设计到完整的闭环控制,对用户进行详细指导。通信软件示例具有同样的功能,详细介绍了常见照明通信协议软件的实施。通过附带的图形用户界面,用户能够快速开始用套件进行实验,然后再实现进一步的软件级别实验。所有套件的硬件和软件全部是开放源码并可通过 controlSUITE 免费提供。

    *电力线通信附加套件 (TMDSPLCMODA-P3X) 包括模拟前端插入式模块和能够使用 AC LED 照明和通信套件实现电力线通信的 Piccolo controlCARD。

    **电力线调制解调器开发者套件 (TMDSPLCKIT-V3) 包括电力线调制解调器,用于使用 AC LED 照明和通信套件实现点对点 PLC 通信。

    特性

    • 交流电源供电,完整的 LED 照明电源,效率约为 90%

    • 通过 UCC28810D 进行功率因数校正 (PFC) 控制,>0.99 PF

    • 通过 Piccolo 数字控制实现隔离谐振 LLC DC/DC

    • 通过 Piccolo 进行远程连接,包括 DALI、DMX512 和电力线通信(PLC,单独出售)

    • Piccolo 支持高达 250W 的 6 通道独立和多串调光

    • C2000 的模块化 controlCARD 概念,使开发者能够使用价格、性能和外设功能设置要求方面均为适合的各种 C2000 MCU 进行实验。

    • 附带的 controlSUITE 软件提供用于对 AC/DC 电源、多串 LED 控制和高级通信进行完整闭环控制的简便易用和开源演示 GUI、软件示例和文档。

    controlSUITETM 软件--全面、 直观、 优化

    用于 C2000TM 微处理器的 controlSUITETM 是一套全面的软件基础设施和软件工具集,以全面满足每个设计阶段对更加直观易用的软件的需求,旨在最大程度地缩短软件开发时间。与传统 MCU 产品不同,controlSUITE 软件可为简化评估、应用自适应、调试、测试以及重复使用提供必要的内容与内容管理。controlSUITE 软件除免费软件产品系列常见的简单演示之外,还可提供能够作为真正开发系统使用的全面开源项目 —— 库与示例,实现诸如电机控制等应用。此外,全新安装程序还可消除版本与依赖性等问题,使开发人员能够在集中区域获得完整的软件产品。

    C2000 丰富全面的软件生态系统

     应用程序开发—系统范例,应用程序库

     器件评估—基础程序库,标头文件和工程范例

     调式与代码生成—第三方程序库及仿真,CCS集成型开发环境

    TI 在线技术支持社区

    欢迎加入德州仪器在线技术支持社区与同行工程师互动交流,咨询问题并帮助解决技术难题: www.deyisupport.com 。

    TI 各种系列的 MCU 与软件

    从通用型超低功耗 MSP430™ 微控制器 (MCU) 到 Stellaris® Cortex™-M MCU,再到实时控制 C2000™ MCU,乃至 Hercules™ 安全 MCU,TI 可为设计人员提供最广泛的各种微控制器解决方案。通过充分利用 TI 全面的软硬件工具、广泛的第三方产品以及技术支持,设计人员可加速产品的上市进程。

    公司信息:

    TI-德州仪器

  •     使用TMS320C2812控制异步电机的程序,采用SVPWM空间矢量控制算法,运行正常,加减速,正反转等.

       

       首先,初始化设备,

    /*初始化系统*/

        InitSysCtrl();

     

        /*关中断*/

        DINT;

        IER = 0x0000;

        IFR = 0x0000;

     

        /*初始化PIE控制寄存器*/

        InitPieCtrl();

     

        /*初始化PIE矢量表*/

        InitPieVectTable();

     

        /*初始化SCIb寄存器*/

        InitSci();

     

        /*设置CPU定时器*/

        InitCpuTimers();

        ConfigCpuTimer(&CpuTimer2, 150, 20000);

        StartCpuTimer2();

     

        /*初始化IO口*/

     InitGpio();

     

        /*初始化EV*/

        eva.Init(&eva);

        evb.Init(&evb);

    下步,(个人习惯写个显示程序)

    void ShowDisp(void)       //显示

    {

        static unsigned int i=0;

        switch(i)

        {

        case 0:

            i++;

            ScibRegs.SCITXBUF =(ku&0xf)+(3<<5);

            break;

        case 1:

            if(RunFlag)     ScibRegs.SCITXBUF =23+(2<<5);

            else        ScibRegs.SCITXBUF =24+(2<<5);

            i++;

            break;

        case 2:

            if(RunFlag)     ScibRegs.SCITXBUF =f_now/10+(1<<5);

            else            ScibRegs.SCITXBUF =f_given_disp/10+(1<<5);

            i++;

            break;

        case 3:

            if(RunFlag)     ScibRegs.SCITXBUF =f_now%10;

            else        ScibRegs.SCITXBUF =f_given_disp%10;

            i=0;

            break;

        default:

            i=0;

            break;

        }

     

    下面再写,各功能模块:

    1、  矢量计算和PWM生成

    以下给出步骤1中的控制参数及其调节范围

    EnableFlag:0、1;启停控制位

    SpeedRef:(0~0.99);速度给定值

    VdTesting:(0~0.9);D轴电流给定

    VqTesting:(0~0.9);Q轴电流给定

    步骤1

    实验一流程图

     

     

    void rampgen_calc(RAMPGEN *v)

    {  

     

    // Compute the angle rate

            v->Angle += _IQmpy(v->StepAngleMax,v->Freq);      

     

    // Saturate the angle rate within (-1,1)       

            if (v->Angle>_IQ(1.0))

              v->Angle -= _IQ(1.0);

            else if (v->Angle<_IQ(-1.0))

              v->Angle += _IQ(1.0);

     

    // Compute the ramp output

           v->Out = _IQmpy(v->Angle,v->Gain) + v->Offset;

     

    // Saturate the ramp output within (-1,1)    

           if (v->Out>_IQ(1.0))

              v->Out -= _IQ(1.0);

            else if (v->Out<_IQ(-1.0))

              v->Out += _IQ(1.0);

     

    }

     

    void RotateVecotr_calc(RotateVecotr_Handle v)

    {

         _iq Ua,Ub;

      

    // Using look-up IQ sine table

         Ub   = _IQsinPU(v->Angle);

         Ua   = _IQcosPU(v->Angle);

     

         v->Ualpha = _IQmpy(v->k,Ua);

         v->Ubeta  = _IQmpy(v->k,Ub); 

    }

    void scope(void)

    {

       

        long tl,tm,t0;

        tl = svpwm.tl;

        tm = svpwm.tm;

        t0 = ((long)1<<19) - tl - tm;

        switch(svpwm.vect)

            {

                case 2:ua = t0+tm;  ub = t0;            break;

                case 3:ua = 0;      ub = tl;             break;

                case 1:ua = t0;     ub = ((long)1<<19);      break;

                case 5:ua = tl;     ub = tl+tm;             break;

                case 4:ua = ((long)1<<19); ub = tm+t0;      break;

                case 6:ua = tl+tm;      ub = 0;          break;

                default:                                   break;

            }

        uab=ua-ub;

    }

     

     

    2、这就是传说中的精华所在:电流、直流母线电压、速度测试

     

    void svgendq_calc(SVGENDQ *v)

    {  

     

        _iq Va,Vb,Vc,t1,t2;

        unsigned long Sector = 0;  // Sector is treated as Q0 - independently with global Q

                                                                       

    // Inverse clarke transformation

        Va = v->Ubeta;

        Vb = _IQmpy(_IQ(-0.5),v->Ubeta) + _IQmpy(_IQ(0.8660254),v->Ualpha);  // 0.8660254 = sqrt(3)/2

        Vc = _IQmpy(_IQ(-0.5),v->Ubeta) - _IQmpy(_IQ(0.8660254),v->Ualpha);  // 0.8660254 = sqrt(3)/2

     

    // 60 degree Sector determination

        if (Va>_IQ(0))

           Sector = 1;

        if (Vb>_IQ(0))

           Sector = Sector + 2;

        if (Vc>_IQ(0))  

           Sector = Sector + 4;

          

    // X,Y,Z (Va,Vb,Vc) calculations

        Va = v->Ubeta;                                                       // X = Va

        Vb = _IQmpy(_IQ(0.5),v->Ubeta) + _IQmpy(_IQ(0.8660254),v->Ualpha);   // Y = Vb

        Vc = _IQmpy(_IQ(0.5),v->Ubeta) - _IQmpy(_IQ(0.8660254),v->Ualpha);   // Z = Vc

       

        if (Sector==0)  // Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)

        {

           v->Ta = _IQ(0.5);

           v->Tb = _IQ(0.5);

           v->Tc = _IQ(0.5);

        }

        if (Sector==1)  // Sector 1: t1=Z and t2=Y (abc ---> Tb,Ta,Tc)

        {

           t1 = Vc;

           t2 = Vb;

           v->Tb = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2));      // tbon = (1-t1-t2)/2

           v->Ta = v->Tb+t1;                             // taon = tbon+t1

           v->Tc = v->Ta+t2;                             // tcon = taon+t2

        }

        else if (Sector==2)  // Sector 2: t1=Y and t2=-X (abc ---> Ta,Tc,Tb)

        {

           t1 = Vb;

           t2 = -Va;

           v->Ta = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2));      // taon = (1-t1-t2)/2

           v->Tc = v->Ta+t1;                             // tcon = taon+t1

           v->Tb = v->Tc+t2;                             // tbon = tcon+t2

        }     

        else if (Sector==3)  // Sector 3: t1=-Z and t2=X (abc ---> Ta,Tb,Tc)

        {

           t1 = -Vc;

           t2 = Va;

           v->Ta = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2));      // taon = (1-t1-t2)/2

           v->Tb = v->Ta+t1;                             // tbon = taon+t1

           v->Tc = v->Tb+t2;                             // tcon = tbon+t2

        }  

        else if (Sector==4)  // Sector 4: t1=-X and t2=Z (abc ---> Tc,Tb,Ta)

        {

           t1 = -Va;

           t2 = Vc;

           v->Tc = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2));      // tcon = (1-t1-t2)/2

           v->Tb = v->Tc+t1;                             // tbon = tcon+t1

           v->Ta = v->Tb+t2;                             // taon = tbon+t2

        }   

        else if (Sector==5)  // Sector 5: t1=X and t2=-Y (abc ---> Tb,Tc,Ta)

        {

           t1 = Va;

           t2 = -Vb;

           v->Tb = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2));      // tbon = (1-t1-t2)/2

           v->Tc = v->Tb+t1;                             // tcon = tbon+t1

           v->Ta = v->Tc+t2;                             // taon = tcon+t2

        }  

        else if (Sector==6)  // Sector 6: t1=-Y and t2=-Z (abc ---> Tc,Ta,Tb)

        {

           t1 = -Vb;

           t2 = -Vc;

           v->Tc = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2));      // tcon = (1-t1-t2)/2

           v->Ta = v->Tc+t1;                             // taon = tcon+t1

           v->Tb = v->Ta+t2;                             // tbon = taon+t2

        }

     

    3、这个工程还没做完,先上这么多。

    4、这块是上面初始化部分的,模块化程序,凑个字数,嘻嘻!!

    void InitXintf(void)

    {

     

        #if  F2812

        // Example of chaning the timing of XINTF Zones. 

        // Note acutal values should be based on the hardware

        // attached to the zone - timings presented here are

        // for example purposes.

        

        // All Zones:

        // Timing for all zones based on XTIMCLK = SYSCLKOUT

        XintfRegs.XINTCNF2.bit.XTIMCLK = 0x0000;

       

        // Zone 0:

        // Change write access lead active trail timing

        // When using ready, ACTIVE must be 1 or greater

        // Lead must always be 1 or greater

        // Use timings based on SYSCLKOUT = XTIMCLK

        XintfRegs.XTIMING0.bit.XWRTRAIL = 3;

        XintfRegs.XTIMING0.bit.XWRACTIVE = 7;

        XintfRegs.XTIMING0.bit.XWRLEAD = 3;

        // Do not double lead/active/trail for Zone 0

        XintfRegs.XTIMING0.bit.X2TIMING = 0;

       

        // Zone 2

        // Ignore XREADY for Zone 2 accesses

        // Change read access lead/active/trail timing

        XintfRegs.XTIMING2.bit.USEREADY = 0;

        XintfRegs.XTIMING2.bit.XRDLEAD = 3;

        XintfRegs.XTIMING2.bit.XWRACTIVE = 7;

        XintfRegs.XTIMING2.bit.XRDTRAIL = 3;

        // Double lead/active/trial timing for Zone 2

        XintfRegs.XTIMING2.bit.X2TIMING = 1;

     

        // Zone 2 is slow, so add additional BCYC cycles when ever switching

        // from Zone 2 to another Zone.  This will help avoid

        // bus contention.

        XintfRegs.XBANK.bit.BANK = 2;

        XintfRegs.XBANK.bit.BCYC = 3;

       

        #endif

    }  

     

    DSP2812控制异步电机.docx
  • 我是一个电子爱好者(哈哈,同伙肯定不少),本科阶段就开始对处理器的学习,从起初的C51单片机,到后来的FPGA,以及现在风靡的ARM处理器,这些我都一步步逐渐学习过来了,这些芯片深深地吸引了我,其也帮助我完成了许多项目。后来我渐渐地发现我对硬件的学习还不够完善,缺少了DSP这部分的学习,是啊,由于缺少DSP这部分的学习,好多现有的想法都无法去实现,例如,我想实现一个音频的处理平台(包括:音频的MIC输入,音频的PCM解码、音频的压缩编码、音频的扩音器输出),这其中的音频的压缩编码部分是用其它类型的芯片所无法完成的,除此之外,对于其它各模块(包括:音频的MIC输入,音频的PCM解码、音频的扩音器输出)TI也都有相应的音频处理芯片。我现在就正在使用其中的一款芯片:TLV320AIC1106,其是具有麦克风放大器和扬声器驱动器的PCM编解码器,此引脚采用20引脚TSSOP封装,对于我DIY来说易于焊接,功能也相当强大。后来我又渐渐地开始了对DSP的学习。

    好了,关于其它的芯片就先说到这吧,近期,关注到TI开始推出在MCU领域的芯片,一向对TI芯片都很关注的我,这一次也不容错过,我开始了解有关C2000的知识,并在TI官网上申请到了一块TMS320F2808GGMA的样片,TI真够速度的,申请样片的两天后就到了,我就花了一周的时间制作了一块双层的PCB板,板子上是其最小系统,具体器件的参数,我也是参考了其Datasheet上的推荐值设置的,然后又花费了大概一周左右的时间,去焊接这款芯片,众所周知,100引脚的芯片不好焊啊,没办法啊,咱不是没有工厂的过流焊机吗,再说也就这么一块板子,也不值当专门去焊接,于是我就向我的导师请教,这才第一次了解到,多管脚芯片不能像平常DIP封装的芯片那样一个一个的管脚去焊接,而应该是采用焊锡膏再加上热风枪,再导师的帮助下,这才完成了整个板子的焊接。这才是万里长征的第一步,还有许多关于硬件和软件的知识,还需要再慢慢学习。

    经过近5年对处理器的学习和实践,我也逐渐摸索出了一种学习硬件的路数。对于一款MCU来说,首先要了解其硬件配置,例如其处理器位数,工作频率范围,FLASH、RAM大小,集成的外设的种类,例如:PWM、SPI、SCI、CAN、I²C、ADC等,可用GPIO个数等指标。对于TMS320F2808GGMA芯片来说,其内部具有64K×16bit的FLASH和18K×16bit的RAM,可基本满足其作为MCU对外部设备控制的要求。

    再对芯片级硬件结构有了大致的了解之后,接下来需要做的就是搭建系统的硬件系统架构,这是对芯片编写程序的基础,否则只能是空中楼阁。由于本次试验是想了解TI的C2000微控制器的开发流程,所以在功能相对简单一些,都是一些孤立的小系统,前一段时间还一直在做,这些小系统包括:

    基于IT中断的8*LED流水灯

    按键控制无源蜂鸣器

    LCD1602液晶驱动显示

    AD模数转换LCD1602液晶驱动

    基于IIC的EEPROM读写

    PWM模块实现H桥直流马达驱动

    计划后期还要实现在TMS320F2808GGMA芯片上移植UCOSii操作系统,到时候测试一下运行多任务程序的效果如何。

    这些小系统这么多,就找其中一个典型的例子:AD模数转换LCD1602液晶驱动,来给大家说一说吧。图就不上了,系统也很简单,从可变电阻开始,其直接连接到TMS320F2808GGMA芯片的AD管脚上,设置好AD的工作模式为单次固定通道采集,可变电阻是用来改变AD管脚的输入电压,范围在0到5V可调,另外一侧通过TMS320F2808GGMA的12个GPIO来控制LCD1602液晶显示屏,使其实时显示AD端口的输入电压,这个小测试系统的整体架构就是这样的。

    接下来可就是我们熟悉的给TMS320F2808GGMA芯片进行编程了哦,当然编程工具都是TI关注者最熟悉的软件:Code Composer Studio IDE,传说中的CCS,哈哈!具体程序的编写我也就不说了,旨再为那些还未曾了解过或刚刚入门C2000的TI迷们提供思路,抛砖引玉,文中难免有不正确之处欢迎拍砖!

    谢谢!

  • 以前一个项目里有一部分是使用2812控制无刷直流电机,这里分享一下软硬件设计和程序代码~~

    基于TMS320F2812的无刷直流电机控制.doc
  • “1.在其中controlSUITE软件的中文显示不知为何为乱码,可以是翻译的问题或者为中文的简体与繁体的转换问题”,其显示乱码的地方弹右键,选编码—自动选择即可!

  • 谢谢了。又学会了一个方法。呵呵

  • 先分享点 XIntrupt的设计心得。。。。

    TMS320F28335外部中断总结

    作者:Free    文章来源:Free    点击数:93    更新时间:2010-8-26   

     

    在这里我们要十分清楚DSP的中断系统。C28XX一共有16个中断源,其中有2个不可屏蔽的中断RESETNMI、定时器1和定时器2分别使用中断13

    14。这样还有12个中断都直接连接到外设中断扩展模块PIE上。说的简单一点就是PIE通过12根线与28335核的12个中断线相连。而PIE的另外

    一侧有12*8根线分别连接到外设,如ADSPIEXINT等等。这样PIE共管理12*8=96个外部中断。这12组大中断由28335核的中断寄存器IER来控

    制,即IER确定每个中断到底属于哪一组大中断(如IER |= M_INT12;说明我们要用第12组的中断,但是第12组里面的什么中断CPU并不知道需

    要再由PIEIER确定 )。接下来再由PIE模块中的寄存器PIEIER中的低8确定该中断是这一组的第几个中断,这些配置都要告诉CPU(我们不难想

    象到PIEIER共有12总即从PIEIER1-PIEIER12)。另外,PIE模块还有中断标志寄存器PIEIFR,同样它的低8位是来自外部中断的8个标志位,同

    CPUIFR寄存器是中断组的标志寄存器。由此看来,CPU的所有中断寄存器控制12组的中断,PIE的所有中断寄存器控制每组内8个的中断。

    除此之外,我们用到哪一个外部中断,相应的还有外部中断的寄存器,需要注意的就是外部中断的标志要自己通过软件来清零。而PIECPU

    中断标志寄存器由硬件来清零。

     

     

        EALLOW;  // This is needed to write to EALLOW protected registers

     

       PieVectTable.XINT2 = &ISRExint; //告诉中断入口地址

     

       EDIS;    // This is needed to disable write to EALLOW protected registers

     

     

     

       PieCtrlRegs.PIECTRL.bit.ENPIE = 1;          // Enable the PIE block使能PIE

     

        PieCtrlRegs.PIEIER1.bit.INTx5= 1;   //使能第一组中的中断5

     

       IER |= M_INT1;                              // Enable CPU 第一组中断

     

     

     

        EINT;   // Enable Global interrupt INTM

     

        ERTM;   // Enable Global realtime interrupt DBGM 

     

    也就是说,12组中的每个中断都要完成上面的相同配置,剩下的才是去配置自己的中断。如我们提到的EXINT,即外面来个低电平我们就进入

    中断,完成我们的程序。在这里要介绍一下,DSPGPIO口都可以配置为外部中断口,其配置方法如下:

     

         GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 0; //选择他们是GPIO

     

         GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 0;

     

         GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 0;

     

         GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 0;

     

         GpioCtrlRegs.GPBDIR.bit.GPIO54 = 0;//选择他们都是输入口

     

         GpioCtrlRegs.GPBDIR.bit.GPIO55 = 0;

     

         GpioCtrlRegs.GPBDIR.bit.GPIO56 = 0;

     

         GpioCtrlRegs.GPBDIR.bit.GPIO57 = 0;

     

         GpioCtrlRegs.GPBQSEL2.bit.GPIO54= 0;//GPIO时钟和系统时钟一样且支持GPIO

     

         GpioCtrlRegs.GPBQSEL2.bit.GPIO55= 0;

     

         GpioCtrlRegs.GPBQSEL2.bit.GPIO56= 0;

     

         GpioCtrlRegs.GPBQSEL2.bit.GPIO57= 0;

     

         GpioIntRegs.GPIOXINT3SEL.bit.GPIOSEL = 54;//中断3选择GPIO

     

         GpioIntRegs.GPIOXINT4SEL.bit.GPIOSEL = 55;

     

         GpioIntRegs.GPIOXINT5SEL.bit.GPIOSEL = 56;

     

         GpioIntRegs.GPIOXINT6SEL.bit.GPIOSEL = 57;

     

         XIntruptRegs.XINT3CR.bit.POLARITY= 0;//触发模式为下降沿触发

     

         XIntruptRegs.XINT4CR.bit.POLARITY= 0;

     

         XIntruptRegs.XINT5CR.bit.POLARITY= 0;

     

         XIntruptRegs.XINT6CR.bit.POLARITY= 0;

     

         XIntruptRegs.XINT3CR.bit.ENABLE = 1;//使能中断

     

         XIntruptRegs.XINT4CR.bit.ENABLE = 1;

     

         XIntruptRegs.XINT5CR.bit.ENABLE = 1;

     

         XIntruptRegs.XINT6CR.bit.ENABLE = 1;

     

    注意一点就是外部中断12只能对GPIO0GPIO31配置;外部中断34567只对GPIO32GPIO63配置。

    TMS320f28027_英文资料.pdf
  • 哈哈,看一下!

  •                                               《于TMS320F2812电机控制的PWM驱动程序设计
             我们在以TMS320F2812 TI DSP为核心的电动机系统设计中,DSP主要是负责管理协调、监督与控制系统各个环节任务。由于变频调速系统属于快速性要求较
    高的运动控制范畴,系统受控状态量的变化很快,这就要求系统的采用的周期要尽可能的要短,鉴于该系统的采样要求的实时性要求都是很高,因此在软件设计时必须在合理安排好各个以及程序模块结构相互之间的时序配合。系统软件设计可能可分为初始化模块和控制模块部分。本系统采用的转子磁场定向策略,其主要工作是由控制模块中的中断来完成的系统程序的主程序和控制模块流程图如下:在位置偏差进入较大范围的时候采用能快速纠偏的非线性控制作为开始的初定位。为了保证精度,在位偏差进入较小范围内的时候,控制器由非线性控制转换成线性控制,从而保证位置控制的快速性和精确性。


           对于模块初始化,主要包括硬件初始化、软件变量初始化以及循环等待等。其中硬件初始化主要完成DSP的设置,如看门狗、时钟、计时器、ADC、SCI、I/O、

    事件管理器(EV)等的设置;软件变量初始化对软件变量赋予初值;等待循环通过中断方式与DSP进行通信。通过软件设计可以改变电动机的转速和方向。应用程序如下:
    ==============================================================================================================
    #include"DSP281x_Device.h"       //DSP281x Headerfile include file
    #include"DSP281x_Examples.h"     //DSP281x Examples include file

    // Prototype statements for functions found within this file.
     void init_rva (void);


    //Golbal counts used in this example


    void main (void)
    {


    //Step 1.Initialize system control:
    //PLL,Watchdog,enable peripheral clocks
    //This example function is found in the DSP281x_Sysctrl.c file.
     initsysctrl()

    //Step 2.initallize GPIO:
    //this example function is found in the DSP281x_Gpio.c file and
    //illustrates how to set the GPIO to it's defult state.
    //InttGpio ();//skipped for this test
      EALLOW
      //Enable PWM pins
      GpioMuxRedgs.GPAMUX.all = 0x00FF;//EVA PWM 1-2 pins

      EDIS;

    //Step 3.clear all interrupts and initialize PIE vector table:
    //Disable CPU interrupts
      DINT;

    //Initialize PIE control registers to their default state.
    //The default state is all PIE interrupts disabled and flags
    //are cledred.
    //This function is found in the DSP281x_PieCtrl.c file.
      InitPieCtrl();

    //Disable CPU interrupts and clear all CPU interrupt flags:
      IER = 0x0000;
      IFR = 0x0000;

    //Initialize the PIE vector table with pointers to the shell Interrupt
    //Service routines (ISR).
    //This will populate the entire table, even if the interrupt
    //is not used in this example. this is useful for debug purposes.
    //The shell ISR routines are found in DSP281x_pieVect.c.
    //This function is found in DSP281x_pieVect.c.
      InitpieVectTable();

    //Step 4. initialize all the device Peripherals;
    //This function is found in DSP281x_initperipherals.c
    //Initperipherals ();// Not required for this example
      init_eva();


    //Step 5.user specific code,enable interrupts:
    //Just sit and loop forever:
    //PWM pins can be observed with a scope.
      for(;;);

    }

    void init_eva()
    {
     
     
      //initalize EVA Timerl
      EvaRegs.T1PR = 0xFFFF;         //Timer1 period
      EvaRegs.T1CMPR = 0x3c00;       //Timer1 compare
      EvaRegs.T1CNT = 0x0000;        //Timer1 counter
      EvaRegs.T1CNT.all = 0x1042;


     // Drive T1/T2 PWM by compare logic
      EvaRegs.GPTCONA.bit.TCMPOE = 1;
     //polarity of GP timer 1 compare = active low
      EvaRegs.GPTCONA .bit.T1PIM = 1 ;
     //enable compare for PWM1-PWM2
      EvaRegs.CMPR1 = 0x0C00;
     

      EvaRegs.ACTRA.all = 0x0666;
      EvaRegs.DBTCONA.all = 0x0000;// disable deadband
      EvaRegs.COMCONA.ALL = 0xA600;

    }
    ==================================================================================================

    经过量产试验证明,利用TMS320LF2812 DSP构建的直流电动机控制器控制方式简单,输出信号很稳定。调速性能非常好,可以应用在各种各样高精密调速系统和位置

    伺服系统中大量使用。

     

  • 期待,祈祷一下这次能拿到板子!继续好好学习!

    谢谢TI和各位管理员!

  • 感谢TI举办这次活动,给我们初学者一个很好的机会,给我们一个良好地硬件条件。

     

    学习DSP有一段时间了!一直都是借用的TI 以TMS320F2812为主芯片的一块板子上实现的,因为使用时间不能保障,学习进度有点慢,前一段时间主要熟悉了存储器映射结构,GPIO的控制,看门狗,ADC,SPI,学习中是通过在线,在RAM中运行的。

    做完上面后,需要将程序固化,就要用到FLASH操作了!

    了解一下TMS320F2812的存储模式:采用哈佛总线结构,具有统一的存储模式,包括4M 可寻址程序空间和4M 可寻址数据空间。同时片内具有128 ×16 位的FLASH 存储器和18K ×16 位的SRAM,以及4K×16 位的引导ROM。最大支持外扩512K×16 位的SRAM 和512K×16 位的FLASH。具有两个事件管理器(EVA、EVB)以及外设中断模块(PIE),最大支持96 个外部中断。TMS320F2812 的外部存储器接口(XINTF)被映射到5 个独立的存储空间。所以感觉Flash这一块肯定是一个很可玩的一部分!

    查看TI的文档,原来在擦除flash阵列前后,不能时进行复位,这样会使pwl中的值为0,导致flash被锁死,所以每次往flash里面写东西都很担心,后来发现只要在擦出前后不断电,基本上不会发生问题,这样写了很多次都是OK的!

    F2812的程序在仿真状态下调试好了以后,要移植到脱机运行并不难,一个很简单的方法,打开外围接口例程中的FLASH工程,把文件添加到这个工程中去,用F2812.CMD更换原来你的程序里面的CMD.编译通过后,通过烧写插件下载,就可以脱机运行了。

     

    分享一个最近在做的一个项目资料   共同学习

    基于ADS8482与TMS320F28335的信号采集系统

    针对加速度计电流信号微弱,给出一种大动态范围的高速高精度信号采集系统。介绍模数转换器ADS8482的 性能,和T-作原理.并给出ADS8482与DSPTMS320F28335的接口设计方案。包括部分硬件电路和软件编程代码。外 围扩展的CPLD EPM7l28控制ADS8482。该方案实现的加速度计检测装置简单实用,可应用于中低精度的惯性测 量中。

    (具体内容见附件)

     

    基于ADS8482与TMS320F28335的信号采集系统.pdf
  • 谢谢了。已经收到C2000了。很精美。

  • 关于C2000芯片的FLASH锁死以及解决办法!详细说明文档已经写在压缩包里了

  • 基于TMS320LF2407A的电能质量检测电路设计    

    电能质量(Power Quality),从普遍意义上讲是指优质供电,包括电压质量、电流质量、供电质量和用电质量。随着电力、电子技术的迅速发展,特别是电炉炼钢、多项可控硅整流、电机变频调速以及洗衣机、空调等家电设备的广泛应用,电网质量问题正变得日益严峻,严重威胁着电力设备的正常使用,及时准确的获得电能质量参数,对工业发展具有重要的指导意义。

    本系统采用TMS320LF2407A为控制核心,同时还扩展了接口电路----键盘和LCD显示电路。霍尔电压、电流互感器对电力系统进行实时数据的采集,将采集到的电压、电流瞬时值通过数据处理计算出电能质量的相关参数。通过SCI接口将采集的数据传送到PC机进行误差分析。硬件系统框图如下图所示。

     

    main( )

    { 

       SystemInit( );                    //系统初始化

       MCRC=MCRC & 0xFF00;         //IOPE0-7设为IO端口模式

       PEDATDIR=0xFF00;            //所有LED=0,

       MCRA=MCRA & 0x00C7;          //IOPB0-7设为IO端口模式,IOPA3-5IO模式

       PADATDIR=0xFFC0;

       PBDATDIR = PBDATDIR & 0x00FF;

       asm(" CLRC INTM ");

     

       Timer1Init( );                            //定时器初始化

       SCI_Init( );                       //SCI串口初始化

       LcdInit( );                         //液晶初始化

       WriteMenu(MenuTab);               //开机界面

       While(1)

       {

          ScanKey( );                      //键盘扫描

    }

    }

    中断服务模块

     

    定时器中断子程序:

    void  c_int2( )               /*定时器1中断服务程序*/

    {

        if(PIVR!=0x27)

                  {    asm(" CLRC INTM ");

                         return;

                  }

           T1CNT=0;                        //定时器计数器清零

           numlcd++;

           t0++;

           t2++;

           if((SCI_FLAG==0) & (t0%129)==0)

            {

               SCI_FLAG=1;                  //SCI串口通信标志

               t0=1;

           }

    if (numlcd%2000==0) KeyLcd( );       //刷新液晶显示数据

    if(numlcd>=2000) numlcd=0;

    EVAIFRA=0x80;

    asm(" CLRC     INTM ");             //清除中断屏蔽位

    }

    外部中断子程序:

    void  interrupt  AD_start( )

    {   

         T1CON=T1CON & 0xE7FF;

         flag = ~flag;

         flag = flag & 0x1;            //flag取反

         T1CNT=0;

               SCI_FLAG=0;

         t0=1; t1=0; t2=1;

    XINT2CR = XINT2CR | 0x8000;   //高优先级中断,清除周期中断标志

               asm(" CLRC  INTM ");

    }

    信号采集单元

     

    AD数据采集子程序:

    void  AD_Sample( )

    {  

        ADCTRL1=0x4000;                      /* ADC模块复位 */

        asm(" NOP     ");

        ADCTRL1=0x0020;              /* 自由运行,启动/停止模式,双排序器工作模式 */

        MAXCONV=0x0000;

        CHSELSEQ1=0x0000;             //0通道

        ADCTRL2=0x4000;                 //复位使排序器指针指向CONV00

        ADCTRL2=0x2000;                               /* 启动ADC转换 */

        while( (ADCTRL2 & 0x1000)==0x1000);           /*等待转换完成 */

        asm(" NOP ");

        asm(" NOP ");

        RESULT_0=RESULT0>>6;

        MAXCONV=0x0000;                          //8通道

        CHSELSEQ3=0x0008;

        ADCTRL2=0x0040;

        ADCTRL2=0x0020;

        while( (ADCTRL2 & 0x0010)==0x0010);

        asm(" NOP ");

        asm(" NOP ");

        RESULT_8=RESULT8>>6;

      }

    AD转换流程图

     

    测试结果

                  电烙铁的电压测量数据

    数据组数

    Urms/V

    Ureal/V

    误差d1

    1

    218

    218.4

    -0.4

    2

    221

    219.1

    1.9

    3

    226

    219.7

    6.3

    4

    222

    219.1

    2.9

    5

    213

    218.4

    -5.4

    6

    220

    218.5

    1.5

    7

    213

    218.7

    -5.7

    8

    219

    218.5

    0.5

    9

    225

    219.1

    5.9

    10

    214

    218.5

    -4.5

    平均值

    219.1

    218.8

    0.3

         电烙铁的电流测量数据

    数据组数

    Irms/A

    Ireal/A

    误差d2

    1

    0.135

    0.135989

    -0.00099

    2

    0.134

    0.136011

    -0.00201

    3

    0.134

    0.13564

    -0.00164

    4

    0.134

    0.135555

    -0.00155

    5

    0.137

    0.135989

    0.001011

    6

    0.134

    0.135011

    -0.00101

    7

    0.133

    0.135345

    -0.00235

    8

    0.139

    0.136384

    0.002616

    9

    0.133

    0.136011

    -0.00301

    10

    0.137

    0.135011

    0.001989

    平均值

    0.135

    0.135695

    -0.00069

     电烙铁的功率测量数据

    数据组数

    功率P/W

    实际功率/W

    误差d3

    1

    29.43

    29.7

    -0.27

    2

    29.614

    29.8

    -0.186

    3

    30.284

    29.8

    0.484

    4

    29.748

    29.7

    0.048

    5

    29.181

    29.7

    -0.519

    6

    29.48

    29.5

    -0.02

    7

    28.329

    29.3

    -0.971

    8

    30.441

    29.8

    0.641

    9

    29.925

    29.8

    0.125

    10

    29.318

    29.5

    -0.182

    平均值

    29.575

    29.69

    -0.115

     

    本系统能够基本实现电能质量各项参数的测量,同时又受到负载的限制。当第一级I-V变换电路的输出电压峰峰值超过10V时,偏置电路的输出信号会产生失真。在系统的软硬件调试的过程中采用的是低功耗的电阻性负载,因此转换得到的电流信号的线性度在理想的范围内,对相位漂移的影响也较小,信号调理电路输出的信号也比较稳定。但是当负载为非电阻性负载时,电流端信号处理电路的输出信号会有一定程度的闪变,从而导致采样的数据产生误差,最终导致测量结果不准确。其次,由于前端信号处理电路的局限性,当输入的电流较小时,容易受外界环境和内部电路的失调电流的干扰,造成许多不确定的因素,也会对后续的采样和数据运算产生影响。

    还有必要在以下方面做进一步的研究:

    1. 信号调理部分电路的抗干扰能力没有经过足够充分且严格的测试与实验。在调试过程中有时会出现较大的测试误差,在信号转换端可以考虑精度更高、线性特性更好的霍尔型高精度传感器,以确保输出信号的稳定性和准确度。

    2. 测量的精度不够,既有模拟电路的原因,又有数字电路部分的原因。因此要在这两部分加以改进:模拟量的变换需要运用更精确的方法,本文没有外接A/D转换电路,采用TMS320LF2407A芯片内部自带A/D10位)来实现的,可以考虑外接更高位数的A/D转换芯片;数字电路方面,特别是选择DSP芯片方面,应该选择一款适用于浮点运算的DSP芯片,这样会使测量的速度和精确度都得到改善。

    3. 测量使用的算法过于简单,数据处理能力有限,可以尝试频域FFT算法来实现数据的运算。

    硬件系统原理图

     

    PCB图

     

    电压、电流测量电路

     

    脉冲电路

    脉冲产生电路通过TI公司生产的LM393双路比较器芯片来实现,其原理电路如下图所示。

     

    系统软件设计

     

  • 图片挂了,上传word吧!

    基于TMS320LF2407A的电能质量检测电路设计

    基于TMS320LF2407A的电能质量检测电路设计.doc
  • 板子收到,感谢TI............................

  • 基于TMS320LF2407上实现快速傅里叶变换(FFT

    在DSP中,经常会对信号进行一些算法,FFT算是最常用的一种算法!

     1.快速傅立叶变换(FFT)的原理

    FFT是计算DFT的快速算法,但是它是基于复数的,所以计算实数DFT的时候需要将其转换为复数的格式,下图展示了实数DFT和虚数DFT的情况,实数DFT将时域中N点信号转换成2个(N/2+1)点的频域信号,其中1个(N/2+1)点的信号称之为实部,另一个(N/2+1)点的信号称之为虚部,实部和虚部分别是正弦和余弦信号的幅度。

    相比较而言,复数DFT将2个N点的时域信号转换为2个N点的频域信号。时域和频域中,1个N点信号是实部,另1个N点信号是虚部。

    如果要计算N点实数DFT,则将这个N个点作为时域中的实部,另取N个0点作为时域的虚部,用FFT计算这样一个复数信号的DFT得到2个N点的频域信号,1个N点是实部另1个N点是虚部,在这两个N点的信号中,从0到N/2个点就是须计算的N点实数的DFT频域。

    对于实数DFT来说,就像前几章讲的那样,它的频域也是离散周期信号,其周期为N点,从0到N/2点和1-N到-1点具有对称性,这个你可以从下面一张图看出。图中坐标不是用N表示是用采样频率的分数表示,如果你看不懂,请看前面几章。


    所以你如果用FFT反变换计算的是实数时域,则要满足上图的对称性。
    --------------------------------
    FFT如何工作

    FFT的计算可以分为三步:首先将1个N点的时域信号分成N个1点的时域信号,然后计算这N个1点时域信号的频域,得到N个频域的点,然后将这个N个频域的点按照一定的顺序加起来,就得到了我们需要的频谱。这里每个点的意思是复数,都有实部和虚部。

    第一步的信号分解按照下面的规律执行:


    可以看出它是按照比特反转顺序来分解的。

    第二步是计算每个点的频谱:
    这一步很简单,因为一个时域的点的频谱的数值就是它自己,所以这一步什么也不需做,但需明白这时候N个点不是时域信号了,而是频域信号。

    第三步是将这N个频域信号结合起来
    这一步是最麻烦的一步。就是和前面时域分解的顺序相反,将2个1点的频域信号变成1个2点的频域信号,再将2个2点的频域信号变成1个4点的频域信号,一直到结束。这里看下如何将2个4点的频域信号变成1个8点的频域信号。

    首先对1个4点的频域信号进行复制,这样能稀释时域信号,也对另1个4点的频域信号进行复制不过复制之前需要乘上正弦函数,这样得到的稀释时域信号时经过了平移的,然后将这两个频域信号加起来,如下图所示。之所以这么做的目的是在时域分解的时候就是用这种交织的分解方式的。
    以下是基本的运算,称为蝶形运算,它将2个1点的复数变成1个2点的复数。

    以下是FFT运算的流程图



    --------------------------------
    运算速度比较
    如果用相关方法计算DFT:

    如果用FFT方法计算DFT:



    FFT的速度还能更快
    比如使用基4或者基8,这样不是2点一计算,而是4点或者8点一计算,可以提高速度。

    2.FFT的程序代码

    1)主程序

    #include                     "f2407_c.h"

    #include                     "math.h"

    #define           N          32               //    FFT变换的点数 

    extern               void   fft(void)      

    extern               void   resave(void) 

    interrupt             void  phantom(void) 

    void                 sysinit(void)

    extern                int input[2*N]        //    输入数据的存储数组

    int                    indati[N]={0}        

    //    -----------------------------------------------------------------------------------

    //    128 FFT所需的数据

    //    采样函数: x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t)

    //    f=50Hz

    //    -----------------------------------------------------------------------------------

    /*    int indatr[N]={16394158711442512398 10276    8584   7767   8088    9557    11913   14660    17155    18724    18802    17044    13411   8197   1995   -4389   -10071   -14231  -16255   -15844   -13057   -8309   -2296   4125    10079    14819    17843    18969    18342    16394   13739    11055   8950    7848   7921    9070    10961    13110    14992    16159    16334   5479    13792   11675    9640    8197    7741    8457    10264    12815    15554    17812   18939    18429    16034    11825    6203  -156   -6405   -11662  -15165  -16394   -15165   -11662  -6405  -156    6203    11825    16034    18429    18939    17812    15554    12815   10264    8457    7741  8197    9640    11675    13792    15479    16334    16159    14992  13110    10961    9070   7921    7848    8950    11055    13739    16393    18342    18969   17843    14819    10079   4125   -2296   -8309   -13057  -15844  -16255  -14231   -10071   -4389    1995    8197   13411    17044    18802    18724    17155    14660    11913    9557   8088    7767    8584   10276    12398    14425    15871            

    }*/

    //   -----------------------------------------------------------------------------------

    //   32FFT所需的数据

    //   采样函数: x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t)

    //   f=50Hz pi=π;

    //   -----------------------------------------------------------------------------------

    /*  int indatr[N]={16384 10270    9551    18713    8192   -14222   -8304    14810   16384    7843    13102 15469    8192    12807    18418   -0156   -16384  -0156    18418    12807    8192    1546913102    7843    16383    14810  -8304  -14222    8192    18713    9551   10270 

    }*/

    int indatr[N]={0x07ff 0x07ff    0x07ff    0x07ff  0x07ff 0x07ff 0x07ff    0x07ff   0x07ff   0x07ff    0x07ff 0x07ff    0x07ff    0x07ff    0x07ff   0x07ff   0x0F801 0x0F801    0x0F801    0x0F801  0x0F801    0x0F8010x0F801    0x0F801   0x0F801    0x0F801  0x0F801  0x0F801   0x0F801    0x0F801    0x0F801   0x0F801

    }  

    //   -----------------------------------------------------------------------------------

    //    64 FFT所需的数据

    //   采样函数: x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t)

    //   f=50Hz

    //   -----------------------------------------------------------------------------------

    /*    int indatr[N]={16384    14416    10270    7762    9551    14651    18713    17034    8192   -4387  -14222-15834  -8304   4123    14810   18957    16384    11049    7843    9064   13102   16149   15469    11668    8192    8452   12807    17801   18418    11818   -0156  -11655  -16384  -11655  -0156   11818    18418    17801    12807    8452    8192    11668    15469    16149  13102   9064   7843   11049   16383    18957   14810   4123   -8304  -15834  -14222     -4387   8192   17034    18713    14651    9551   7762   10270    14416     }*/

    //   ---------------------------------------------------------------

    //    128 FFTsin cos值存储表

    //   ---------------------------------------------------------------

    /*    const int sintab[N]={0x07fff0x00x07fd90x0f9b90x07f620x0f3750x07e9d0x0ed38

                       0x07d8a0x0e7080x07c2a0x0e0e70x07a7d0x0dad80x078850x0d4e1

                       0x076420x0cf050x073b60x0c9460x070e30x0c3aa0x06dca0x0be32

                       0x06A6C0x0B8E40x066CE0x0B3C10x062F10x0AECD0x05ED60x0AA0C

                       0x05A810x0A57F0x055F40x0A12A0x051330x09D0F0x04C3F0x09932

                       0x0471C0x095940x041CD0x092370x03C560x08F1F0x036B90x08C4B

                       0x030FB0x089C00x02B1E0x0877D0x025270x085840x01F190x083D7

                       0x018F80x082770x012C70x081640x00C8B0x0809F0x006470x08029

                       0x000000x080010x0F9B90x080290x0F3750x0809F0x0ED390x08164

                       0x0E7080x082770x0E0E70x083D70x0DAD90x085840x0D4E20x0877D

                       0x0CF050x089C00x0C9470x08C4B0x0C3AA0x08F1F0x0BE330x09237

                       0x0B8E40x095940x0B3C10x099320x0AECD0x09D0F0x0AA0C0x0A12A

                       0x0A57F0x0A57F0x0A12A0x0AA0C0x09D0F0x0AECD0x099320x0B3C1

                       0x095940x0B8E40x092370x0BE330x08F1F0x0C3AA0x08C4B0x0C947

                       0x089C00x0CF050x0877D0x0D4E20x085840x0DAD90x083D70x0E0E7

                       0x082770x0E7080x081640x0ED390x0809F0x0F3750x080290x0F9B9

    }*/

    //   ---------------------------------------------------------------

    //   64 FFTsin cos值存储表

    //   ---------------------------------------------------------------                   

    /*    const int sintab[N]={  0x7FFF0x00000x7F61 0xF375 0x7D89 0xE708 0x7A7C 0xDAD90x7640 0xCF05 0x70E1 0xC3AA 0x6A6C 0xB8E4 0x62F1 0xAECD

    0x5A81 0xA57F 0x5133 0x9D0F 0x471C 0x9594  0x3C56  0x8F1F

    0x30FB 0x89C0 0x2527 0x8584 0x18F8 0x8277 0x0C8B 0x809F

    0x0000 0x8001 0xF375 0x809F 0xE708 0x8277 0xDAD9 0x8584

    0xCF05 0x89C0 0xC3AA 0x8F1F 0xB8E4 0x9594 0xAECD 0x9D0F

    0xA57F 0xA57F 0x9D0F 0xAECD 0x9594 0xB8E4 0x8F1F 0xC3AA

    0x89C0 0xCF05 0x8584 0xDAD9 0x8277 0xE708 0x809F 0xF375 }*/

    //   ---------------------------------------------------------------

    //   32 FFTsin cos值存储表

    //   ---------------------------------------------------------------

    const int sintab[N]={

                                0x7FFF0x00000x7D890xE7080x76400xCF050x6A6C0xB8E4

                                0x5A810xA57F0x471C0x95940x30FB0x89C00x18F80x8277

                                0x00000x80010xE7080x82770xCF050x89C00xB8E40x9594

                                0xA57F0xA57F0x95940xB8E40x89C00xCF050x82770xE708

    }

    extern int table128[]

    extern int nom                                                //   nom=1时, FFT 需要归一化处理

    main()

    {       int i  

             double x=0y

             nom=1                                   //   需要归一化处理

             sysinit()

             for(i=0i<=255i++)   input[i]=0        //   清除输入数据

    resave()                                //    把原始的输入数据反序排列                  

             *PCDATDIR=(*PCDATDIR&0x0FF00)|0x01

             fft( )                                 //    进行FFT运算 

             *PCDATDIR=*PCDATDIR&0x0FF00

    }

    void  interrupt  phantom(void)

    {      

    return

    }                

    void sysinit(void)

    {      

    *SCSR1=0x81FE

             *WDCR=0x0E8

             *IFR=0x0FF

             *IMR=0x0

             WSGR=0

             *MCRB=0

             *PCDATDIR=0x100

    }

    2)反序排列子程序

    .def   _resave

    //  2时间抽取的128FFT算法需要定义的各量

    //  N                   .set    128                                        

    //  2时间抽取的64FFT算法需要定义的各量

    //  N                   .set    64                 

    //  2时间抽取的32FFT算法需要定义的各量 

    N                .set    32                

            .global _resave

            .global _input

            .global _indatr

            .global _indati

    _resave

    //-------------------------------------------------------------------

    //  C语言兼容的代码部分

    // -------------------------------------------------------------------

                       POPD        *+

                       SAR           AR0*+

                       SAR           AR1*

                       LAR           AR0*+AR3

    // ------------------------------------------------------------------

    //  反序排列程序部分

    //------------------------------------------------------------------

                       LAR           AR2#_input

                       LAR           AR3#_indatr

                       LAR           AR0#N

                       LAR           AR4#(N-1)

    RESAV1   

    LACC        *+0AR2

                       SACL        *BR0+AR4

                       BANZ        RESAV1*-AR3

    //-------------------------------------------------------------------

    //  C语言兼容的程序代码部分

    //-------------------------------------------------------------------

                       MAR                   *AR1

                       SBRK        #2

                       LAR           AR0*-

                       PSHD        *

                       RET

    3 FFT应用子程序

    // -------------------------------------------------------------------------------------------------

    // 函数名:        void           fft(void)

    // 功能:实现3264128采样点的快速傅立叶变换

    // 入口条件:   

    //       _sintab                 存放FFT运算中用到的sincosin函数值

    //       _input                  存放FFT运算中用到的数据,包括实部和虚部,按二进制反序排列

    //                                   注意:由于“*BR0+”间接寻址方式对_input的地址有特殊的要求,

    //                                   所以最好将数组_input放置在一个独立的块中,如B1块。

    //       _nom                            _nom=0时,本函数将不对运算结果进行归一化。反之,将对每

    //                                   一步运算结果进行归一化处理,避免溢出,但是,它会使运算精度降低。

    //      N                       常数,参与FFT运输的点数,用户可根据需要选择,例如,需要进行128

    //                                 FFT时,请在本函数中做出如下选择:

    //       N      .set    128

    //       M      .set    7

    //       依此类推。

    //       出口条件:

    //       _input                  存放FFT的运算结果

    //       本函数可供C调用,请用户在C主程序中作以下声明:

    //       extern         void fft(void)

    //       const          int sintab[N]={...}             N1286432

    //       extern         int _input[2*N]

    //       extern         int nom

    //--------------------------------------------------------------------------------------------------

             .def   _       fft

    // 2时间抽取的128FFT算法需要定义的各量

    // N             .set    128                               // 点数

    // M            .set    7                                 //  N=2**M

    // 2时间抽取的64FFT算法需要定义的各量

    // N             .set    64                 // 点数

    // M            .set    6                  // N=2**M

    // 2时间抽取的32FFT算法需要定义的各量

    N                .set    32                // 点数

    M               .set    5                 // N=2**M

    _input         .usect  ".data0"2*N              //   输入数据      

    //              .bss   _sintabN                        //   SINCOSIN函数的存储表                                  

                       .bss   _nom1            //   _nom=1时, FFT需要归一化处理,为0时则不需要

                       .global        _fft

                       .global        _sintab

                       .global        _input

                       .global _nom

                       .text    

    _fft  

    //   --------------------------------------

    //   C语言兼容的代码部分

    //   --------------------------------------

                   POPD        *+                              //   存储返回地址ADDRESS

                   SAR           AR6*+          //   存储 AR6

                   SAR           AR7*+          //   存储 AR7

                   SAR           AR0*+          //   存储 AR0

                   SAR           AR1*             //   堆栈分布情况:ADDRESS/AR6/AR7/AR0/AR1

                                                                       //   ARP=AR1 AR1AR1

                   LAR           AR0#08h          

                   LAR           AR3*0+AR3     //   AR3FP SP=SP+size(size=frame的长度)

                                                                   //   ARP=AR3

                   LAR           AR2*                   //   AR2AR1

                   LAR           AR7#_nom               //   AR7 指向 _nom

    //   -----------------------------------------

    //   初始化一些寄存器

    //   -----------------------------------------          

                       SPLK         #(N-1)*+                         

                       SPLK         #(M-1)*+                          

                                                                          //   堆栈分布情况:ADDRESS/AR6/AR7

    //   /AR0/N/M/Y(其中Y为没有确定的量)

                                                                          //   ARP=AR3 AR2N AR3Y

                       SPLK         #1*+AR2                 //   ID=1ARP=AR2

                                                                          //   堆栈分布情况:ADDRESS/AR6/AR7/AR0/                                                                                      //   N/M/ID/Y    ARP=AR2 AR2N AR3

    //   -----------------------------------------

    //   FFT运算处理部分

    //   -----------------------------------------                                                                            

                      SETC         OVM                                         //   使能溢出模式

                       SETC         SXM                                             //   符号扩展使能

                       SPM 1                                    //   PREG寄存器的输出左移一位,

    //   自动将两个Q15相乘后化为Q15的格式

                       LACC        *+AR3

                       ADD          #1

                       SACL        *+1AR2               //   IW=2*(N+1)

                                                                               //   堆栈分布情况:ADDRESS/AR6/AR7

                                                                          //   /AR0/N/M/ID/IW/Y  

    //   ARPAR2 AR2M AR3Y

                       LAR     AR5*+                       //   AR5=MARPAR2 AR2ID

    //   AR3Y AR5=M

    LOOP3     

                       LAR AR6#_input                        //   AR6input-->Ri ARPAR2

    //   AR2ID AR3Y AR5=M AR6input 

                       LACC        *1

                       SACL    *+                                 //   ID=ID*2ARPAR2AR2IW

    //    AR3Y AR5=M AR6input

              LACC       *15

              SACH      *                                   //   IW=IW/2

              LACC       *-15AR3

              SACH      *+AR2                  //   C2=IW/2

    //   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/Y

    //   ARPAR2 AR2ID AR3Y AR5=M AR6input

                        LAR         AR0*                        //   AR0=ID

    LOOP2     

                         LAR       AR4#_sintab            //   AR4sintab

    //  ARPAR2AR0=IDAR2ID AR3Y AR4sintab AR5=M AR6input

                     LACC    *+15AR3

                     SACH    *+AR6            //   C1=ID/2=1

    //   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/Y

    //  ARPAR6 AR0=ID AR2IW AR3Y AR4sintab AR5=M AR6input

                      MAR     *0+AR4                            

    //  ARPAR4AR0=IDAR2IWAR3YAR4sintabAR5=MAR6=AR6+ID-->Rj

    LOOP1     

    LACC        #0

                       LT     *+AR6                  //   TREG=COSαlk

    MPY         *+AR4                       //   Rj* COSαlkARP=AR4AR4SINαlkAR6Ij

                        LT            *AR6

                        MPYA    *-AR3                   //   ACC=ACC+Rj*COSαlk PREG=Ij*SINαlk

                                                                           //   ARP=AR3 AR4SINαlk AR6 Rj

                        SPAC                                         //   ACC=ACC-Ij*SINαlk

                        SACH    *+AR4                         //   XT=Rj*COSαlk-Ij*SINαlk

    //   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/Y

    //   ARPAR4 AR0=ID AR2IW AR3Y AR4SINX AR5=M AR6Q.X

                     LACC        #0

                     LT              *-AR6

                     MPY                   *+AR4                       //   Rj*SINαlkARP=AR4AR4COSαlkAR6Ij

                     LT              *AR6

                     MPYA       *-AR3                       //   ACC=ACC+Rj*SINαlk PREG=Ij*COSαlk

                                                                               //   ARP=AR3 AR4COSαlk AR6Rj

                     APAC       

                     SACH        *-AR7                        //   YT=Rj*SINαlk+Ij*COSαlk

    //   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/YT

    //   ARPAR7 AR0=ID AR2IW AR3XT AR4COSX AR5=M AR6Q.X

                       LACC        *AR6

                       BCND       D2NEQ                  //   _nom不为0时,需要在运算过程中进

    //   行归一化操作

    //   ----------------------------------------

    //   不进行归一化操作程序部分

    //   ----------------------------------------

                       MAR                   *0-                                  //   AR6=AR6-ID-->Ri

                       LACC        *AR3

                       ADD                   *AR6

                       SACL        *0+AR3                     //   Ri=Ri+XT

    //   ARPAR3 AR0=ID AR2IW AR3XT AR4COSαlk AR5=M AR6Rj

                       SUB           *+1AR6

                       SACL        *+                                   //   Rj= Ri+XT -XT*2=Ri-XT AR6Ij AR3YT

    //   ARPAR6 AR0=ID AR2IW AR3YT AR4COSαlk AR5=M AR6Ij

                       MAR                   *0-                                    //   AR6Ii

                       LACC        *AR3              

                       ADD                   *-AR6

                       SACL        *0+AR3                     //   Ii= Ii +YT AR6Ij

    //   ARPAR3 AR0=ID AR2IW AR3XT AR4COSαlk AR5=M AR6Ij

                       SUB           *1AR6                                   

                       SACL        *+0AR2            //   Ij= Ii +YT -YT*2=Ii-YT

    //   STACKADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/YT

    //   ARPAR2AR0=IDAR2IWAR3XTAR4COSαlkAR5=MAR6NEXT Rj

                       B                D                    //   AR6 指向下一个Rj

    //   ---------------------------------------

    //   归一化处理程序部分

    //   ---------------------------------------

    D2              MAR                   *0-                                  //   AR6-->Ri

                       LAC           *15AR3

                       ADD                   *15AR6                                 

                       SACH        *0+AR3                      //   Ri =( Ri +XT)/2

    //   ARPAR3 AR0=ID AR2IW AR3XT AR4COSαlk AR5=M AR6Rj   

                 SUB            *+16AR6

                       SACH        *+                                    //   Rj=Ri-XT AR6Ij AR3YT

    //  ARPAR6 AR0=ID AR2IW AR3YT AR4COSαlk AR5=M AR6Ij

                       MAR                   *0-                                   //   AR6Ii

                       LACC        *15AR3

                       ADD                   *15AR6

                       SACH        *0+AR3              //   Ii=(Ii+YT)/2 AR6Ij

    //  ARPAR3 AR0=ID AR2IW AR3YT AR4COSαlk AR5=M AR6Ij

                       SUB           *-16AR6

                       SACH        *+0AR2                   //   Ij=Ii-YT

    //   STACKADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/YT

    //   ARPAR2AR0=IDAR2IWAR3XTAR4COSαlkAR5=MAR6:下一个Rj

    D               

    LAR              AR0*-AR4               //   AR0=IW

    //  ARP=AR4 AR0=IW AR2ID AR3XT AR4COSαlk AR5=MAR6:下一个Rj

                       MAR                   *0+AR2                       //   AR4=AR4+IW-->下一个COSαlk

                       LAR           AR0*                            //   AR0=ID

                       ADRK       #3                                     //   AR2C1

    //  ARP=AR2 AR0=ID AR2C1 AR3XT AR4: 下一个COSαlk AR5=M AR6Rj

                 LACC         *

                 SUB            #1

                 SACL          *-                                               //   C1=C1-1

    //   ARP=AR2 AR0=ID AR2C2 AR3XT AR4COSαlk AR5=M AR6Rj

                   BCND       LOOP4LEQ                 //   跳转至LOOP4 IF C1<0

                   MAR                   *-AR4                          //   AR2IW

    //   ARP=AR4 AR0=ID AR2IW AR3XT AR4: 下一个COSαlk AR5=M AR6Rj

                   B                LOOP1               

    LOOP4      LACC        *

                       SUB           #1

                       SACL        *-AR3

                       MAR     *-AR2                              

    //   ARP=AR2 AR0=ID AR2IW AR3C1 AR4: 下一个COSαlk AR5=M AR6Ri

                       MAR                   *-

            BCND LOOP2GT

            MAR     *AR3

            MAR            *-AR5             

    //   ARP=AR5 AR0=ID AR2IW AR3C2 AR4下一个COSαlk AR5=M AR6Ri

            BANZ LOOP3*-AR2

    //   ------------------------------------

    //   C语言兼容的代码部分

    //   ------------------------------------

                CLRC  OVM

                SPM              0          

            MAR            *AR1

            SBRK #09

            LAR             AR0*-

            LAR             AR7*-

            LAR             AR6*-

            PSHD *

            RET

  • 补充一下上个帖子中关于flash锁死的解决办法:

    在烧写过程中(clear)-->erase-->(depletion)-->program-->verify。如果在Erase的时候,芯片因为强行断电,供电不稳定导致类似于强行断电的情况,时钟不稳定,那么FLASH中的密码段有可能成为随机值或全0。

    1、确认一下是不是有程序放在FLASH的密码区(查看芯片的datasheet,比如2833x在0x33FFF8~0x33FFFF),如果是那么想办法得到.out中这里的数据,这就是密码、

    2、断电,上电,用CCS-->memory看看FLASH区是不是全0,用GEL功能中的Code Security Module-->Unlock_CSM试试能不能解锁。