前言

​ 本笔记首先对DSP的特点及其选型进行了描述,然后重点记录DSP开发环境的搭建及基础工程示例,对为DSP开发新手有一定的指导作用。

1. DSP简介

1.1 主要特点

  1. 在一个指令周期内可完成一次乘法和一次加法;
  2. 程序和数据空间分开,可以同时访问指令和数据;
  3. 片内具有快速RAM,通常可通过独立的数据总线在两块中同时访问;
  4. 具有低开销或无开销循环及跳转的硬件支持;
  5. 快速的中断处理和硬件I/O支持;
  6. 具有在单周期内操作的多个硬件地址产生器;
  7. 可以并行执行多个操作;
  8. 支持流水线操作,使取指、译码和执行等操作可以重叠执行。

1.2 主要厂商

TI

  • 面向数字控制、运动控制的TMS320C2000系列;
  • 面向低功耗、手持设备、无线终端应用的TMS320C5000系列;
  • 面向高性能、多功能、复杂应用领域的TMS320C6000系列

ADI

  • 21xx系列:16位定点dsp,主要以218x和219x系列为代表,性能优异,内部RAM大,外围接口多,适合作为控制类芯片使用;
  • SigmaDSP:完全可编程的单芯片音频DSP;
  • blackfin系列:ADI最新推出的一款dsp,是高性能16位DSP信号处理能力与通用微控制器使用方便的性能结合;
  • SHARC 系列:32位浮点dsp,包括前期的2106x系列,和目前的主力21160,21161系列,提供与大内存容量结合的简单浮点算法,具有高水平的浮点性能;
  • TigerSHARC系列:从SHARC系列发展而来,比SHARC具有更高的浮点运算功能;

其他

  • Motorola:定点DSP 处理器MC56001,浮点DSP芯片MC96002;
  • Freescale(Nxp):MSC8xx系列,DSP56Fxx;

国产

  • 进芯电子:仿TI的c2000系列;

1.3 DSP性能参数

  1. 运算速度
  • MIPS:百万条指令/秒,定点DSP芯片运算速度的衡量指标。
  • MOPS:百万操作/秒,通常操作包括CPU操作外,还包括地址计算、DMA访问数据传输、I/O操作等。一般说MOPS越高意味着乘积-累加和运算速度越快。MOPS可以对DSP芯片的性能进行综合描述。
  • MFLOPS:百万次浮点操作/秒,这是衡量浮点DSP芯片的重要指标。
  • ACS:指令周期,即执行一条指令所需的时间,通常以ns(纳秒)为单位。
  • FFT/FIR执行时间:运行一个N点FFT或N点FIR程序的运算时间,该指标可以作为衡量芯片性能的综合指标。
  1. 运算精度
  • 16位、32位定点:动态范围小,需要注意定标及溢出,功耗低,成本低;
  • 32位浮点:动态范围大,编程相对简单一些,功耗高;

1.4 DSP选型其他因素

  1. 外设、特定功能需求

    如:同步/异步串口、A/D、D/A、以太网、音频处理等;
  2. 片内存储

    DSP片内存储器可用来放程序和数据;
  3. 封装、功耗

    一般定点功耗较低,当然也有低功耗版浮点dsp但其速度很低;

    QFP封装对底板要求较低,BGA封装需求多层板;

初次选型建议:

最先考虑C2000系列,如果满足需求,选型型号: TMS320F28335(支持FPU,150MHz,100元左右);

其次考虑C674X系列,如TMS320C6747(375~456-MHz,3648 MIPS and 2736 MFLOPS,100元左右);


2. DSP基础开发

从初版学习开发考虑,建议选用TI的DSP,其资源和技术支持均非常成熟。

2.1 开发环境

