Aguilera

  • 2019-10-16
  • 发表了主题帖: AD采样的FPGA程序书写 Verilog代码

      提供一段AD采样的FPGA程序 程序如下 Verilog源程序如下: //--------------------------------------------------------------------------- //--        文件名                :        Ad_Module.v //--        作者                :        ZIRCON //--        描述                :        AD模块 //---------------------------------------------------------------------------   `define AD_CLK_TIME                        10'd49        //1.1M, 909ns,909 / (1 / 50M) = 45 =0x2D `define AD_CLK_TIME_HALF        10'd24        //909ns / 2 = 454.5ns 45 / 2 = 22           module Ad_Module (                 //Input         CLK_50M,RST_N,         //Output         AD_CS,AD_CLK,AD_DATA,data_out );          //--------------------------------------------------------------------------- //--        外部端口声明 //--------------------------------------------------------------------------- input                                        CLK_50M;                                //时钟的端口,开发板用的50M晶振 input                                        RST_N;                                //复位的端口,低电平复位 input                                        AD_DATA;                                //AD数据端口 output                                AD_CS;                                //AD片选端口 output                                AD_CLK;                                //AD时钟端口,最大不超过1.1MHz output        [ 7:0]        data_out;                        //AD模数转换完成的数据输出     //--------------------------------------------------------------------------- //--        内部端口声明 //--------------------------------------------------------------------------- reg                                        AD_CS;                                //AD片选信号端口 reg                                        AD_CS_N;                                //AD_CS的下一个状态 reg                                        AD_CLK;                                //AD时钟,最大不超过1.1MHz reg                                        AD_CLK_N;                        //AD_CLK的下一个状态   reg                [ 2:0]        ad_fsm_cs;                        //状态机的当前状态 reg                [ 2:0]        ad_fsm_ns;                        //状态机的下一个状态   reg                [ 5:0]        time_cnt;                        //用于记录一个时钟所用时间的定时器 reg                [ 5:0]        time_cnt_n;                        //time_cnt的下一个状态 reg                [ 5:0]        bit_cnt;                                //用来记录时钟周期个数的计数器 reg                [ 5:0]        bit_cnt_n;                        //bit_cnt的下一个状态   reg                [ 7:0]        data_out;                        //用来保存稳定的AD数据 reg                [ 7:0]        data_out_n;                        //data_out的下一个状态 reg                [ 7:0]        ad_data_reg;                //用于保存数据的移位寄存器 reg                [ 7:0]        ad_data_reg_n;                //ad_data_reg_n的下一个状态   parameter        FSM_IDLE                        = 3'h0;        //状态机的初始状态; parameter        FSM_READY                = 3'h1;        //满足CS有效时的第一个1.4us的延时状态 parameter        FSM_DATA                        = 3'h2;        //读取8个数据状态 parameter        FSM_WAIT_CONV        = 3'h3;        //等待转换状态,等待17us; parameter        FSM_END                        = 3'h4;        //结束的状态   //--------------------------------------------------------------------------- //--        逻辑功能实现         //--------------------------------------------------------------------------- //时序电路,用来给ad_fsm_cs寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 ad_fsm_cs <= 1'b0;                                //初始化ad_fsm_cs值         else                 ad_fsm_cs <= ad_fsm_ns;                        //用来给ad_fsm_ns赋值 end   //组合电路,用来实现状态机 always @ (*) begin         case(ad_fsm_cs)                                                //判断状态机的当前状态                 FSM_IDLE:                                                                                                 //3 x 0.909us = 2.727us用于初始化延时                          if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))                                 ad_fsm_ns = FSM_READY;        //如果空闲状态完成就进入延时状态                         else                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变                 FSM_READY:                                                                                                 //2 x 0.909us = 1.818us用于延迟1.4us                         if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))                                 ad_fsm_ns = FSM_DATA;        //如果延时状态完成就进入读取数据状态                         else                                 ad_fsm_ns = ad_fsm_cs;  //否则保持原状态不变                  FSM_DATA:                                                                                                 //读取数据8位,1~8个时钟脉冲                         if((bit_cnt == 6'd8 ) && (time_cnt == `AD_CLK_TIME))                                 ad_fsm_ns = FSM_WAIT_CONV;//如果读取数据状态完成就进入等待状态                         else                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变                                 FSM_WAIT_CONV:                                                                                                 //19 x 0.909us = 17.271us用于延迟17us                         if((bit_cnt == 6'd10) && (time_cnt == `AD_CLK_TIME))                                 ad_fsm_ns = FSM_END;                //如果等待状态完成就进入读取状态                         else                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变                   FSM_END:                                                                                         ad_fsm_ns = FSM_READY;                //完成一次数据转换,进入下一次转换                 default:ad_fsm_ns = FSM_IDLE;                                         endcase end   //时序电路,用来给time_cnt寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 time_cnt <= 6'h0;                                        //初始化time_cnt值         else                 time_cnt <= time_cnt_n;                        //用来给time_cnt赋值 end   //组合电路,实现0.909us的定时计数器 always @ (*) begin         if(time_cnt == `AD_CLK_TIME)                //判断0.909us时间                 time_cnt_n = 6'h0;                                //如果到达0.909us,定时器清零         else                 time_cnt_n = time_cnt + 6'h1;        //如果未到0.909us,定时器继续加1 end   //时序电路,用来给bit_cnt寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 bit_cnt <= 6'h0;                                        //初始化bit_cnt值         else                 bit_cnt <= bit_cnt_n;                        //用来给bit_cnt赋值 end   //组合电路,用来记录时钟周期个数的计数器 always @ (*) begin         if(ad_fsm_cs != ad_fsm_ns)                        //判断状态机的当前状态                 bit_cnt_n = 6'h0;                                        //如果当前的状态不等于下一个状态,计时器就清零         else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间                 bit_cnt_n = bit_cnt + 6'h1;        //如果到达0.4545us,计数器就加1         else                 bit_cnt_n = bit_cnt;                                //否则计数器保持不变 end   //时序电路,用来给AD_CLK寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 AD_CLK <= 1'h0;                                        //初始化AD_CLK值         else                 AD_CLK <= AD_CLK_N;                                //用来给AD_CLK赋值 end   //组合电路,用来生成AD的时钟波形 always @ (*) begin         if(ad_fsm_cs != FSM_DATA)                        //判断状态机的当前状态                 AD_CLK_N = 1'h0;                                        //如果当前的状态不等于读取数据状态,AD_CLK_N就置0         else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间                 AD_CLK_N = 1'h1;                                        //如果到达0.4545us,ADC_CLK_N就置1         else if(time_cnt == `AD_CLK_TIME)//判断0.909us时间                 AD_CLK_N = 1'h0;                                        //如果到达0.909us,AD_CLK_N就置0         else                 AD_CLK_N = AD_CLK;                                //否则保持不变 end   //时序电路,用来给AD_CS寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 AD_CS <= 1'h0;                                                //初始化AD_CS值         else                 AD_CS <= AD_CS_N;                                        //用来给AD_CS赋值 end   //组合电路,用来生成AD的片选波形 always @ (*) begin         if((ad_fsm_cs == FSM_DATA) || (ad_fsm_cs == FSM_READY))//判断状态机的当前状态                 AD_CS_N = 1'h0;//如果当前的状态等于读取数据状态或等于延时1.4us状态,AD_CS_N就置0         else                 AD_CS_N = 1'h1;//如果当前的状态不等于读取数据状态或不等于延时1.4us状态,AD_CS_N就置1 end   //时序电路,用来给ad_data_reg寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 ad_data_reg <= 8'h0;                                //初始化ad_data_reg值         else                 ad_data_reg <= ad_data_reg_n;        //用来给ad_data_reg赋值 end   //组合电路,将AD线上的数据保存到移位寄存器中 always @(*) begin         if((ad_fsm_cs == FSM_DATA) && (!AD_CLK) && (AD_CLK_N))//判断每一个时钟的上升沿                 ad_data_reg_n = {ad_data_reg[6:0],AD_DATA};//将数据存入移位寄存器中,高位优先         else                 ad_data_reg_n = ad_data_reg;        //否则保持不变 end   //时序电路,用来给data_out寄存器赋值 always @ (posedge CLK_50M or negedge RST_N) begin         if(!RST_N)                                                                //判断复位                 data_out <= 8'h0;                                        //初始化data_out值         else                 data_out <= data_out_n;                        //用来给data_out赋值 end   //组合电路,将移位寄存器中的数据存入data_out中,可用于输出 always @ (*) begin         if(ad_fsm_cs == FSM_END)                        //判断复位                 data_out_n = ad_data_reg;                //初始化data_out值         else                 data_out_n = data_out;                        //用来给data_out赋值 end   endmodule

  • 发表了主题帖: 基于微机械加速度计的无键多功能电视遥控器

    1 引言        随着科技高速发展,人们日用品不断向易操作、易携带、智能化的方向发展。电视作为重要的生活用品,其遥控器易操作、无键化、智能化是目前发展趋势。随着微机械加速度计技术的日趋成熟,其微小化、低功耗、高精度、智能化、低成本的特点使电视遥控器的应用得以实现。        此设计利用单片机体积小、功能丰富、精度高及在线仿真方便快捷的特性,实现对电视机的简单方便的控制。该设计采用完全无键化的设计模型,利用加速度计准确测定控制方向。此遥控器有二维4个方向,即4个功能键。经实践分析,4个键可满足对电视机的基本操作。在正常状态下,X轴方向作音量调节,Y轴方向作频道调节。系统采用电池组供电,采用电视遥控通用编码,实用方便,适用于社会不同人群的操作方式和习惯,其简易、低功耗的特点,是未来电视遥控发展的方向。该设计的创新点:实现控制系统的无键化,用微机械加速度计的方向量及在各方向量上的大小实现遥控;电路设计独特,完全符合加速度计性能的设计特点;该产品体积小,电池供电,外观设计灵活性强,对其不同程度的改变,可适用于不同场合,不同人群;通过软件实现对加速度计的误差消除和算法测量。 2 系统结构       整个系统主要包括信号的采集、处理、发送3部分。每个模块的设计都直接影响系统功能的实现。一般加速度计输出的模拟信号比较微弱。由于系统中内部和外部干扰的影响,被测信号参杂有干扰信号,当被测信号很微弱时,就会被干扰噪声“淹没”,导致很大的数据采集误差。因此必须在放大之前对信号进行滤波。把信号放大到适当的量程内,以获得尽可能高的分辨率。另外,该模块应尽可能靠近信号源,这样信号在受环境影响之前即被放大,使信噪比得以改善。这里选用LM358 滤波放大电路。再将经放大的模拟信号传到A/D转换器中,转换成数字信号,由于单片机内部带有A/D转换功能,因此整个转换过程是在单片机内部实现的,而无需添加额外的A/D转换器。同时利用单片机分析、处理信号;然后通过射频收发模块发射信号。系统框图如图1所示。 3 硬件电路设计 无键多功能电视遥控器的硬件主要包括加速度计传感器单元,控制器单元及红外发射单元3部分。 3.1 加速度计传感器单元     加速度计传感器单元原理框图如图2所示,选用三轴的加速度计ADXL330,该器件可同时测量3个不同方向的重力加速度。该系统只采用2个输出信号,即X轴和Y轴方向。 3.2 控制器单元      图3为控制器单元原理框图,控制器的P30/AN00和P31/AN01引脚接收放大后的传感器采集信号。P60~P67和P00~P07引脚与发射器相连,发送发射码。MOD引脚外接跳线,在工作模式或下载烧写模式可选择相应电压。RST复位引脚外接按键用于系统复位。 3.3 红外发射单元 红外发射单元选用MC50462AP,其采用5 V(AVDD)供电,通过红外二极管口发射遥控编码。 4 软件设计     单片机上电复位后,首先判断输入端口是否有模拟信号输入,如果没有则重复检测、判断,如果有,则对端口信号进行循环采集。采集后在单片机中对采集的信号进行A/D转换,对转换后的数字信号进行大小标定。由于种种原因,输入的加速度信号不可能是单一方向的,因此,进行简化处理,假定输入信号始终是单一方向,若同时检测到多个方向有输入,则将比较各个输入,然后选择一个最大值作为其唯一输入。最后通过对输入进行分析,设计各个输入的处理子程序,设定其功能。 由于三轴加速度计能输出3个不同方向的加速度值,因此可以对不同的输入设定其不同的功能,每一种输入对应一种功能,并通过各自的子程序体现。图4为软件设计流程。       由于该系统使用电池供电,所以在无信号输入时,系统处于休眠状态,当有信号输入时才处于工作状态。开始或复位5 s后,若无信号输入,则进入休眠状态以减小电源消耗。       通过试验验证人为摆动遥控器的平均最小加速度为1 g,即系统所设定的标定值为1 g,加速度小于1 g,则认为是无效信号。在此系统中,不必特别地考虑对输入抖动的消除,完全可把抖动作为一次输入信号处理。信号发射完全采用通用电视机遥控的发射原理,微处理器芯片内部的振荡器与外部的振荡晶体组成高频振荡器,产生高频振荡信号。此信号送入定时信号发生器后产生正弦信号和定时脉冲信号。正弦信号送入编码调制器作为载波信号;定时脉冲信号送至指令编码器作为调制信号待发送,然后在调制器中调制后送到红外线发光二极管VD发射脉冲调制信号。 5 结束语      介绍一种基于微机械加速度计的无键遥控器的设计。该产品可利用运动姿势控制电视,操作简单方便,尤其适合行动不方便的群体。同时具有很强的扩展功能,可控制玩具车、电动玩具的姿态及控制车间内生产机床。由于微加速度计体积小,低功耗以及低成本,类似的设备具有广泛的市场。

  • 2019-10-13
  • 发表了主题帖: 让你的LED跟随MUSIC HIGH起来!

    说到点灯,可能大家再熟悉不过了,基本上是逢板必点灯啊!看那一篇篇开发板试用帖,几乎是只要开发板上有灯,那就是必须要来点一点了。正所谓:灯不在多,能亮就行。所以笔者也没准备很多个灯,除了一个电源指示灯,其他就剩一个灯可以拿来点了。那么究竟笔者会怎样来点这个灯呢?别急,且听笔者慢慢道来!   1、制作思路   所谓的点灯,那应该是在简单不过的事情了,几乎所有学习过单片机的小伙伴们写的第一个程序,那就该属点灯程序了。笔者也看到了不少有关点灯的作品,包括现在论坛的作品,和其他地方以往的一些作品,比较好的有:立方光、广州塔之类的,可谓是精彩绝伦。但是笔者可没那么多时间去研究这些,焊那么多个灯也得花不少时间。     那么这几个IO口要怎么分布呢?笔者思考再三,LED肯定是要占一个了,但是,仅仅只做一个LED是不是有点过于单调?最好是能把所有IO口都利用起来吧!于是,笔者又找到了一个无源蜂鸣器。找到了这个蜂鸣器,笔者就突然灵机一动:要不用这个蜂鸣器来唱歌吧!于是,产品雏形就出来了:会唱歌的蜂鸣器+LED。 那么蜂鸣器用来唱歌,LED又用来干嘛呢?有唱歌的,那么是不是还要有跳舞的,这样才精彩?好吧,那就让它来跳舞吧,哈哈!那么还剩下4个IO口,用来干嘛呢?笔者又翻了翻抽屉,找到了之前做实验用的315M的无线收发模块!     纳尼,当时买的接收器正好是M4的,遥控器也是4个按键,也就是说正好是4个输出口。好吧,那么就直接全用上吧!既然IO口全用上了,那么是不是该想想他们的功能呢?笔者思考再三,就给这遥控器上的4个按键(也即4路信号)分别定义为:播放、停止、单曲(不循环)、单曲循环。这样一来,是不是显得有点高大上了啊!     2、成本组成   那么接下来,我们来分析一下大概成本,由于都是现有的料,所以也不用再去买了,成本就只算了大概的实际成本: 1)单片机                        1.4元 2)洞洞板                        0.8元 2)USB头                        0.1元 4)蜂鸣器                        0.5元 4)电阻+电容+LED         0.5元 6)三极管                        0.2元 7)遥控收发器                 12元 这样一算,成本也就大概在15.5元左右了,应该是算比较低的了!   3、制作分享 产品雏形在心里构思好后,就该动手了!首先,自然是画原理图了,经过十几分钟,原理图就基本出来了!     接下来就是展现焊工的时候了,经过一个多小时的折腾,总算是把板子给焊好了,虽然有点丑,但是……能用就行了,哈哈……板子的尺寸尽可能的做到了最小,只有63mm*20mm,差不多一个U盘的大小了!       4、效果展示        

  • 发表了主题帖: 测评STM32“鸡肋”的RAM调试

            拿到野火MINI STM32开发板有一段时间了,这个开发板是上次社区“RTT开发者大会直播,深度体验RT-Thread”直播间抽奖得到的,感谢社区!          开发STM32有好几年了,每次都是毫无意外的使用FLASH调试,RAM调试一次都没有使用过,RAM调试好像显得有点“鸡肋”了,本次也是抱着仅学习和尝试的目的了解一下,以备不时之需。   RAM调试的优点: Ø  下载速度超快。在使用FLASH的时候,由于需要擦除扇区,所以需要一定的时间。但是使用RAM调试的时候,无需这个过程,所以下载速度很快 Ø  可以延长FLASH的寿命。单片机的FLASH擦写寿面最小在10K个循环,“延长寿命”这个说法是没有问题,但是实际上,没有太多的意义,10K次,假设10S烧录一次,那至少也得不吃不喝连续烧录27个小时;实际项目开发一个单片机也就烧录几十上百次就完成了开发项目,所以RAM调试意义不大。 Ø  RAM调试不会更改和破坏单片机FLASH原有的程序,某些特殊场合可能会用到。   RAM调试的缺点: Ø  程序断电、或者引脚复位,程序就丢失了。 Ø  RAM空间尺寸要比FLASH小很多,所以,RAM调试的代码尺寸有限            可能就第一条缺点,就注定了RAM调试显得有点“鸡肋”,但是作为一种技术,可以去抱着学习的心态,去了解和学习,说不定某天公司研发要求使用必须使用RAM调试呢(网上好像看到这样的公司)。                   本次测试就拿野火MINI STM32开发板吧,MCU为STM32F103RCT6,FLASH为256K,RAM为48K,在使用RAM调试的时候,由于不会用到FLASH,所以需要将48K的RAM进行分割,拿一部分空间用来代替FLASH的功能,用另一部分空间来代替RAM的功能。   这个是我从野火的例程中随便找了一个串口例程。 程序功能:上电串口打印出一串字符。然后在串口接收中断中,将串口接收到的数据通过串口发送出来。 为什么我没找LED的例程? 因为,我想顺便试试,中断是不是也能在RAM调试中很好的被使用。   程序编译完成后可以看到,整个程序需要占空的空间如下:          ROM(Flash)     size = Code + RO-data + RW-data   =4648 byte       =4.5 K          RAM               size = RW-data + ZI-data                            =1072byte        =1.05K          根据上面的数据,结合自己的经验,我决定把48K的RAM分割成40K+8K的模式,即用40K来代替FLASH的功能,用8K来空间来实现RAM的功能。   第一步,在原有的工程里面新建一个RAM的项目,并切换到RAM项目   第二步,配置RAM项目的工程参数。   这里的IROM1的起始地址就是RAM的起始地址,0x20000000尺寸大小为40K=0xA000 IRAM1的地址地址就是RAM剩下的地址,0x2000A000,尺寸大小为8K=0x200.   注意:地址是0x2000 0000,我在第一次使用的时候,把地址写成了0x2000000,少些了一个0,折腾我好几个小时。   第三步,使能中断向量表,重定义到RAM里面。   通过system_stm32f10x.c文件中的代码可以看到,使能了中断向量表重映射之后,其Vector起始地址被定义到0x2000 0000   第四步,Linker里面保持默认就可以,最好不要修改。 第五步,设置DEBUG     首先选择自己的仿真器类型,我这里使用的是JLINK 然后加载配置文件。我是将配置文件放在工程目录下              如果取消LOAD %L INCREMENTA和g, main 的注释,则Load Application ar Startup和Run to main()就可以不用打勾          另外,LOAD %L INCREMENTA  与LOAD CpuRAM\obj\output.axf INCREMENTAL 这两句是等效的,任意一句都可以,用LOAD CpuRAM\obj\output.axf INCREMENTAL 需要注意工程的axf文件的路径。建议使用LOAD %L INCREMENTA语句。   关于这句的用法,可以查看“Vision Help”     第六步,设置setting里面红色标记的,实际上对RAM调试没有影响。     在网上有的教程里说,红色部分的必须勾选,或者不能勾选。经过我实测,勾选与部勾选都可以。   同样,还有的说法是必须选择Do not Erase ,RAM的算法规则地址必须要改,编程芯片选择也必须删掉,经过我实测,同样不会有影响。          我的选择Erase Sector状态系,FLASH的内容没有变化,因为在ROM的地址,我已经设置为0x20000000 第七步,设置Utilities   Update Target before debugging 这个绝对不能勾选,另外一个可以勾选也可以不勾选。   最后一步,就是回到工程,点击DEBUG就可以,实现RAM调试。   注意,不要点击“下载”,RAM调试的时候下载是不能用的。   串口中断收发正常、GPIO也正常。到这里就可以实现RAM仿真程序了。   最后,在说说STM32的BOOT0 、BOOT1引脚的电平。            根据手册,单片机从RAM启动,需要将BOOT0、BOOT1设置为高电平。但是在实际使用过程中,BOOT0、BOOT1即使设置为高是,单片机依然不能正常的从RAM启动。通过硬件仿真,可以看打PC指针与SP指针值并没有只在RAM范围内。所以才需要DebugRAM.ini文件进行引导和加载。 通过DebugRAM.ini引导加载之后,实际上的BOOT0、BOOT1电平就显得无用了,故BOOT0、BOOT1都为0的时候,依然能够实现RAM调试仿真。

  • 2019-10-12
  • 发表了主题帖: TMS320C6678中Hyperlink的架构

    1.hyperlink需要一个参考时钟为SerDes模块服务,可以选择156.25Mhz,250Mhz,312Mhz。 2.管脚描述,serdes是数据传输,LVCMOS是边带信号用于控制,数了一下一共26根线,8*2的LVCMOS线,10根serdes线。具体功能如下图: 3.TXPM和TXFL控制serdes的TXDATA;RXPM和RXFL控制serdes的RXDATA。 4.电源管理和流控管理的四个位D3D2D1D0只有前两位D0D1是有效的,D0=1表示支持高于12.5G的Baud,D0=0表示支持12.5G和低于。D1=1表示支持4个通道,D0=0表示不支持4个通道。 5.激活通道:     激活通道,传输方通过TXPM发送一个power-up事件告知接收者。接收方通过RXPM接收该power-up事件,然后使能接收。档接收方已经完全和传送方的训练序列同步之后,接收方发送个事件回去告诉发送者现在可以使用通道来进行数据传输了。然后接收方侦测到该传输并从训练队列切换到数据接收模式。     在serdes内支持符号对齐,PLS需要使能去通知serdes符号对齐会发生。同步字包含一个comma"逗号?"以方便serdes可以轻易的完成。每一个通道都需要符号对齐,取决于其他通道的状态,相位矫正也许会在所有活动的lane中发生。这使得开发一个通道到四个通道的时候,在对齐过程中不会taken down。     流控对用户是透明的,hyperlink的接收端自动管理可用资源的传输流量,并且限制TX端的流量通过边带信号。 6.电源管理:     hyperlink根据lane power management register决定通道的电源状态,并且通过sideband signals统治相关的接收者进入相同的电源状态。     在重启阶段,serdes和所有通道一样处于掉电模式。当退出掉电模式之后,HYPERLINK模块通过sideband总线发送一条消息给远程的相关设备请求其能力。当收到应答之后,HYPERLINK自动的进入一种可操作的状态。serdes只有在PWRMGT寄存器被清零或者传送挂起的时候才会被带出复位。hyperlink模块会基于PWRMGT寄存器和outbound load来自动的改变电源模式。默认情况下,HYperlink 让传输连接空闲知道节后到从VBUS的从端口来的传输。然后hyperlink进入单一通道模式为该传输服务并且一个通道的上电处理也已经完成。hyperlink根据traffic load动态的管理他的电源模块。当一个通道跟不上数据传输的时候,hyperlink就会自动进入四个通道的模式,如果流量低于一个通道的,那就自动转到单通道模式。如果流量进一步减少,Hyperlink会自动的进入0通道模式,关闭serdes的传输,直到通道内有传输来。发送和接收都是独立控制的一遍一些应用只有一个方向的传输。     不同模式的传输是被lane power management寄存器控制的。 7.serdes配置和时钟     该模块控制hyperlink的开发速率,提供hyperlink的发送和接收以及外部设备的管脚之间的接口。文档末尾体供了配置serdes的相关例子。serdes寄存器是芯片级的,并不在hyperlin的配置寄存器空间。在操作这些寄存器之前,必须对Kick寄存器操作以允许有对寄存器操作的权限。     serdes的时候取决于hyperlink serdes PLL和发送接收的RATESCALE,速率比例因子。环路带宽?loop bandwidth。     hyperlink serdes的主要目的是由一个低频率的参考时钟(REFCLK)生成一个高频率的输出时钟。PLL输出频率由MPY决定,MPY在HYPERLINK_SERDES_CFGPLL中,计算公式如下:     PLL_OUTPUT=REFCLK*MPY     输出范围必须在1.5625GHz到3.125GHz的范围内。     为了消除抖动带来的干扰,引入了LOOP_BANDWIDTH来设置,公式如下:     PLL_BANDWIDTH = REFCLK/BWSCALE  

  • 发表了主题帖: DSPC6678的片上存储空间的分配机制

    嵌入式的设备如DSP上的栈空间是Kb级别,在函数内定义数组或申请空间都不能像linux下那样直接定义和申请,要么定义成全局的,要么指向一块划分好的空间,否则就会造成覆盖代码段等的问题。 片上有三片可读写的内存区域 L2:0x00800000-0x00880000        512Kb L3:0x0C000000-0x0C400000      4Mb DDR:0x80000000-0xFFFFFFFF  2Gb DSP的所有变量,函数,以及程序员定义的地址都保存在这三片空间上,程序员在定义变量时,若没有特殊规定,则编译器自动把变量分配到可读写空间上的任意位置,所以当程序员使用int *p = 0x00810000;这种语法的时候,很有可能会覆盖掉程序保存变量和函数的空间,导致程序运行异常,因此需要一个.cmd文件来约束,哪些地方用来给程序员自己定义变量地址用,哪些地方用来给程序为变量和函数申请内存来用。 /******************************************************************************  * Copyright (c) 2010-2011 Texas Instruments Incorporated - http://www.ti.com  *   *  Redistribution and use in source and binary forms, with or without   *  modification, are permitted provided that the following conditions   *  are met:  *  *    Redistributions of source code must retain the above copyright   *    notice, this list of conditions and the following disclaimer.  *  *    Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the   *    documentation and/or other materials provided with the     *    distribution.  *  *    Neither the name of Texas Instruments Incorporated nor the names of  *    its contributors may be used to endorse or promote products derived  *    from this software without specific prior written permission.  *  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT   *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT   *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  *   *****************************************************************************/ /*  *  Linker command file  *  */   -c -heap  0x8000 -stack 0x5000   /* Memory Map 1 - the default */ MEMORY {       L1PSRAM (RWX)  : org = 0x00E00000, len = 0x7FFF     L1DSRAM (RWX)  : org = 0x00F00000, len = 0x7FFF       L2SRAM (RWX)   : org = 0x00800000, len = 0x50000     L2SELFUSE      : org = 0x00850000, len = 0x30000     MSMCSRAM (RWX) : org = 0xc000000, len = 0x20000     DATASRAM       : org = 0xc100000, len = 0x200000    // FPGADATA       : org = 0xc300000, len = 0x20000     NOCACHE           : org = 0x50050000,    len = 30000h       DDR3DATA (RWX)  : org =0x80000000,len=0x10000000     DDR3 (RWX)     : org = 0x90000000,len = 0x10000000     DDR3_MID (RWX)     : org = 0xA0000000,len = 0x10000000 }   SECTIONS {     .csl_vect   >       L2SRAM//srio测试可以放在L2或者L3上     .text       >       L2SRAM//srio测试可以放在L2或者L3上        //代码段     GROUP (NEAR_DP)     {     .neardata                                                //已初始化的全局单变量     .rodata                                                    //带const修饰的已初始化的全局单变量     .bss                                                    //未初始化的全局单变量     } load > L2SRAM//srio测试可以放在L2     .stack      >       L2SRAM//srio测试可以放在L2            //栈     .cinit      >       L2SRAM//srio测试可以放在L2或者L3上        //程序初始化段     .cio        >       L2SRAM//srio测试可以放在L2            //printf用到的段     .const      >       L2SRAM//srio测试可以放在L2或者L3上        //带const修饰的全局多变量     .data       >       L2SRAM//srio测试可以放在L2或者L3上     .switch     >       L2SRAM//srio测试可以放在L2或者L3上        //switch表     .sysmem     >       MSMCSRAM//srio测试可以放在L2或者L3上    //堆,malloc     .far        >       L2SRAM//srio测试必须放在L2或者L3上        //未初始化的全局多变量     .testMem    >       L2SRAM//srio测试可以放在L2或者L3上     .fardata    >       L2SRAM//srio测试可以放在L2或者L3上        //已初始化的全局多变量     platform_lib >         L2SRAM//srio测试可以放在L2或者L3上     .L2  >         L2SRAM//srio测试可以放在L2或者L3上     .L3         >       MSMCSRAM     .NoCache       >   NOCACHE         //必须放在MSMCSRAM     .qmssSharedMem:          load >> MSMCSRAM     .cppiSharedMem:          load >> MSMCSRAM     .i2ceeprom:     load >> MSMCSRAM//i2ceeprom段必须放在MSMCSRAM     .emif16nandflash     load >> MSMCSRAM//emif16nandflash段必须放在MSMCSRAM     .srioSharedMem >       MSMCSRAM//srio放在msmc上的代码     .ChipIntc     >     MSMCSRAM //片级中断控制器的段     .Sharemem   >       MSMCSRAM //edma3多核测试main.c程序中的段     .timerSharedMem   >       MSMCSRAM //timer多核测试main.c程序中的段       //必须放在L2上     .srioL2Mem    >       L2SRAM//srio放在L2上的代码     .qmssL2Mem:          load >> L2SRAM//qmss放在L2上的代码     .cppiL2Mem:          load >> L2SRAM//cppi放在L2上的代码     .CoreIntcL2Mem:        load >> L2SRAM//coreintc放在L2上的代码     .edma3                load >> L2SRAM//edma3放在L2上的代码     .DDRDATA:               load>> DDR3DATA     .DDR3_MID:               load>> DDR3_MID }  MEMORY中定义的是所有内存的分配情况,SECTIONS定义的是每一块内存上定义了些什么东西。     //必须放在MSMCSRAM     .qmssSharedMem:          load >> MSMCSRAM     .cppiSharedMem:          load >> MSMCSRAM     .i2ceeprom:     load >> MSMCSRAM//i2ceeprom段必须放在MSMCSRAM     .emif16nandflash     load >> MSMCSRAM//emif16nandflash段必须放在MSMCSRAM     .srioSharedMem >       MSMCSRAM//srio放在msmc上的代码     .ChipIntc     >     MSMCSRAM //片级中断控制器的段     .Sharemem   >       MSMCSRAM //edma3多核测试main.c程序中的段     .timerSharedMem   >       MSMCSRAM //timer多核测试main.c程序中的段       //必须放在L2上     .srioL2Mem    >       L2SRAM//srio放在L2上的代码     .qmssL2Mem:          load >> L2SRAM//qmss放在L2上的代码     .cppiL2Mem:          load >> L2SRAM//cppi放在L2上的代码     .CoreIntcL2Mem:        load >> L2SRAM//coreintc放在L2上的代码     .edma3                load >> L2SRAM//edma3放在L2上的代码     .DDRDATA:               load>> DDR3DATA     .DDR3_MID:               load>> DDR3_MID 定义的是C6455库的内存分配方式,若要使用哪种库,就必须按照相应的规则去定义。  

  • 发表了主题帖: C6678多核DSP开发——hello world几个关键问题

    a)调试技巧: breakpoint可以设置断点,f8之后运行到断点处; F5单步执行,F8全部执行,这跟VS不太一样。 在debug窗口选中想要执行的内核,然后右键group cores 就可以新建一个组,组里包括若干个核,对这个组进行F8 就可以几个核一起运行。 在view菜单下可以选择观察寄存器,变量追踪什么的,方便调试。 b)关于工程文件说明: include 默认链接到了本工程需要的.h文件库,基本不用修改,特殊情况除外。 hello.c是核心代码编写文件,C语言。 CMD文件时硬件设备的地址配置文件,挺重要的,一开始就是因为这个文件没弄懂,走了好大弯路。下面介绍下这个文件。 ccxml是目标配置文件,连接硬件板卡用的。 有的时候可能会遇到gel文件,目前还没搞懂这个gel文件是什么东西,怎么用。后续再研究。 c)CMD文件编写 cmd:链接器配置文件,存放链接器的配置信息,cmd文件使开发者可以通过自己定义的存储器模块来配置系统存储器,说白点也就是cmd是用来分配ROM和RAM空间用的,告诉链接程序怎样计算地址和分配空间。 MEMORY命令:描述系统实际的硬件资源 SECTION命令:描述“段”如何定位 其中比较关键的就是MEMORY和SECTIONS两个伪指令的使用,MEMORY用来建立目标存储器的模型,SECTIONS指令就可以根据这个模型来安排各个段的位置,MEMORY指令可以定义目标系统的各种类型的存储器及容量。 把hello world里的CMD文件拷上来分析一下: -heap是堆,我这里分出3M是因为我把所有段都分配在了Share RAM(SHRAM)上,L2一共有4M。 -stack 是栈,一般都是这么大。 memory是L1、L2、SHRAM、EMIF和DDR3的地址范围和大小,一般的应用都会用DDR3,由于我的板卡还没开发DDR3,就只好都用SHRAM了。 section里的字段: .cinit 存放程序中的变量初值和常量 .const 存放程序中的字符常量、浮点常量和用const声明的常量 .switch 存放程序中switch语句的跳转地址表 .text 存放程序代码 .bss 为程序中的全局和静态变量保留存储空间 .far 为程序中用far声明的全局和静态变量保留空间 .stack 为程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递存储局部变量和保存中间结果 .sysmem 用于程序中的malloc 、calloc 、和realoc 函数动态分配存储空间 /*************************************************************************/ -c -heap  0x300000 /*3MB*/ -stack0x10000 MEMORY {     LOCAL_L2_SRAM:  o = 0x00800000 l = 0x00080000   /* 512kB LOCAL L2/SRAM */     LOCAL_L1P_SRAM: o = 0x00E00000 l =0x00008000   /* 32kB LOCAL L1P/SRAM */     LOCAL_L1D_SRAM: o = 0x00F00000 l =0x00008000   /* 32kB LOCAL L1D/SRAM */     SHRAM:         o = 0x0C000000 l = 0x00400000   /* 4MB Multicore shared Memmory */         EMIF16_CS2:     o = 0x70000000 l = 0x04000000   /* 64MB EMIF16 CS2 Data Memory */     EMIF16_CS3:     o = 0x74000000 l = 0x04000000   /* 64MB EMIF16 CS3 Data Memory */     EMIF16_CS4:     o = 0x78000000 l = 0x04000000   /* 64MB EMIF16 CS4 Data Memory */     EMIF16_CS5:     o = 0x7C000000 l = 0x04000000   /* 64MB EMIF16 CS5 Data Memory */       DDR3:          o = 0x80000000 l = 0x80000000   /* 2GB CE0 and CE1 external DDR3 SDRAM */ }   SECTIONS {     .text         >  SHRAM     .stack        >  SHRAM     .bss          >  SHRAM     .cio          >  SHRAM     .const        >  SHRAM     .data         >  SHRAM     .switch        > SHRAM     .sysmem       >  SHRAM     .far          >  SHRAM     .args          > SHRAM     .ppinfo        > SHRAM     .ppdata        > SHRAM       /* COFF sections */     .pinit        >  SHRAM     .cinit        >  SHRAM       /* EABI sections */     .binit         > SHRAM     .init_array    > SHRAM     .neardata      > SHRAM     .fardata       > SHRAM     .rodata       >  SHRAM     .c6xabi.exidx  > SHRAM     .c6xabi.extab  > SHRAM }  

  • 发表了主题帖: C6678学习——中断嵌套

    C6678的底层学习,写一些TIPS给有需要的朋友。 需求:在外部GPIO中断中,嵌套SRIO中断。 “TMS320C66x DSP CPU and Instruction Set” 有关于中断嵌套的说明(6.6.2),这些寄存器是可以直接操作的。 例如: temp_csr = CSR; temp_csr |= 1; CSR = temp_csr; 虽然我很奇怪,调用<csl_chip.h> 中 CSL_chipWriteReg和CSL_chipReadReg两个函数会报错。 需要强调的是,这些配置是在“被嵌套”的中断中操作的。在本例中,就是GPIO产生的主中断的ISR里。 另一方面,C6000编程指南(http://www.ti.com/lit/ug/spru198k/spru198k.pdf)中也有中断嵌套的介绍,但是用汇编写的。 还有,需要注意的是,除了CPU and Instruction Set 里提到的,也要对ISR 和ICR进行操作。一个可以参考的例子是: https://e2echina.ti.com/question_answer/dsp_arm/c6000_multicore/f/53/t/164843  

  • 发表了主题帖: CUBEMX配置六步方波驱动BLDC

    前言       做电机控制已有半年时间了,对于电机控制最基础的莫过于六步方波驱动有霍尔的无刷直流电机了(BLDC)。对于底层的一些配置我使用的是cubemx来完成,如果你有cubemx基础更好,没有的话也不用慌,我将把每一步的配置讲明白,让你能够转起来自己的电机。无刷电机运行的原理说到底就是高中物理课程中讲到的电磁感应定律,读者可自己去找个视频看看,这里我就不在介绍电机运行原理了。我将把更多的内容放在实际操作和程序上让你的电机转起来上。 硬件说明       下面的示意图可以看作是电机运行的最小系统,用onenote画的不好请多谅解。MCU接驱动电路有6路pwm,以免示意图太杂乱这里我只画了一路pwm。同样的驱动电路接三相桥那也是6路pwm接到mos管。我简单说下电机的运行,假设你程序上写的是Q1管和Q4管导通了,此时电机接通了电源,转子在磁场的作用下会转动一下,如果在下一个状态时,我让Q3和Q6导通了,转子就可以在惯性的作用下继续转动一下,也就是说我只要连续控制6个mos管的导通状态就可以让电机转起来了。这里需要说下启动,如果你没有写启动程序的话,你需要先自己手动拨一下转子才能让电机转起来。对于方波而言启动是比较简单的,只需要在电机正常运行前先检测一下转子的位置来发对应的pwm波,等到电机启动完成后就切换到正常运行流程即可。如果是做FOC的正弦驱动的话,启动就比较麻烦了,目前各大芯片公司用的大都是高频注入的方式来启动,关于电机启动算法在学术界以及工程界都是很难的课题,我在这就不说这些了,这不是这篇文章的重点,后面我将会写一些FOC的文章,到时再和大家讨论。 转子定位       上面我说了电机如何运转以及pwm发波的情况,现在的问题是发波的规律,要发哪一相pwm的前提是需要知道当前的转子位置,只有知道当前转子的位置发相应的pwm,导通怎么检测转子位置这是电机控制的核心问题。目前最简单的检测转子位置的方波是在转子上安装霍尔传感器,实时检测转子转一圈的位置就需要安装三个霍尔传感器,并且呈120°安装 关于霍尔信号是怎样确定转子位置的,可以参考下面的霍尔信号时序图 把霍尔信号数字化,高电平记为1,低电平记为0,可以得到在一个电角度周期内UVW(101,100,110,010,011,001)有6种状态,写成十进制就是5,4,6,2,3,1。如果你选择的起始信号与我不同的话,得到的信号也会不同,不过在一个电角度周期内最终的编号都一样。不要急,其对应发波状态我等会在下面给出。 互补PWM 至于pwm调制,我就不解释其原理了。在电机控制中首先需要理解下互补pwm。假设有pwm1和pwm2的电平状态完全相反的话,就说pwm1和pwm2是一对互补pwm。 也就是说如果上桥臂的Q1管导通,那么下桥臂的Q2管必然是关闭状态,其他几个mos管的状态同样如此。这里需要注意以下,因为实际的情况下有时候会出现上桥臂Q1管和下桥臂Q2同时导通,情况好的话mos管烧坏。因此需要引入死区的概念,通俗点说就是在pwm电平发生变化时让其延迟几个微秒再变化。cubemx里提供图形化的死区配置,至于定时器参数配置,你可以选择自己的参数,不必和图中一样。 可以看到实际产生的互补pwm还是很不错的 软件设计 说完了硬件方面的就开始说软件配置以及程序编写了。 从硬件说明中可以看出首要问题就是如何让MCU发出6路pwm。stm32f103RCT6总共有8个定时器,其中有两个高级定时器TIM1和TIM8都可以产生三路互补pwm,这里我用的是TIM1,当然你也可以用TIM8来产生pwm(实际使用时请结合自己的硬件电路来选择)。具体的cubemx配置如下图所示。 说完了三路互补pwm配置的配置,下面就开始配置HALL信号检测了,我采用的是外部中断的方式来检测霍尔信号 配置为上升沿和下降沿触发,没有上拉和下拉。 最终的配置图可以参考下面我给出的图 这里我用电位器来调速,其实就是根据电位器来改变pwm的占空比调节电机转速的,因为我的电位器与PA1口的(ADC1通道1)相连,你们根据自己的硬件电路设置即可,完成配置,生成工程文件后就开始写程序了。 首先编写ADC读取电位器程序 由于读取的数据是12位的,不能直接用来调节pwm的占空比,我现在是希望简单的线性调速,因此做个比例运算 DutyCycle = (ADC_Value * 1000 ) >>12即可 下面就是霍尔信号读取函数了 直接读取IDR寄存器的值,将其处理后即可得到霍尔信号了 无奈我的示波器只有两个通道,无法测第三相的霍尔信号了。 可以在调试界面看到霍尔信号的变化 完成了上面的任务后,我们就可以编写发波函数来启动电机了。首先要明白发什么波,依照我上面说的电机运行规律,填上楼上挖的坑,给出发波规律表 根据上面的霍尔信号发波表编写程序即可 限于篇幅,我就只给出霍尔信号为5的发波程序了,其余的读者可自行编写。 写完电机运行函数之后,在刚刚的外部中断里或者主函数里调用它,接上电机功率线和霍尔信号线。由于只有霍尔信号发生变化才会进入外部中断函数,而刚开始上电时电机的转子位置检测不到,因此你需要拨动一下转子才能转起来。 下面来看看启动的思想。我先检测一次霍尔信号,然后发相应的pwm,使电机稍微抖动一下,霍尔信号发生变化,进入中断函数,执行电机运行函数。这样的话就不用启动前人为的拨动一下了,来看看程序上怎么写。 实际上跟上面的外部中断检测霍尔信号一样。 最终结果 没怎么拧电位器,所以转的不怎么快,实际测速可以转到2000r/min。

  • 2019-10-11
  • 发表了主题帖: TMS320C6000系列DSP的CPU与外设

          该书着重介绍了TMS320C6000系列DSP的内部结构和外围设备的开发与使用,可供基于TIDSP的程序开发人员、系统设计工程师等参考,也可以作为相关专业本科生和研究生选修课程的参考书。      TMS320C6000系列DSP是TI公司推出的一种高性能的数字信号处理器。它的处理内核采用超长指令字结构,一个指令周期最多能并行执行8条指令。片内集成大容量存储器,并采用二级存储器的结构。片上集成了丰富的外围设备接口。强大的处理能力和丰富的片上资源使TMS320C6000系列DSP在处理性能上高于其他传统DSP。        本书着重介绍了TMS320C6000系列DSP的内部结构和外围设备的开发与使用,具体内容包括:CPU数据通路和控制、TMS320C620x/C670x内部程序和数据存储器、TMS320C621x/C671x/C64x二级内部存储器、直接存储器访问寄存器(DMA)控制器、DMA和CPU数据访问性能、EDMA控制器、主机接口(HPI)、扩展总线、PCI、外部存储器接口、引导模式和配置、多通道缓冲串口、定时器、中断选择器和外部中断、省电逻辑、JTAG仿真设计、通用输入/输出口(I/O)。      本书可供基于TIDSP的程序开发人员、系统设计工程师等参考,也可以作为相关专业本科生和研究生选修课程的参考书。 图书目录 第0章 引言 0.1 TMS320系列DSP概述 0.2 TMS320C6000系列DSP的应用 0.3 TMS320C6000系列DSP的特点和性能 第1章 TMS320C6000系列DSP的CPU数据通路和控制 1.1 C6000系列DSP的基本结构 1.2 CPU通用寄存器组 1.3 数据通路的功能单元 1.4 寄存器交叉通路 1.5 存储器存取通路 1.6 数据地址通路 1.7 TMS320C6000控制寄存器 1.8 TMS320C67x控制寄存器扩展 1.9 TMS320C64x控制寄存器扩展 1.10 TMS320C64x体系结构的扩展 第2章 TMS320C620x/C670x内部程序和数据存储器 2.1 程序存储器控制器 2.2 内部程序存储器 2.3 数据存储器控制器 2.4 内部数据存储器 2.5 外围总线 第3章 TMS320C621x/C671x/C64x二级内部存储器 3.1 概述 3.2 TMS320C621x/C671x/C64x高速缓存定义 3.3 TMS320C621x/C671x二级存储器 3.4 TMS320C64x二级存储器 3.5 L1P操作 3.6 L1D操作 3.7 L2操作 3.8 应用级优化 3.9 程序级优化 3.10 举例 第4章 直接存储器访问寄存器(DMA)控制器 第5章 DMA和CPU数据访问性能 第6章 EDMA控制器 第7章 主机接口(HPI) 第8章 扩展总线 第9章 PCI 第10章 外部存储器接口 第11章 引导模式和配置 第12章 多通道缓冲串口 第13章 定时器 第14章 中断选择器和外部中断 第15章 省电逻辑 第16章 JTAG仿真设计 第17章 通用输入/输出口(I/O)

  • 发表了主题帖: DSP TMS320C6000的基本特性

          TMS320C6000产品是美国TI公司于1997年推出的dsp芯片,该DSP芯片定点、浮点兼容,其中,定点系列是TMS320C62xx系列,浮点系列是TMS320C67xx系列,2000年3月,TI发布新的C64xx内核,主频为1.1GHz,处理速度9000MIPS,在图像处理和流媒体领域得到了广泛的应用。   C6000片内有8个并行的处理单元,分为相同的两组。DSP的体系结构采用超长指令字(vliw)结构,单指令字长为32位,指令包里有8条指令,总字长达到256位。执行指令的功能单元已经在编译时分配好,程序运行时通过专门的指令分配模块,可以将每个256为的指令包同时分配到8个处理单元,并有8个单元同时运行。芯片最高时钟频率为300MHz(67xx系列),且内部8个处理单元并行运行时,其最大处理能力可达到1600MIPS。   dsp tms320c6000与gel文件   什么是gel文件?gel文件能干什么?   gel全称General Extended Language,即通用扩展语言文件,gel文件中由类似C语言的代码构成,gel语言是一种解释性语言,gel文件扩展名为.gel;   gel文件用于(1)扩展CCS功能,比如菜单选项等,(2)通过gel可以访问目标板的存储器。   1. gel基本语法——类C   gel函数和gel参数不需要在DSP程序中定义。gel具有C语言的很多相似的东西:函数、return语句、if-else语句、while语句、与C一样的注释方式、#define,这些函数或语句的用法也与C中的非常类似。   GEL函数   funcName(param1 “discription” [,param2 “discription”, param3 “discription”,。。.])   {   statements;   }   gel函数中不用声明返回类型和参数类型,但函数中可以使用return语句返回;   参数使用“参数+字符串类型的描述”组成,参数不需要定义,可以是以下的任意一种:实际/仿真的DSP目标板的符号值;数字常量(表达式或常值);字符串常量。   GEL函数调用:通常可以在输入C表达式的任意地方调用GEL函数,也可以在另一个GEL函数中调用GEL函数。GEL函数无法递归调用。

  • 发表了主题帖: C66x指令集——指令集架构初探索

    定义       指令集架构(英语:Instruction Set Architecture,缩写为ISA),又称指令集或指令集体系,是计算机体系结构中与程序设计有关的部分,包含了基本数据类型,指令集,寄存器,寻址模式,存储体系,中断,异常处理以及外部I/O。指令集架构包含一系列的opcode即操作码(机器语言),以及由特定处理器执行的基本命令。(wiki定义 ) 关于指令集的工作方式,知乎上有一个回答我觉得还可以,这里引用一下: CPU的指令集存放在哪里? 其内容如下: 比如我们设计一套指令集,其中肯定有条加法指令。比如Add R1 R2 。我们可以认为这条指令的意思是计算寄存器R1中的内容和R2的和,然后把结果存到R1寄存器中。 那么经过编译后这条指令会变成二进制,比如010100010010 。这条二进制指令一共12位。明显可以分为三大部分。最前面的0101表示这是条加法指令,后面0001说的是第一个操作数是寄存器1,最后0010说的是第二个数就是寄存器2(其实实际没有这么简单的指令,至少应该区分操作数是寄存器还是直接的数据,但为了把这说的更容易理解作了简化)。我们可以通过十二根导线把这条指令输入一个CPU中。导线通电就是1,不通电就是0 。为了叙述方便我们从左到右用A0-A11给这12根导线编上号。 然后计算机会分析这条指令。步骤如下:        最开始的两根导线A0和A1,第一根有电第二根没电,就能知道这是一条运算指令(而非存储器操作或者跳转等指令)。那么指令将被送入逻辑运算单元(ALU)去进行计算。其实很简单。只要这两根线控制接下来那部分电路开关即可。 接下来的A2和A3,01表示加法,那么就走加法运算那部分电路,关闭减法等运算电路。 A4-A7将被送入寄存器电路,从中读取寄存器保存的值。送到ALU的第一个数据接口电路上。 后面的A8-A11同样被送入寄存器选择电路,接通R2寄存器,然后R2就把值送出来,放到ALU的第二个数据接口上。 ALU开始运算,把两个接口电路上的数据加起来,然后输出。 最后结果又被送回R1。      基本上简单的运算计算机就是这么操作的。他其实不知道你那些指令都是什么意思。具体的指令编程机器码后就会变成数字电路的开关信号。其中某几段会作为控制信号,控制其他部分的数据走不同的电路以执行运算。他没有一个地方保存着如何翻译这些机器码的字典,所有机器码的意义都被体现在整个电路的设计中了。 当然,从汇编到机器码这步是汇编程序翻译的。汇编程序当然知道某条指令要翻译成什么样的机器码。 所以指令集的目的就是为了实现底层操作,为每一种运算,每一种操作(如数据移动)提供相应的寄存器级别的动作,这些寄存器再和最底层的逻辑电路对应,最终完成顶层类似于"int a = 0; a = 1 + 2"的功能。  

  • 发表了主题帖: TMS320C665x]02、CCS v6.1 Full License 和谐

    [TMS320C665x]01、 CCS 与Process SDK的安装 http://blog.sina.com.cn/s/blog_7e7fa4c80102wdka.html 讲述了软件的安装, 编译是没有问题的,但是用xds200下载与调试时就出错问题, 关键CCS V6.1 Full License 和谐才可以,和谐方法如下   把license文件放在C:\ti\ccsv6\ccs_base\DebugServer\license下面 打开ccs6.1,点击Help->Code Composer Studio Licensing Information,; 观察License的状态,如果注册完成,则为Licensed;注册完成后的状态如下图所示; 如果没有注册,点击Upgrade选项,然后点击Launch License Setup…,然后点击下一步,点击Specify a License File,浏览第一步所粘贴License的文件夹,打开。到此为止,已注册完成。 使用XDS200 对TMS320C6655进行仿真

  • 发表了主题帖: TMS320C6655固定和浮点数字信号处理器

           KeyStone 多核架构为集成 RISC 和 DSP 内核与专用协处理器和 I/O 提供了一种高性能架构。KeyStone 是其同类解决方案中的首款,能够提供充裕的内部带宽,实现对所有处理内核、外设、 协处理器以及 I/O 顺畅的访问。这是通过四大硬件元素实现的:多核导航器、TeraNet、多核共享内存控制器以及 HyperLink。        多核导航器是一款基于包的创新管理器,可管理 8192 个队列。在把各种任务分配给这些队列时,多核导航器可提供硬件加速分发功能,将任务导向可用的适当硬件。这种基于数据包的片上系统 (SoC) 可使用 拥有2Tbps 带宽的 TeraNet 来传输数据包。多核共享内存控制器允许处理内核直接访问共享内存,避免占用 TeraNet 的带宽,这样数据包传输就不会受到内存访问的限制。       HyperLink 提供 40 Gbaud 芯片级互连,该互连让 SoC 能够协同工作。HyperLink 支持低协议开销与高吞吐量,是芯片间互连的理想接口。通过与多核导航器协同工作,HyperLink 可将任务透明地分发给串联器 件,而任务的执行就如同在本地资源上运行一样。 一个 (C6655) 或两个 (C6657) TMS320C66x ™ DSP 内 核子系统 (CorePacs),每个系统都拥有 850 MHz(仅 C6657),1.0 GHz 或 1.25 GHz C66x 定点/ 浮点 CPU 内核 1.25 GHz 时,定点运算速度为 40 GMAC / 内核 针对浮点 @ 1.25GHz 的 20 GFLOP / 内核 存储器 每内核 32K 字节一级程序 (L1P) 内存 每核 32K 字节一级数据 (L1D) 内存 每核 1024K 字节本地 L2 多核共享存储器控制器 (MSMC) 1024KB MSM SRAM 内存 (由 C6657 的两个 DSP C66x CorePacs 共享) MSM SRAM 与DDR3_EMIF 的内存保护单元 多核导航器 带有队列管理器的 8192 个多用途硬件队列 基于包的 DMA 支持零开销传输 硬件加速器 两个 Viterbi 协处理器 一个 Turbo 协处理器译码器 外设 4 个 SRIO2.1 线道 每通道支持 1.24/2.5/3.125/5G 波特率运行 支持直接 I/O,消息传递 支持四个 1x,两个 2x,一个 4x,和两个 1x + 一个 2x 链路配置 PCIe Gen2 单端口支持 1 或 2 个通道 每通道支持的速率高达 5 GBaud HyperLink 连接到其它支持资源可扩展性的 KeyStone 架构连接 支持高达 40 Gbaud 千兆以太网 (GbE) 子系统 一个 SGMII 端口 支持 10/100/1000 Mbps 工作速率 32 位 DDR3 接口 DDR3-1333 8GB 可寻址空间 16 位 EMIF 通用并行端口 两个通道,每个 8 位或 16 位 支持 SDR 和 DDR 传输 两个 UART 接口 两个多通道缓冲串行端口 (McBSP) I2C 接口 32 个 GPIO 引脚 SPI 接口 信号量 (Semaphore) 模块 8 个 64 位定时器 两个片上 PLL SoC 安全支持 商用温度: 0°C 至 85°C 扩展温度范围: -40°C 至 100°C 扩展低温: -55°C 至 100°C TMS320C6655/57 定点和浮点数字信号处理器 数据表 (Rev. A)

  • 2019-10-10
  • 发表了主题帖: 针对含DSP电路板的测试方法与诊断分析

          在现代雷达系统中,含DSP电路板应用很广,含DSP电路板通常是以某种DSP芯片为核心,外围配以双口RAM(DRAM)和闪存(Flash)等器件。DSP芯片大多支持IEEE1149.1标准,并且在电路板中形成了边界扫描链,支持边界扫描。本文采用边界扫描技术与传统的外部输入矢量测试方法相结合,为含DSP电路板的测试与诊断提供了可以借鉴的方法。   2.电路原理简介及总体测试思想   2.1 电路原理介绍   本文以雷达系统中某含DSP电路板为例对测试方法进行介绍,该电路以AD公司的ADSP-21160M为核心,外加DRAM、Flash、信号匹配转换器组成,Flash为DSP工作提供配置程序,4个DSP之间通过Link口进行数据交换,同时DSP的部分数据线和地址线与DRAM的数据线和地址线相连,DSP的Link口通过信号匹配转换器与外部连接器进行数据交换。该电路板在电路器件构成上使用了集成度较高的器件,芯片封装采用了PQFP132、PLCC100等多种表贴器件,器件引脚间距极小,采用探笔测试可能破坏电路工艺;并且电路上的DSP芯片不能从电路板上取下,所以采用边界扫描技术较为合理。如图1所示。      2.2 测试与诊断分析   对电路中核心器件DSP的资料分析,芯片具有JTAG测试接口,具备边界扫描测试的条件。但边界扫描测试不是基于IP内核的测试,使用边界扫描技术可以对电路测试但无法达到全面的测试与诊断,所以可以利用与传统的外部输入矢量测试方法相结合的方式实现电路的互连以及器件功能的测试,达到故障定位的目的。   2.3 测试系统组成   根据测试与诊断需求、测试工具以及电路本身的特点,设计稳压电路、JTAG测试接口转换电路以及加入一片具有边界扫描功能的芯片(FPGA)构成的电路实现了对电路测试所需的资源。   *稳压电路。稳压电路对测试系统程控电源发送过来的电压进行滤波、稳压后提供被测板的工作电压,保证被测板电源不会因为意外的原因产生突变。   *FPGA电路。该部分电路为被测板提供测试的地址和数据信号,测试时使用系统平台上的边扫控制器将被测电路板上DSP的测试链路的JTAG口与适配板上的FPGA的JTAG口构成一个测试链路,实现4个DSP之间互连测试、DSP与连接器连线测试、通过对FPGA配置程序实现FPGA与DSP间互连线测试。   *JTAG测试接口转接电路。将被测板上的DSP与测试转接板上的FPGA的JTAG接口构成一个测试通道,形成一个边界扫描测试链路。如图2所示。   3.测试与诊断流程开发   基于边界扫描技术的测试诊断流程开发主要内容包括对边扫器件链路设计、引脚映射关系设置、边界扫描控制器相关文档设置,以及测试脚本语言的开发。图3是该电路板的测试诊断流程图。      *测试链路功能测试。实现对边扫器件构成的测试链路的连接情况进行测试,以及完成边扫器件引脚输入输出功能是否正常测试,只有在测试链路测试通过后才能使用边界扫描控制器进行后续测试。   *互连测试。依据被测板电路原理图和测试转接板原理图的网表文件,通过边界扫描测试软件实现对被测电路板上的边扫器件(DSP)、测试转接板上FPGA共五个器件间两两互连线的是否出现开路、短路、虚焊等问题的测试。   *Flash测试。被测电路板上的每个Flash的控制使能信号由不同的器件进行控制,在对Flash的测试过程中需要开发针对各Flash测试与诊断的测试脚本,在测试的过程中完成对故障的分析和定位,开发的测试脚本能够定位到器件的具体引脚故障。   *DRAM测试。通过连接器发送DRAM配置程序的触发信号,FPGA产生DRAM的读写时序,对DRAM的读写功能进行测试,FPGA读写的测试结果进行判读并生成一定的测试结果数据由连接器采集至测试系统,判断该部分电路功能是否正常。   按照上述开发过程实现的测试诊断流程的故障覆盖率≥83%,故障检测率约为92%,隔离到3个器件以内的故障隔离率≥95%.   4.总结   通过在测试转接板上放置具有边界扫描功能的芯片将该芯片与被测板上的边扫芯片构成测试簇,传统的外部输入矢量测试弥补了边扫测试的不足,进而实现了较高的电路测试覆盖率。

  • 发表了主题帖: FPGA和专用DSP的原理及应用

    FIR滤波器(图1)存储n数据单元系列,每个数据单元延迟一个附加周期。通常,这些数据单元称之为分支。每个分支与系数相乘,其结果求和产生输出。某些方法并行执行所有的乘法。更一般的方法是分为N级,用累加器从一级到下一级传递结果。这些实现方法用功能资源换取速度,取N个计算级并需要n/N个乘法器。根据系数是静态还是动态以及系数值设计,有不少其他通用的设计最佳化方法。      图1 典型FIR滤波器的实现   实现方法   从图像压缩到确定数据取样的频谱成分,在不同的应用中都用FFT。实现FFT有多种方法。最通用的方法是通用Cooley-Tukey时间抽取,把FFT分解成若干更小的FFT。最简单的实现方法是用Radix-2蝶形单元(图2),其输入数据必须传递倍数。这种计算概念上是简单的;然而,图左边所有的乘和加是用复数计算的,所需要的乘和加的实数是更复杂的问题(如图右边所示)。   IIR滤滤器除引入反馈通路外,它类似于FIR滤波器。这些反馈通路使IIR滤波器的设计和分析比FIR更复杂。然而,对于相同硅面积,IIR方法可提供更强的滤波器。尽管有几种IIR结构,但是,一种通用的结构是用2阶四次方结构(图3)。   很多应用是用混频器来变换信号频率。概念上,可用单个乘法器,而在数字应用中,用复数形式表示不少优点。最一般的形式是信号表示是为I和Q分量。   DSP选择   做为这些通用功能应用,大多数DSP应用的核心是乘、加、减或累加。通用DSP芯片与通用微处理器结合能有效地实现这些功能。乘法器数量通常1“4个,而微处理器通过乘和其他功能定序通过的数据,存储中间结果在存储器或累加器。主要靠提高乘法所用的时钟速度来提高性能。典型时钟速度为几十MHz”1GHz。性能用每秒MMAC(百万乘累加)度量,典型值10“4000。   需要较佳功能必须并联组合多个DSP引擎。这种方法的主要优点是直接实现用高级编程语言(如C语言)编写的算法。   DSP定向的FPGA能在一个芯片上并行实现很多功能。通用发送、逻辑和存储器资源互连功能、执行加**能、定序和存储数据。某些基本器件仅提供乘法支持,需要用户建造其他逻辑功能。更复杂的器件提供加、减和累加功能做为DSP构建单元的一部分。FPGA通常带有几十乘法器单元,可工作在几百MHz的时钟频率。

  • 发表了主题帖: 如何使DSP数字振荡器产生移相正弦波

            产生数字式移相信号的方法有很多。传统的直接数字频率合成(DDS)移相原理是先将正弦波信号数字化,并形成一张数据表存入两片ROM芯片中,此后可通过两片。D/A转换芯片在计数器的控制下连续地循环输出该数据表,就可获得两路正弦波信号。当两片D/A转换芯片所获得的数据序列完全相同时,则转换所得到的两路正弦波信号无相位差。当两片D/A转换芯片所获得的数据序列不同时,则转换所得到的两路正弦波信号就存在着相位差。相位差的值与数据表中数据的总个数及数据地址的偏移量有关。这种处理方式的实质是将数据地址的偏移量映射为信号间的相位值。数据的偏差可以通过外部微处理器来获得相应的数字量输入,这个数值对应着正弦信号的移相角度。直接频率合成方法具有频率转换时间短、相位噪声性能好、精度高,产生的信号频率范围宽等优点,但由于需要采用地址、相位计算、访问存储器操作等环节,导致直接频率合成器结构复杂、成本高、移相分辨率低。本文利用DSP技术,通过数值迭代方法,即用DSP数字振荡器的实现原理获得两路正弦波信号。通过仿真,硬件实现,能得到设定参数的两路正弦波输出,达到了设计目的,并具有调整方便灵活、分辨率高等特点。数值迭代方法能精确计算角度的正弦值,只需较小的存储空间,选择正弦周期中的样点数、改变样点间的延迟,能产生不同频率的波形,可利用软件改变波形幅度及相位。 1 波形及移相波形发生器的DSP实现原理 利用DSP通过运算,用叠代的方法产生正弦信号,即数字振荡器。数字振荡器的单位冲击响应为sin(nωT+θ)·u(n)即系统在δ(n)的激励下,产生振荡,输出相位为θ的正弦序列,该系统的系统函数就是冲击响应的Z变换,即 当n≥3时有:y(n)=2cosωT·y(n-1)-y(n-2)。在n≥3以后,y(n)能用y(n-1)和y(n-2)算出,这是一个递归的差分方程。因此得到如下结论:只要已知系统输出正弦信号角频率ω和采样周期T就可以得到系统差分方程,系统只需每隔T秒时间计算一次差分方程,就可得到当前正弦采样序列y(n)的值。设定的y(1)、y(2)初值不同,初始相位就不同。在设计中,主程序通过键盘输入频率及相位差等数据,在初始化时依输出信号频率、采样速率及相位差等数据先计算出两路正弦信号的初始值y1(1)、y1(2)和y2(1)y2(2),然后开放定时器中断。以后每次进入定时器中断服务程序时,利用前面的y1(1)、y1(2)和y2(1)y2(2),计算出新的y1(0)和y2(0)。虽然两次计算并输出y1(0)和y2(0)有一定的延迟,但由于DSP的高速流水线运行及McBSP高速串行输出,所引起误差将很小。 2 系统硬件实现方案 基于TMS320VC5416 DSP的两路输出移相正弦波的系统结构如图1所示。该系统的中央处理单元采用美国TI(德州仪器)公司的高性能定点数字信号处理芯片TMS320VC5416,TMS 320 VC54.16是TI公司专门针对便携式设备设计的一款低功耗、高性能定点数字信号处理器,同C54系列其它处理器相比运行速度达到160MPIS,片内RAM达到128K,程序可寻址空间达到8M,为大量数据处理提供了丰富条件。特别是VC5416提供了多种片内外设资源;软件可编程等待状态产生器、可编程锁相环时钟产生器、1个16位计时器、6通道直接内存访问控制器(DMA)、3个多通道缓冲串口(McBSP)、8位增强型HPI接口等。此外,TMS320VC5416支持C和汇编语言混合编程,高效的流水线操作和灵活的寻址方式使其特别适合高速实时信号处理。由于系统有两路正弦信号输出,系统采用两路信号分时传输方式。TLC320AD50C是TI公司出品的一块将A/D和D/A转换功能集成在一起的模拟接口芯片,采用∑-△技术在低系统成本下实现了高精度的A/D和D/A转换。该芯片由一对16 b同步串行转换通道组成,在ADC之后有一个抽取滤波器,在DAC之前有一个插值滤波器。TLC320AD50C支持主从两种工作方式,并且最多支持三个从设备。利用该特点,系统将两片TLC320AD50C串联,使其中一个为主设备另一个为从设备,通过TMS320VC5416的多通道缓冲串口McBSP实现与两片TLC320AD50C间的串行通信。TMS320VC54.16控制两片TLC320AD50C以时分复用方式将数据传送给两片TLC320AD50C进行D/A转换输出。其中AD50C1的M/S接高电平,AD50C2的M/S接低电平,并且利用VC5416的XF引脚为AD50C提供主、次通信选择信号。TLC320AD50被广泛应用于音频数据采集处理中,它可以与TMS320C54xDSP的McBSP无缝串行连接进行数据采集、存储和处理。SCLK输出时钟,DIN串行输入,DOUT串行输出,FS帧同步信号输出,对应DSP的各相应引脚。MCBSP具有特点:①串口的接收,发送时钟既可由外部设备提供,又可由内部时钟发生器提供;②帧同步信号和数据时钟信号的极性可编程,内部时钟和帧信号发生器也可由软件编程控制;③串口的信号发送和接收部分既可单独运行,又可以在一起配合工作;④CPU的中断信号和DMA的同步信号使得McBSP串口可由CPU控制运行,还可脱离CPU通过DMA直接存取内存单独运行;⑤多通道选择部分使得串口具备了多通道信号的通信能力,他的多通道接收和发送能力可达128个信道;⑥数据宽度可在8b、12b、16b、20b、24b、32b中任意选择,并可对数据进行A律和U律压缩和扩展。McBSP串口包括一个数据通道和一个控制通道,数据通道完成数据的发送和接收。McBSP通过DX引脚发送数据、DR引脚接收数据。控制通道完成的任务包括内部时钟的产生、帧同步信号的产生、对这些信号的控制以及多通路的选择等。控制通道还负责产生中断信号送往CPU,产生同步事件信号通知DMA控制器。控制信息则是通过控制通道以时钟和帧同步信号的形式传送。 3 系统软件设计及CCS仿真结果 系统软件主要由BootLoader下载程序、系统初始化、键盘显示、定时中断处理等几个模块构成。系统开始上电时首先执行BootLoader程序,将目标程序从外部FLASH中调入片内RAM中执行。 系统初始化程序完成对TMS320VC5416各控制寄存器,McBSP串口控制寄存器,定时器以及TLC320AD50C相应寄存器的初始化设置。主程序及定时中断服务程序流程图如图2所示。 设定正弦波频率为2 kHz,采样频率40 kHz,移相60度的CCS仿真波形如3所示。 4 结束语        本文提出了一种基于DSP数字振荡器产生移相正弦波的设计方法。实验结果表明系统产生的波形稳定,抗干扰能力强,频率、相位和幅度调节方便,精度高,输出频率范围为20 Hz~20 kHz,相移0~360°,移相分辨率可高达0.001度。另外系统若连接高速DA转换芯片,可大大提高输出频率范围。该设计方案简单可行、新颖实用,有推广应用价值。

  • 发表了主题帖: 基于c2000的实时嵌入式数字处理系统设计剖析

    本帖最后由 Aguilera 于 2019-10-10 22:02 编辑         弹载信息处理系统是一种实时嵌入式数字处理系统,用于对弹载导引系统接收信号进行分析处理,实现对目标信号的检测、截获和跟踪以及目标信息的提取,是弹载雷达导引系统的关键组成部分。随着军事技术的发展,未来空战面临着越来越严酷的战场环境,对于弹载雷达导引系统的探测能力以及反隐身、抗干扰等性能提出了更高的要求。为此需要采用复杂处理算法,如数字波束形成、空时自适应处理技术、杂波抑制、低信噪比信号检测和识别、超分辨等,提高系统目标探测和抗干扰能力。数据处理复杂度越来越大、实时性要求越来越高,同时弹载应用环境对系统功耗、尺寸又有着严格的限制,因此需要运算速度更快、容量更大、功耗更低的数字处理平台来实现这些功能需求。基于单核DSP的信号处理实现方式难以适应大运算量实时处理的新需求,传统的DSP互联技术是将多个单核DSP用高速接口连接在一起,但是这样的系统架构会带来功耗和尺寸方面的问题。采用基于单片异构多核处理器的信号处理平台成为发展趋势,以实现高速实时并行处理平台的小型化、低功耗设计,显着提高弹载信息处理系统的信号与信息处理能力。   1 多核处理器TMS320C6678性能   单核DSP其性能通常由时钟频率来评价,然而DSP的时钟频率并不能做到直线上升,单片单核结构受限于速度极限,很难再有更大发展空间;随着应用系统复杂性持续增加,只通过提高时钟频率来增强处理性能达到了极限。单片多核的结构将成为DSP发展的主流,应用单片多核处理器,将显着提升弹载雷达信息处理系统性能,并能实现弹载雷达信息处理平台更进一步的小型化。   多核DSP是近年来针对高性能嵌入式应用而出现的一类多核微处理器(MultiCore MicroProcessor)。相比传统的单核处理器,多核处理器在提高并行处理能力的同时配置了更高的存储带宽和更灵活的存储结构。TMS320C6678是TI公司的最新型的KeyStone架构多核DSP,该DSP集成了8个DSP内核,每个内核频率可达1.25 GHz;定点运算能力为320 GMAC,浮点运算能力可达160 GFLOPS,运算能力比现在主流的DSP(如TS1 01)有大幅提高(TS101的内核时钟是300MHz,浮点运算能力为1 800 MFLOPS),充分体现并行处理的理念。每个DSP内核配置32 kb的一级局部程序缓存器、32 kb的一级局部数据缓存器和512 kb的二级局部缓存器。TMS320C6678的功能原理图如图1所示。     基于KeyStone体系架构,能够确保多核DSP的每一个内核发挥全面的处理功能,TMS320C6678除了具有多DSP内核导致的运算处理能力提高,还提供了丰富的对外通信接口以及存储单元的支持,增强了处理器对外高速数据交换的吞吐能力。Keystone多核架构为RISC和DSP内核以及专用协处理器和I/O的集成提供了一种高性能的系统结构,Keystone架构能够在处理器内核、外部设备、协处理器和I/O之间建立无阻塞数据传输,这主要基于多核导航器(MulTIcore Navigator)、TeraNet、多核共享存储区控制器(MulTIcore Shared Memory Controller,)和超链接总线(HyperLink)。超链接总线和高速输入输出接口实现DSP与外界信息传输,TeraNet总线结构(速度为2Tbps)把所有组成部分有机联系在一起,包括作为主要处理单元的多个内核以及通信协议处理器和数据信息包传输协处理器,能实现快速无冲突的内部数据传送。   多核共享存储控制器(MSMC)配有DSP内核共享的4 MBSRAM存储器,对共享存储器存取和信息包传输能够并发进行;为了实现对外部存储器快速存取,提供了速度为1 600 MHz的64位DDR3接口,寻址存储空间可达到8 GB。多核导航器配置控制8192个多用途硬件队列的队列管理器,建立基于DMA的零开销信息包传送通道,当需要并行处理的多任务被分配到队列中,多核导航器通过将任务引导到适当的可用硬件来实现任务的加速派遣。网络协处理器支持信息包传送加速和安全加速引擎,增强了与上位机的通信功能。TMS320C6678提供丰富的高速外设接口:四路串行高速IO(SRIO),每路传输速度最高可达到5 GBaud;两通道PCIe—II传输,每通道速度最高可达5 GBaud;超链接总线(HyperLink)支持与其他具有KeyStone架构的器件互连,传输速度可达到50 GBaud;16位扩展存储器接口,支持256 MBNAND Flash和16 MB NOR Flash,支持异步SRAM容量可达到1 MB;以及16个GBIO接口等,诸多高速的外部接口可以保证多通道高采样率的大量数据实时进入DSP内核进行处理。另外,TM S320C6678具备动态电源监测和SmartReflex电源管理技术,能够在低功耗和强大运算处理能力之间达到性能平衡。   综上所述,TMS320C6678处理器为弹载高速实时大容量数据处理、数据传输和复杂算法实现提供了强大的硬件平台基础。其中的Keystone架构提供了一种集成了片内各种子系统的可编程平台,该架构使用多种开创性的技术和硬件组成使得芯片内部和芯片之间的数据信息传输达到最佳化,从而保障各种DSP资源能够高效无缝发挥作用。这种体系架构的中枢是称为多核导航器的关键组成单元,它能够实现各种芯片组成之间高效的数据管理,对各内核进行管理和协调,使得DSP内核高效互联,保证多核处理器的效能得到发挥。Teranet交换网络能实现2Tbps的无阻塞信息交换,能进行快速无冲突的内部数据传送,多核共享存储控制器确保处理器内核无需通过数据传输网络就能够直接存取共享存储器和外部存储器。   2 基于多核DSP的软件设计   为了有效发挥多核DSP系统的运算处理和数据传输能力,获得多核DSP实际应用系统的最佳性能,需要进行相应的基于多核DSP的系统软件设计,软硬件的有机配合,确保多核DSP的功能和性能真正发挥作用。对于基于多核DSP的信息处理系统,尽管多核DSP提供了高性能硬件基础,在系统设计过程中,需要考虑每个内核之间的任务分配和信息传输,因此,为充分利用多核DSP的硬件优势,多核DSP系统并行软件设计是关键,多核DSP对软件设计提出新的挑战,同时也导致软件设计理念和设计方法的改变。   TMS320C6678集成了8个DSP内核,多内核之间的任务分配和系统处理算法直接影响多核系统的性能和效率。任务分配的目的就是合理配置系统资源,设法减少DSP内核间的通讯开销。均衡负载是将系统承担的任务合理地分配给各DSP内核,以提高系统吞吐量。显然,减少通讯量和均衡负载是相互矛盾的,因此,系统任务分配策略也就是最大限度地减少各子系统间的通讯量,同时均衡各子系统问的负载,以提高整个系统的性能。   为了全面挖掘多核处理器的潜力、充分利用多核处理器的优势,软件设计人员必须掌握相应的并行软件设计技术,将弹载信息处理系统任务映射到各DSP内核。任务并行是指软件中的独立任务同时执行。对于一个单核处理器,各单独任务必须共享同一个处理器;而在一个多核处理器上,各任务实质上是相互独立运行,从而导致更高效的任务执行。   为了将弹载信息处理系统映射到多核处理器,需要识别任务的并行度并相应选择最适宜的处理模式。弹载多核DSP系统的并行处理模式可采用数据流模式。数据流模式表现为分布式控制和执行,处理任务依次通过如同流水线一样的各处理阶段。每个内核使用各种算法处理一组数据,然后这些数据被传送到另一个内核做进一步处理。初始内核通常与一个输入接口相连接,          通过该接口可接收来自A/D转换器或FPGA的待处理的初始数据。调度的触发依赖于数据的可用性。由于弹载信息处理系统包含大量复杂的运算成分和信号与信息处理算法,它们互相关联且不可能在一个内核上处理完成。采用该模型需要将复杂的处理任务划分到各内核并确保系统具有高数据流动速率。系统的组成通常需要被拆分并映射到多个内核中,并确保处理数据有规则地流水传送。高速数据传输速率要求各内核之间具备适宜的存储带宽,各内核之间数据流动是规则的,并确保数据传送开销低。数据流处理模型如图2所示。该处理模型要求每个处理器内核映射一个或多个任务,而各内核之间通过消息传递实现运行同步;各内核之间的数据传送通过共享存储器或DMA方式进行。   对于多核信息处理系统,完成并行任务的辩识后,任务的映射和调度也需要精心策划。多核并行处理系统软件设计可以遵循四步处理法原则,即发现并行执行的机会,其核心是定义大量的小型任务,以便得到待解决问题的高效分解;定义任务之间的信息流动和数据传输;确定在多核架构上高效运行的任务组;以及将各任务映射分配到各内核中,确定每个任务将由哪个内核执行。为了提高多核系统软件开发效能,开展基于嵌入式实时操作系统的软件开发,在操作系统和多核软件开发工具支持下,自动识别任务的并行性并将各处理任务映射到单个内核,为多个实时任务合理分配资源,有效实现系统进程管理,方便多任务程序实时调度,确保多核DSP能够发挥最佳系统性能。   3 结束语   随着DSP技术的不断发展和应用需求的不断提高,单片多核处理器结构逐渐成为DSP发展的主流,单片多核处理器具有强大的多任务实时运算处理能力,同时具备数据搬移、通讯、资源共享和存储器管理等有利于并行任务执行的丰富硬件配置,能很好地支持多任务实时并行处理。对于小尺寸、低功耗且运算处理性能要求极高的弹载信息处理系统,多核DSP使得弹载雷达信息处理能够实时实现目标探测识别以及目标信息高分辨测量等复杂系统算法,能够带来性能/功耗比的大幅提升。采用多核DSP也成为弹载雷达信息处理系统的发展趋势。对于多核DSP应用系统,软件设计是多核DSP性能能否充分发挥的系统设计关键。对于基于多核DSP的弹载信息处理系统,运用数据流处理模式将系统处理任务划分映射到各处理器内核以实现高效实时并行处理。在嵌入式实时操作系统和多核软件开发工具支持下,开展基于多核DSP并行软件开发将成为弹载信息处理系统软件设计的新课题。

  • 发表了主题帖: 简析DSP的工作原理

    DSP有两种理解:   1)广义的理解:digital signal processing——数字信号处理;   它是利用数字信号处理系统,以数字形式对信号进行处理,最终得到符合需求的信号形式。   数字信号处理系统一般组成如下:      2)狭义的理解:digital signal processor——数字信号处理器。   它是一种特别适合于进行数字信号处理运算的微处理器,DSP为了提高数据的处理能力,其结构采用哈佛结构,与传统的冯.诺依曼结构不同的是将数据和程序的存储分开,访问总线也分开,提高了读写数据的能力。   DSP内部除了算术逻辑单元(ALU),还包括多个处理单元——辅助寄存器运算单元(ARAU),累加器(ACC),硬件乘法器(MULT),以及丰富的总线资源,它们的存在使得DSP可以拥有一些数字信号处理的特殊DSP指令,以及可以快速的访问存储以及并行操作的能力,保证数字信号处理中的实时的高速度、高精度累加即乘法等运算。   例:下图为市场某dsp芯片的结构图     该芯片将数据存储(data ram)程序存储(program flash)分离,拥有单个指令周期完成32*32位的乘法运算器,以及高性能的模数转换器,和大量的总线资源,因此适用于数字信号处理领域。

  • 2019-10-09
  • 发表了主题帖: C28x系列的28069、28377D的PWM使用经验

    脉宽调制(PWM)基本的原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。 一般工程的底层代码搭建好之后,大部分应用程序中用到的PWM功能可以用以下三个函数表示: 修改PWM占空比、周期 typedef struct{       Uint16 TBPRD7;     Uint16 TBPRD8;     Uint16 TBPRD9;     Uint16 TBPRD10;     Uint16 TBPRD11;     Uint16 TBPRD12;       Uint16 CmpA7;     Uint16 CmpA8;     Uint16 CmpA9;     Uint16 CmpA10;     Uint16 CmpA11;     Uint16 CmpA12;   }PwmData;     void PwmManage(PwmData*data) {          EPwm7Regs.TBPRD  = data->TBPRD7;     EPwm8Regs.TBPRD  = data->TBPRD8;     EPwm9Regs.TBPRD  = data->TBPRD9;     EPwm10Regs.TBPRD = data->TBPRD10;     EPwm11Regs.TBPRD = data->TBPRD11;     EPwm12Regs.TBPRD = data->TBPRD12;       EPwm7Regs.CMPA.bit.CMPA  = data->CmpA7;     EPwm8Regs.CMPA.bit.CMPA  = data->CmpA8;     EPwm9Regs.CMPA.bit.CMPA  = data->CmpA9;     EPwm10Regs.CMPA.bit.CMPA = data->CmpA10;     EPwm11Regs.CMPA.bit.CMPA = data->CmpA11;     EPwm12Regs.CMPA.bit.CMPA = data->CmpA12;   } 释放PWM void PwmEnable(void) {          EALLOW;       EPwm1Regs.TZCLR.bit.OST = 1;     EPwm2Regs.TZCLR.bit.OST = 1;     EPwm3Regs.TZCLR.bit.OST = 1;     EPwm4Regs.TZCLR.bit.OST = 1;     EPwm5Regs.TZCLR.bit.OST = 1;     EPwm6Regs.TZCLR.bit.OST = 1;     EPwm7Regs.TZCLR.bit.OST = 1;     EPwm8Regs.TZCLR.bit.OST = 1;     EPwm9Regs.TZCLR.bit.OST = 1;     EPwm10Regs.TZCLR.bit.OST = 1;     EPwm11Regs.TZCLR.bit.OST = 1;     EPwm12Regs.TZCLR.bit.OST = 1;       EDIS;        } 闭锁PWM void PwmDisable(void) {          EALLOW;       EPwm1Regs.TZFRC.bit.OST  = 1;     EPwm2Regs.TZFRC.bit.OST  = 1;     EPwm3Regs.TZFRC.bit.OST  = 1;     EPwm4Regs.TZFRC.bit.OST = 1;     EPwm5Regs.TZFRC.bit.OST = 1;     EPwm6Regs.TZFRC.bit.OST = 1;     EPwm7Regs.TZFRC.bit.OST = 1;     EPwm8Regs.TZFRC.bit.OST = 1;     EPwm9Regs.TZFRC.bit.OST = 1;     EPwm10Regs.TZFRC.bit.OST = 1;     EPwm11Regs.TZFRC.bit.OST = 1;     EPwm12Regs.TZFRC.bit.OST = 1;       EDIS;      } 上面代码中释放与闭锁PWM的功能是由软件TRIP实现的。 以上三个函数基本在两电平或者三电平逆变器上用的比较多,除此之外PWM还有很多其他功能,接下来笔者慢慢列举。 PWM启动ADC 这是一个比较常用的功能,基本上如果使用DSP的片内ADC,大部分都会用PWM触发ADC,或者外部中断启动ADC。 PWM启动ADC,主要是考虑启动ADC的周期,常规的做法启动ADC转换的周期就是PWM的周期,这种做法适用于PWM周期比较长的情况下,如果PWM周期比较短,可能需要隔好几个PWM周期,再启动一次ADC转换。     //ADC SOC     EPwm1Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group     EPwm1Regs.ETSEL.bit.SOCASEL    = 1;        // When TBCTR == 0x0000,EPWMxSOCA pulse will be                                                                                          //generated     EPwm1Regs.ETPS.bit.SOCAPRD     = 1;        // Generate pulse on 1st event PWM触发中断 一般DSP系统中的主中断,都是ADC转换完成后触发的主中断,因为大部分的应用需求,都是希望DSP进入主中断后能够读取ADCRESULT,所以采用ADC触发的中断,一点都不浪费时间。 但有人认为ADC是个不稳定的东西,他们认为ADC转换过程中有机率出现问题,这种情况下,会导致系统无法进入主中断,而产生一系列问题?所以也有人用PWM的CMPB触发的中断作为主中断,但CMPB要在ADC转换完成之后才能触发中断,,这是为了进入主中断后读取的ADCRESULT,是当前周期转换的,而不是上个周期的。     EPwm1Regs.ETSEL.bit.INTSEL = 6;        //  time-base counter equal to                                             //CMPB when the timer                                                                                                                             //is incrementin     EPwm1Regs.ETPS.bit.INTPRD  = 1;           // Generate interrupt on 1st event     EPwm1Regs.CMPB  = 1000;         PWM的TRIP模块 TRIP这个词,不好翻译,暂时还是用英文吧,笔者也没有看过特别合适的中文翻译,PWM的TRIP模块,主要功能是关系到PWM的释放与闭锁,闭锁一般是使PWM的A、B 引脚输出低电平。 然后TRIP分为硬件TRIP、软件TRIP,这两者实现的功能是相同的,只是触发TRIP事件的源头不同。硬件TRIP事件是怎么产生的,把DSP的一个GPIO设置为TRIP引脚,当该引脚的电平被拉低时,立即产生TRIP事件,此时PWM即会被闭锁。硬件TRIP闭锁PWM的速度很快,软件闭锁,可能至少需要几十us或者一个中断周期才能够闭锁PWM。 软件TRIP就是实现人为的闭锁、释放PWM功能。       EPwm1Regs.TZSEL.bit.OSHT1 = 1; // one-shit     EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;  //Force EPWMxA to a low state     EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // Force EPWMxB to a low state

统计信息

已有468人来访过

  • 芯币:5219
  • 好友:--
  • 主题:1227
  • 回复:92
  • 课时:--
  • 资源:--

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言