TI

  • 开发工具

    CCS(Code Composer Studio),提供免费版本。
  • 编程语言

    汇编语言和C语言。
  • 仿真器

    XDS100、XDS110、XDS200、XDS560等,通常使用性价比较高的XDS100即可。
  • 软件库

    c2000系列:controlSUITE、C2000Ware(新版)

    其他:有对应的sdk,如TMS320C6747,提供 PROCESSOR-SDK-C6747(包含TI-RTOS)

ADI

  • 开发工具

    VISUAL DSP++,提供90天测试版(正版2w左右,每个系列对应一个版本)。
  • 编程语言

    汇编语言和C语言。
  • 仿真器

    不同系列仿真器不同;

    一般低性能版2000元左右;
  • 软件库

    Technical Library

2.2 DSP开发环境搭建(TI)

本章搭建示例基于c2000系列,主要为裸机开发,资源有限不建议运行OS,其他系列可参考搭建。

CCS安装

经实际测试ccs版本选择应注意以下事项:

ccs版本较多,win10系统不支持ccs6以下的版本;

ccs6以上的版本去掉了软件仿真功能;

ccs9版本只支持64位系统(该版本不能移植老版本的软件仿真功能);

本文选择安装 ccs6

软件库安装

最新ccs9版本推荐使用 c2000ware

ccs9之前版本使用 controlSUITE


CCS基础工程示例

新建工程

新建一个基于TMS320F28335的工程,如下所示:

空工程组成介绍:

  • cmd文件

    由于嵌入式DSP资源比较紧张,存在内部RAM、Flash 和外部RAM与Flash,需要人工干预来进行合理的资源分配;

    链接配置文件,给出了程序空间和数据空间的设置,及编译后各程序段在程序或数据空间的具体位置。类似于IAR的 icf文件和 keil 的sct文件。

    一般ccs工程有两个cmd文件,一个对寄存器进行存储映射,一个是对Flash, Ram进行存储分配。

    上图中的 28335_RAM_lnk.cmd 定义了程序、数据等在Ram上的分配,即程序运行与ram,通常用于仿真调试,一般情况下直接用TI给的,不需要做修改即可满足调试用。

    当程序需要下载固化时,选择 F28335.cmd。

    DSP2833x_Headers_nonBIOS.cmd 这个文件就是寄存器的存储映射,当工程实际操作硬件时需要添加到工程中。

  • targetConfigs

    仿真器的配置,直接双击文件选择使用的仿真器和对应芯片型号即可,后面讲述怎么添加软件仿真器功能。

工程添加软件库

已安装好 controlSUITE。

设备基础软件库:D:\ti\controlSUITE\device_support\f2833x\v142;

  • DSP2833x_common 文件夹:存放了DSP2833x 开发所需的外设、内核、DSP运算库、CMD 等文件。
  • DSP2833x_headers 文件夹:存放了DSP2833x 开发所需的外设头文件、带和不带BIOS CMD 等文件。

其他的应用库到时按需添加。


下面我们移植官方软件库实现简单的GPIO控制功能。

在工程目录下面 DSP2833x_Libraries 文件夹,用于存放从controlSUITE中拷贝出来的库文件。

将 DSP2833x_common 和 DSP2833x_headers 拷贝到 DSP2833x_Libraries目录中。

在工程中新建 APP(用户应用驱动),User(用于程序),Libraries(官方库),cmd等文件夹

最小工程所需文件按下图所示添加到工程中

工程头文件路径包含

GPIO反转程序编写

#include"DSP2833x_Device.h"		//芯片型号、外设使能相关宏定义
#include"DSP2833x_Examples.h" // /**
* @brief LED使用GPIO外设初始化
*/
void LED_Init(void)
{
EALLOW; //关闭写保护
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // 开启GPIO时钟 //LED1端口配置
GpioCtrlRegs.GPCMUX1.bit.GPIO68=0; //设置为通用GPIO功能
GpioCtrlRegs.GPCDIR.bit.GPIO68=1; //设置GPIO方向为输出
GpioCtrlRegs.GPCPUD.bit.GPIO68=0; //使能GPIO上拉电阻 GpioDataRegs.GPCSET.bit.GPIO68=1; //设置GPIO输出高电平 EDIS; //开启写保护
} /*
* @brief 主程序
*/
void main(void)
{
InitSysCtrl(); //系统时钟初始化,默认已开启F28335所有外设时钟
LED_Init(); while(1)
{
GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;//设置GPIO输出翻转信号
DELAY_US(1000);
} }

编译没有错误,基础工程搭建成功。


CCS6添加软件仿真功能

本方法适用于从 ccs6-ccs8.

1.下载仿真功能文件

链接: https://pan.baidu.com/s/1eZT7SGoGIRRsxPYCOLz3Xw 提取码: z94n

2.拷贝文件到ccs指定位置

找到CCS安装路径,将网盘中的simulator文件夹复制到CCS安装路径中的ccs_base文件夹内;

将网盘中的configurations文件夹复制到ccs_base\common\targetdb\文件夹下;

将网盘中的tisim_connection.xml复制到ccs_base\common\targetdb\connections\文件夹下;

将网盘中的devicer文件夹中的内容复制到安装路径ccs_base\common\targetdb\drivers\文件夹下;

重新打开ccs,即可为工程配置软件仿真如下:

接下来工程就支持软件仿真了,当然涉及到外设相关操作时会出错(比如ADC采集)。

2.3 DSP运算仿真实验

专业术语

功能术语

  • FPU:Float Point Unit,浮点运算单元;
  • FixedPoint:定点;
  • VCU:Viterbi and complex unit,用来执行高效 Viterbi、复杂算术运算,16 位快速傅里叶变换 (FFT) 和 CRC 算法的加速器;
  • CLA: 控制律加速器,把一些与控制系统性能息息相关的代码放到CLA中独立运行,不占用CPU时间;

库术语

  • RTS:实时运行库,DSP编程开发,则RTS库提供C/C++代码的运行环境,不同功能可能需要选择器对应的rts库;
  • SGEN:信号产生库;

数学术语

  • DFT:离散傅里叶变换;
  • FFT:快速傅里叶变换,是离散傅立叶变换的快速算法;
  • CFFT:对复数进行fft变换;
  • RFFT:对实序列进行fft变换;
  • FIR滤波器:Finite Impulse Response 有限脉冲响应滤波器;
  • IIR滤波器:无限冲激响应滤波器;

正弦函数仿真显示

测试代码如下

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "math.h" #define PI 3.1415926 //定义圆周率
#define Fs 1000 //定义采样频率 Hz
#define F1 100 //信号频率 Hz
#define F2 20
#define Sample_points 1024 //采样点数 float signal1[Sample_points];
float signal2[Sample_points]; int main(void)
{
int i;
float t; for(i=0;i<Sample_points;i++)
{
t = i*1.0/Fs;
signal1[i] = sin(2*PI*F1*t);
signal2[i] = sin(2*PI*F2*t);
} while(1);
}

很简单的一段代码,大致意思就是生成了两个不同频率的正弦信号,分别保存在了数组signal1和signal2中。

下面我们通过软件仿真功能将代码运行起来,同时同步graph工具图形化显示函数计算数据。

Graph设置如下:

运行程序,显示效果如下

接着我们看其傅里叶变换,Graph提供直接生成fft功能,点击菜单栏Tools->Graph->FFT Magnitude,如图所示:

正玄函数fft变换显示如下:

DSP函数库实现RFFT

这一节将需要进行稍微复杂一点的操作,涉及到变量存储的分配及cmd文件修改,FFT计算原理,函数库及其运行支持库的设置,CFFT相关库函数等知识点。

#pragma DATA_SECTION

利用CCS进行DSP编程时,如果不指定变量的存储位置,那么编译器会自动给变量分配存储位置。但是,有些时候,需要将某个变量存放到某个特定的位置,这个时候就可以利用#pragma DATA_SECTION指令了。

如进行CFFT和ICFFT都要求输入的数组格式对齐,即变量存储的起始地址为2xFFTsize*sizeof(float),例如256点的FFT变换,则变量的起始地址必须是1024的倍数,格式对齐的方式利用变量定义的方式进行。

如:

#pragma DATA_SECTION(RFFTin1Buff, "RFFTdata1");
float32 RFFTin1Buff[RFFT_SIZE];

定义 RFFTin1Buff 数组到 RFFTdata1的RAM段;

RFFTdata1再cmd文件中进行RAM分配,后面实例代码中进行说明。

#pragma CODE_SECTION

利用#pragma CODE_SECTION指令可以将程序从Flash搬到RAM中运行,从而提高程序执行速率。

这个部分后面涉及程序优化时再进行详细描述。

RFFT工程实例

1.拷贝dsp FPU运算库到工作区间,便于工程引用;

2.给工程添加dsp FPU运算库,从controlSUITE拷贝;

3.FPU库头文件路径引用及编译器相关设置

选择fpu运行库

FPU头文件路径添加

示例程序:

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "math.h"
#include "float.h"
#include "FPU.h" //dsp 浮点运算库 #define RFFT_STAGES 8 //RFFT运算阶数
#define RFFT_SIZE (1 << RFFT_STAGES) #pragma DATA_SECTION(RFFTin1Buff,"RFFTdata1"); //Buffer alignment for the input array,
float32 RFFTin1Buff[RFFT_SIZE]; //RFFT_f32u(optional), RFFT_f32(required)
//Output of FFT overwrites input if
//RFFT_STAGES is ODD
#pragma DATA_SECTION(RFFToutBuff,"RFFTdata2");
float32 RFFToutBuff[RFFT_SIZE]; //Output of FFT here if RFFT_STAGES is EVEN #pragma DATA_SECTION(RFFTmagBuff,"RFFTdata3");
float32 RFFTmagBuff[RFFT_SIZE/2+1]; //Additional Buffer used in Magnitude calc #pragma DATA_SECTION(RFFTF32Coef,"RFFTdata4");
float32 RFFTF32Coef[RFFT_SIZE]; //Twiddle buffer float RadStep = 0.1963495408494f; // Step to generate test bench waveform
float Rad = 0.0f; RFFT_F32_STRUCT rfft; void main(void)
{
Uint16 i; // InitSysCtrl(); //没有硬件支撑时,予以注销
DINT;
// InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
// InitPieVectTable();
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM // 清空输入缓存
for(i=0; i < RFFT_SIZE; i++)
{
RFFTin1Buff[i] = 0.0f;
} // 测试样例波形
Rad = 0.0f;
for(i=0; i < RFFT_SIZE; i++)
{
RFFTin1Buff[i] = sin(Rad) + cos(Rad*2.3567); // 实部输入信号
Rad = Rad + RadStep;
} rfft.FFTSize = RFFT_SIZE; // FFT变换的长度,FFTSize=2^stage
rfft.FFTStages = RFFT_STAGES; // 傅里叶变换的阶数
rfft.InBuf = &RFFTin1Buff[0]; // 输入数组
rfft.OutBuf = &RFFToutBuff[0]; // 输出数组
rfft.CosSinBuf = &RFFTF32Coef[0]; // 转化因子数组
rfft.MagBuf = &RFFTmagBuff[0]; // RFFT_f32_sincostable(&rfft); // 计算傅里叶变换的转化因子 Calculate twiddle factor for (i=0; i < RFFT_SIZE; i++)
{
RFFToutBuff[i] = 0; //Clean up output buffer
} for (i=0; i < RFFT_SIZE/2; i++)
{
RFFTmagBuff[i] = 0; //Clean up magnitude buffer
} RFFT_f32(&rfft); //实数傅里叶变换 RFFT_f32_mag(&rfft); //计算幅值 Calculate magnitude for(;;); } //End of main

上面示例程序中使用 #pragma DATA_SECTION 定义了一些数组到RAM段,这些RAM段须在cmd文件中定义分配。

设置仿真器为软件仿真器,编译程序没有错误,然后运行。

设置Graph及数据波形显示如下:

样例输入波形:

RFFT变换之后的波形:

2.4 DSP常用外设

待续......

3. DSP进阶开发

本章开发基于TMS320C6748,运行TI-RTOS.

3.1 术语介绍

  • RTSC:Real-Time Software Component,实时软件组件。RTSC是一个基于C的编程模型,用于开发创建或实施嵌入式平台实时软件组件。
  • XDC:eXpress DSP Components,是一个为嵌入式实时系统提供可重用组件(称作:包)的标准。
  • XDCtools:包含使用RTSC的工具和运行时组件,提供了TI-RTOS及其组件(包括SYS/BIOS)需要的底层核心工具。 其功能如同Linux开发中发编译工具链。

总体来说就是TI提供XDC标准的SDK(里面包含如函数库、BIOS、DSP库等),通过XDCtools进行编译,整体以包的形式操作,而无需添加c文件到工程中。

理解CCS的这个工程框架,有利于工程的搭建。


3.2 C6748工程搭建

工程环境

CCS8.3.0

ti-processor-sdk-rtos-omapl138-lcdk-05.03.00.07

这个组合经测试正常,因为使用TI的sdk需要考虑到 ccs、XDCtools、及sdk三者的版本匹配问题,否则程序无法正确编译。

很遗憾的是首先老版本软件仿真器不支持C6748芯片,CCS8.3更是运行软件仿真器出错,如需深入调试还是需要硬件支持来调试功能。

工程创建

  1. CCS添加sdk包

    Window-->Preferences-->Code Composer Studio-->Products

    点击Add,添加我们安装的sdk软件包



我们会看到下面会出现我们芯片所需要的软件包,点击Apply,然后ccs会提示安装sdk里面包含的包,安装完成后ccs重启。

  1. 新建SYS/BIOS工程

    File-->New-->CCS Project

选择工程需要的组件

这样一个基础的RTOS工程就创建完成,程序编译正常。

DSP开发笔记一的更多相关文章

  1. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  2. [开发笔记]-未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService...匹配的导出【转载自:酷小孩】

    原文地址:http://www.cnblogs.com/babycool/p/3199158.html 今天打算用VisualStudio2012做一个js效果页面测试的时候,打开VS2012新建项目 ...

  3. EasyUI 开发笔记(二)

    接上篇 :EasyUI 开发笔记(一)  (http://www.cnblogs.com/yiayi/p/3485258.html) 这期就简单介绍下, easyui 的 list 展示, 在easy ...

  4. EasyUI 开发笔记(一)

    由于某些原因,在公司做的后台需要改成类似于Ext.js 形式的后台,主要看好其中的 框架布局,以及tab开页面和弹出式内部窗体. 后来看看,改成EasyUI,较Ext.js 库小很多,也便于公司的初级 ...

  5. [Openwrt 项目开发笔记]:Openwrt平台搭建(一)

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 最近开始着手进行Openwrt平台的物联网网关设 ...

  6. Android移动APP开发笔记——Cordova(PhoneGap)通过CordovaPlugin插件调用 Activity 实例

    引言 Cordova(PhoneGap)采用的是HTML5+JavaScript混合模式来开发移动手机APP,因此当页面需要获取手机内部某些信息时(例如:联系人信息,坐标定位,短信等),程序就需要调用 ...

  7. Android移动APP开发笔记——最新版Cordova 5.3.1(PhoneGap)搭建开发环境

    引言 简单介绍一下Cordova的来历,Cordova的前身叫PhoneGap,自被Adobe收购后交由Apache管理,并将其核心功能开源改名为Cordova.它能让你使用HTML5轻松调用本地AP ...

  8. 开发笔记:基于EntityFramework.Extended用EF实现指定字段的更新

    今天在将一个项目中使用存储过程的遗留代码迁移至新的架构时,遇到了一个问题——如何用EF实现数据库中指定字段的更新(根据UserId更新Users表中的FaceUrl与AvatarUrl字段)? 原先调 ...

  9. Lucene/Solr搜索引擎开发笔记 - 第1章 Solr安装与部署(Jetty篇)

    一.为何开博客写<Lucene/Solr搜索引擎开发笔记> 本人毕业于2011年,2011-2014的三年时间里,在深圳前50强企业工作,从事工业控制领域的机器视觉方向,主要使用语言为C/ ...

随机推荐

  1. Android技术分享| 实现视频连麦直播

    视频连麦产品端核心步骤分析 游客申请连麦/取消申请 主播同意/拒绝申请 音视频发布取消 支持很多观众观看 支持多人连麦 低延时 IM 弹幕 视频连麦技术端调研 emmm,大致可以分为视频采集.编码,传 ...

  2. 2021陕西省大学生网络安全技能大赛 Web ez_checkin

    web ez_checkin 进去看了一会,啥也没找到,直接上dirsearch 扫到一个index.php~,打开看一看,是php审计 <?php error_reporting(0); in ...

  3. 比POSTMAN更好用!在国产接口调试工具APIPOST中使用Mock

    APIPOST可以让你在没有后端程序的情况下能真实地返回接口数据,你可以用APIPOST实现项目初期纯前端的效果演示,也可以用APIPOST实现开发中的数据模拟从而实现前后端分离.在使用APIPOST ...

  4. QT-可拖拽可编辑的多控件ListView

    目标 结合前面的2篇文章, 继续升级QML版本的ListView: 又要拖拽, 又要可编辑, 还得支持多个控件. 循序渐进 本文基于前一篇的基础: Qt-可编辑的ListView 要循序渐进的学习. ...

  5. Netty 源码分析系列(二)Netty 架构设计

    前言 上一篇文章,我们对 Netty做了一个基本的概述,知道什么是Netty以及Netty的简单应用. Netty 源码分析系列(一)Netty 概述 本篇文章我们就来说说Netty的架构设计,解密高 ...

  6. 从零开始学习JAVA(入门基础)

    目录 博主从零开始学习JAVA(入门基础) 1.搭建JAVA开发环境 卸载JDK(未安装的请忽略) 安装JDK 2.编程语言中,何为编译型与解释型 编译型 解释型 3.第一个JAVA应用程序 4.JA ...

  7. fiddler抓https包教程

    第一步: 安装fiddler 第二步: 下载fiddler证书生成器 第三步: 进入fiddler导出证书 第四步: 打开浏览器导入证书 第一步:安装fiddler  安装方法各位随意,但需保证是最新 ...

  8. Android 已发行多年,移动 App 已经趋近饱和,那么 Android 开发还会有那么吃香吗?

    一.关于Android的前景 不断地也听见很多人在谈做Android是否还有前途.Android研发在走下坡路了.Android的工作太难找了.Android是不是已经凉了...... 对于这些其实我 ...

  9. vue 源码详解(二): 组件生命周期初始化、事件系统初始化

    vue 源码详解(二): 组件生命周期初始化.事件系统初始化 上一篇文章 生成 Vue 实例前的准备工作 讲解了实例化前的准备工作, 接下来我们继续看, 我们调用 new Vue() 的时候, 其内部 ...

  10. Docker小白到实战之开篇概述

    前言 "不对啊,在我这运行很正常啊",这句话小伙伴们在前几年应该听得很多:每次一到安装.部署时总有一堆问题,毕竟操作系统版本.软件环境.硬件资源.网络等因素在作怪,此时难免会导致开 ...