用C语言开发DSP系统的全过程
一个简单的dspC语言例子
一个简单的dsp C语言例子开发平台: CCS集成开发环境通过这个简单的例子, 可以大致了解用C语言开发dsp程序的原理。
程序要求: 用C语言编写产生正弦调幅波信号的源程序;正弦调幅波的公式在离散域中的表示:y(n) = (1 + M*sin(2 * PI * fb / fs * n)) * sin(2 * PI * fa / fs * n);编写文件1.sin_am.c#include<stdio.h>#include<math.h>#define TRUE 1#define pi 3.1415926536int y[500],i;float M;void main(){puts("amplitude modulation sinewave example started.\n");M = 50;for(i = 0; i < 500; i++)y[i]= 0;while(TRUE){for(i = 0; i < 500; i++)y[i]=(int)((1 + M / 100 * sin(i * 2 * pi * 20 / 4000))* sin(i * 2 * pi * 200 / 4000)* 16384);puts("program end");}}2.sin_am_v.asm (reset vector file).title "sin_am_v.asm".sect ".vectors".ref _c_int00RESET:B _c_int00.end..3.sin_am.cmdsin_am.objsin_am_v.obj-m sin_am.map-o sin_am.outMEMORY{PAGE 0:EPROG: origin = 0x1400, len = 0x7c00 VECT: origin = 0xff80, len = 0x80PAGE 1:USERREGS: origin = 0x60, len = 0x1c IDATA: origin = 0x80, len = 0x3000 }SECTIONS{.vectors:>VECT PAGE 0.text:>EPROG PAGE 0.cinit:>EPROG PAGE 0.bss:>IDATA PAGE 1.const:>IDATA PAGE 1.switch:>IDATA PAGE 1.system:>IDATA PAGE 1.stack:>IDATA PAGE 1}"*.cmd"文件说明:链接命令文件是实现对段的存储空间位置的定位, C语言程序中常用已初始化和未初始化段如下:已初始化段包括:.init 存放C程序中的变量的初值和常量, 放在ROM和RAM 中均可, 一般属于PAGE 0.const 存放C程序中的字符常量、浮点常量和用const声明的常量, 放在ROM和RAM中均可, 一般属于PAGE 1.text 存放C程序代码, 放在ROM和RAM中均可, 一般属于PAGE 0.switch 存放C程序中的语句的跳针表, 放在ROM和RAM中均可, 一般属于PAGE 0未初始化段包括:.bss 为C程序中的全局和静态变量保留存储空间, 一般存放于RAM中, 属于PAGE 1.stack 为C程序系统堆栈保留存储空间, 用于保存返回地址、函数间的参数传递、存储局部变量和保存中间结果, 一般存放于RAM中, 属于PAGE 1.sysmem 用于C程序中malloc、calloc和realloc函数动态分配存储空间, 一般存放于RAM中, 属于PAGE 14.vary_M.gelmenuitem "Myfunctions"slider vary_M(0, 100, 10, 1, Amount_of_modulation){M = Amount_of_modulation;}该文件用于调试的时候可随意改变变量M的值, 该文件通过file->load GEL File添加到工程中, 调试的时候可选择GEL->My Functions->vary_M来打开vary_M滑动条组件。
轻松学会DSP——第5章-C程序编写和编译
C/C++系统堆栈.stack
.stack不同于DSP汇编指令定义的堆栈。DSP汇编程序 中要将堆栈指针SP指向一块RAM,用于保存中断、调 用时的返回地址,存放PUSH指令的压栈内容。
.stack定义的系统堆栈实现的功能是保护函数的返回 地址,分配局部变量,在调用函数时用于传递参数, 保护临时结果。
LNK500时使用的-c和-cr是对C语言中常量 (放在.cinit段中)的处理不同。-c(ROM 模式)表示在运行时处理,由boot.asm完成, 数据空间具有一个初始化表;而-cr则在装入 时处理,由load或者bootloader完成,数 据空间没有初始化表。如果是汇编文件进行 链接,这个参数不加。
6、汇编文件中使用C文件变量
C文件中该变量要在MAIN()函数外定义为 全局变量;
汇编中需要把该变量声明为全局标号; 汇编文件中使用绝对地址寻址方式
*(_var_name)方式访问,var_name为变 量名,同时要有“_”前缀。
三、运行环境及C编译工具
1、运行环境
C54x将存储器处理为程序存储器和数据存 储器两个线性块。程序存储器包含可执行 代码;数据存储器主要包含外部变量、静 态变量和系统堆栈。编译器的任务是产生 可重定位的代码,允许链接器将代码和数 据定位进合适的存储空间。C编译器对C语 言编译后除了生成3个基本段, 即.text、.data、.bss外,还生 成.cinit、.const、.stack、.sysmem段。
.stack定义的段大小(堆栈大小)可用链接器选项-
stack size设定,链接器还产生一个全局符号_
_STACK_SIZE,并赋给它等于堆栈长度的值,以字为 单位,缺省值为1K。
初始化过程
DSP实验编写一个以C 语言为基础的DSP 程序
编写一个以C 语言为基础的DSP 程序
实验结果:
通过实验可以发现,修改cmd文件可以安排程序和数据在DSP内存资源中的分配和位置;map文件中描述了程序和数据所占用的实际尺寸和地址。
C语言编制的程序,在经过编译器编译后,需要连接若干C 标准程序辅助运行。
以下是运行流程:
1.程序入口为_c_int00,执行标准C库中的程序,负责初始化C环境、申请堆栈、初始化有初始值的变量
2.程序最终转到用户编制的主函数运行。
3.程序在主函数中的无限循环中持续运行。
编写一个汇编和C 混合的DSP 程序。
dsp实验二-编写一个以C语言为基础的DSP程序
实验二:编写一个以C语言为基础的DSP程序一、实验目的1.学习C语言编制程序:了解C语言程序设计方法和组成部分。
2.学习编制连接命令文件,用来控制代码的连接。
3.学会建立和改变map文件,以及利用它观察DSP内存使用情况。
4.进一步熟悉CCS调试程序。
二、实验设备1.PC机一台:操作系统为Windows2000或WindowsXP。
2.ICETEK-F2812-EDU实验箱一台。
三、实验原理1.C语言程序(1)CCS支持使用标准C语言应用程序。
当使用标准C 语言编制的程序时,其源程序文件名的后缀应为.c(如:volume.c)。
(2)CCS 在编译标准C 语言程序时,首先将其编译成相应汇编语言程序,再进一步编译成目标DSP 的可执行代码。
最后生成的是coff 格式的可下载到DSP 中运行的文件,其文件名后缀为.out。
2.命令文件的作用命令文件(文件名后缀为cmd)为链接程序提供程序和数据在具体DSP 硬件中的位置分配信息。
通过编制命令文件,我们可以将某些特定的数据或程序按照我们的意图放置在DSP 所管理的内存中。
命令文件也为链接程序提供了DSP 外扩存储器的描述。
在程序中使用CMD 文件描述硬件存储区,可以只说明使用部分,但只要是说明的,必须和硬件匹配,也就是只要说明的存储区必须是存在的和可用的。
3.内存映射(map)文件的作用一般地,开发的DSP 程序在调试好后,要固化到系统的ROM 中。
为了更精确地使用ROM空间,我们就需要知道程序的大小和位置,通过建立目标程序的map 文件可以了解DSP 代码的确切信息。
当需要更改程序和数据的大小和位置时,就要适当修改cmd 文件和源程序,再重新生成map 文件来观察结果。
另外,通过观察map 文件,可以掌握DSP 存储器的使用和利用情况,以便进行存储器方面的优化工作。
四、实验步骤1.实验准备:设置软件仿真模式。
2.建立工程文件:新建工程文件设置如图2.1。
轻松学会DSP——第4章-TMS320C54x软件开发
汇编器对段的处理
2.2.已初始化段 已初始化段包含可执行代码或已初始化数据。
这些段的内容存储在目标文件中,加载程序 时再放到TMS320C54X存储器中。三个用于 建立初始化段的伪指令句法分别为: .text [段起点] .data [段起点] .sect “段名”[,段起点]
汇编器对段的处理
件为真时要汇编代码块。 .else — 标志若.if条件为假时要汇编代码块。 .endif — 标志条件块的结束,并终止该条件代码块。
汇编伪指令
3.引用其他文件 .include '文件名' — 将指定文件复制到当前位置,其
内容可以是程序、数据、符号定义等。 .copy '文件名' — 与.include类似。 .def 符号名 — 在当前文件中定义一个符号,可以被
归档器
Option:归档器工作 -q :不显示状态栏及相关信息; -s :打印全局变量;
Libname: 库文件名 Filename:目标文件
Ar500 -a function sine.obj cos.obj flt.obj
3 、连接器
lnk500 [ -options] filename 1 . ... filename n -e global_symbol:定义程序的进入点; -c:使用C编译器的ROM初始化模式; -cr:使用C编译器的RAM初始化模式; -i dir:指定库文件的路径; -l filename:指定连接时使用的库文件名; -m filename:生成map文件; -o filename:指定生成的out文件名。系统缺省
链接器对段的处理有两个功能。首先,它将 汇编器产生的COFF目标文件(.obj文件)中 的各种段作为输入段,当有多个文件进行链 接时,它将输入段组合起来,在可执行的 COFF输出模块中建立各个输出段。其次,链 接器为输出段选择存储器地址。
DSP的C语言编程
DSP的C语言开发一、流程步骤:main() {}下面是vectors.asm函数,该文件在每个DSP的project中(需手工加入),其中有对_c_int00的调用,而_c_int00在rts.lib中,在开发时要手工加入。
在reset 后,rom等外存中的程序已经转移到了L2 cache中,并且程序从0x0000 0000处开始执行,而0x0000 0000处的程序正是vectors.asm,以下就开始层层调用,进入main函数。
======== vectors.asm ========; Plug in the entry point at RESET in the interrupt vector table;;; ======== unused ========; plug inifinite loop -- with nested branches to; disable interrupts -- for all undefined vectors;unused .macro id.global unused:id:unused:id:b unused:id: ; nested branches to block interruptsnop 4b unused:id:nopnopnopnopnop.endm.sect ".vectors".ref _c_int00 ; C entry point.align 32*8*4 ; must be aligned on 256 word boundaryRESET: ; reset vectormvkl _c_int00,b0 ; load destination function address to b0mvkh _c_int00,b0b b0 ; start branch to destination functionmvc PCE1,b0 ; address of interrupt vectorsmvc b0,ISTP ; set table to point herenop 3 ; fill delay slotnopnop;; plug unused interrupts with infinite loops to; catch stray interrupts;unused 1unused 2unused 3unused 4unused 5unused 6unused 7unused 8unused 9unused 10unused 11unused 12unused 13unused 14unused 15Rts6000.lib来自于rts6000.src,该原文件是由多个.c和.cpp以及.asm组成的,其中关于int _args_main()的函数:这个函数就是void __interrupt c_int00()在初始化完成后调用的函数,int _args_main()函数中调用了main(argc, argv)从而正式转入main函数。
DSP的C语言程序设计
DSP的C语言程序设计一、为什么要使用C语言对DSP编程C语言是高级语言,易学易用。
C语言的编程效率极高,易于调试。
C语言的可移植性好。
二、C程序的结构及组成完整的C程序是由一个主函数main()和其它的子函数组成的,每一个子函数完成特定的功能。
DSP的C 语言的入口地址固定为c_int00,在中定义。
C语言支持丰富的数据类型和数据结构,在ccs集成开发环境中,为C语言提供了完整的支持硬件的底层函数库和支持算法的DSP函数库。
在使用C语言的库函数时,在工程中必须包括相应的函数库和运行时支持库。
下面是一般C语言程序的结构和组成框架。
一般C程序的结构如下:h头文件#include “函数库1”#include <函数库2>#include “函数库3”…*//* *//* Parameters: *//* - port - port address (HEX) *//* *//* Return: *//* - returns value read from port. *//* *//* Notes: *//* *//*****************************************************************************/s16 portRead(u16 port);/*****************************************************************************//* portWrite(u16 port, s16 value) *//* *//* This routine writes a word to the specified port. */ /* *//* Parameters: *//* - port - port address (HEX) *//* - value - 16 bit word to write. *//* *//* Return: *//* - none *//* *//* Notes: *//* *//*****************************************************************************/void portWrite(u16 port, s16 value);#endif /* end of #ifndef _PORTIO_H */使用时,先使用宏替换或枚举定义I/O端口的地址,然后使用portRead()和portWrite()函数访问I/O端口例如:#includeVariable=portRead(portA);c5400\cgtools\include目录与c5400\dsk5402\include目录中的头文件类型不同。
DSP软件开发流程
软件开发基础
DSP C语言:C运行环境(3) 语言: 运行环境 运行环境( ) 语言
系统初始化
在运行C程序前,必须建立C运行环境,此任务由C引导程序 _c_int00完成 _c_int00包含在库函数中,build时自动将其链接进可执行程序中, 程序的入口地址必须设为_c_int00起始地址 _c_int00的源程序存放在由rts.src分离出来的boot.asm中,用户可 根据需要修改
初试化段和未初始化段
.bss和.usect为未初始化段,用于为变量、堆栈等保留一块存储空 间 .text、.data和.sect为初试化段,用于存放代码块或有初值的数据 块
系统定义的段和用户定义的段
.text、.data和.bss为系统已定义好的段名 用户根据需要用. sect和.usect伪指令来定义段名,创建相应的“段 ”
软件开发基础
软件build流程 流程 软件
.CPP file .C file .ASM file .ASM file .OBJ file Linker .OUT file .HEX file .OBJ file .ASM file Assembler .OBJ file
目标文件地址是浮动的,能被重定位 链接器用.cmd文件对链接目标,进行重定位
加载时定位:PC机系统采用
编程、编译和链接时均未对程序进行绝对定位 程序运行前,由操作系统对程序进行重定位,并加载到存储空间中
软件开发基础
程序定位方式的比较
编译时定位:
ORG xxxx,绝对定位 优点:简单、容易上 手 缺点:程序员必须熟 悉 硬件资源 模块化编程差 工程化不支持 持
链接时定位:
SECTION,相对定位 缺点:灵活、上手较 难 优点:程序员不必熟 悉 硬件资源 模块化编程强 工程化管理支
第7章 DSP的C语言编程
• DSP的C编译器还在不断优化; DSP的 编译器还在不断优化; • DSP的C编译器符合ANSI C标准; DSP的 编译器符合ANSI C标准 标准; • ANSI C标准会受处理器、运行环境或主机环境 C标准会受处理器、 标准会受处理器 的影响。 的影响。
14:42:22
6
CCS的C语言简介
• 由DSP厂商及第三方为DSP提供C编译器; DSP厂商及第三方为 厂商及第三方为DSP提供 编译器; 提供C • 使得采用高级语言开发DSP软件成为可能; 使得采用高级语言开发DSP软件成为可能 软件成为可能; • TI公司的CCS又提供了优化的C编译器; TI公司的 公司的CCS又提供了优化的 编译器; 又提供了优化的C
14:42:22
4
• Output Files
– Assembly source output
Generates assembly language source files that you can inspect easily, enabling you to see the code generated from the C/C++ source files.
14:42:22
11
• 访问数据空间 访问数据空间
– 通过指针来实现; 通过指针来实现; 指针来实现
*(unsigned int *) 0x1000=a; b=*(unsigned int *) 0x1001;
可以不事先进行定义; – 访问数据空间的地址可以不事先进行定义; 访问数据空间的地址可以不事先进行定义
※ const
轻松学会DSP——C程序编写和编译课件
根据个人习惯选择
开发者可以根据自己的习惯和喜好 选择适合自己的开发环境,比如习 惯使用CCS的开发者可以选择CCS 作为开发环境。
根据开发成本选择
开发者还需要考虑开发环境的成本 ,比如购买IDE的费用、学习成本等 。在选择开发环境时,需要根据实 际情况进行综合考虑。
05
DSP程序调试
BIG DATA EMPOWERS TO CREATE A NEW
FFT算法分类
FFT算法有多种实现方式,如基于 蝶形运算的Cooley-Tukey FFT算 法和基于分治思想的FFT算法等。 Cooley-Tukey算法是最常用的 FFT算法,其基本思想是将一个长 度为$N$的DFT分解为多个长度 为$N/2$的Hale Waihona Puke FT,递归计算直到 长度为2的DFT。
FFT算法实现过程
BIG DATA EMPOWERS TO CREATE A NEW ERA
轻松学会DSP——C程序编
写和编译课件
• DSP基础概念 • DSP编程语言 • DSP编译过程 • DSP开发环境 • DSP程序调试 • DSP应用实例
目录
CONTENTS
01
DSP基础概念
BIG DATA EMPOWERS TO CREATE A NEW
数字控制系统有多种类型,如开环控 制系统和闭环控制系统等。开环控制 系统结构简单,但控制精度和稳定性 较差;闭环控制系统具有反馈环节, 能够提高控制精度和稳定性。
数字控制系统的设计方法包括状态空 间法、根轨迹法和频域法等。状态空 间法能够得到系统的全部状态信息, 但计算量大;根轨迹法能够得到系统 的极点位置,但计算精度较低;频域 法能够得到系统的频率响应,但无法 得到系统的全部状态信息。
DSP的C语言编程
C LKOUT TOUT
1 2
J1 C ON2 R 2 4.7K DGND
A19 NC GND DVDD D6 D7 D8 D9 D10 D11 D12 HD4 D13 D14 D15 HD5 C VDD NC HDS1 GND HDS2 DVDD A0 A1 A2 A3 HD6 A4 A5 A6 A7 A8 A9 C VDD NC NC
15~ 12 保留
11 soft
10 9 ~ 6 5 4 3~ 0 free PSC TRB TSS TDDR
定时器开始定时后,减1计数器开始计数, 计数到0再减1时产生借位Байду номын сангаас将会使中断标志 寄存器IFR的第3位TINT置1,在程序中可以 不断地查询该标志位的状态,以判断定时时 间到否。原理可参见教材。 定时时间=Tclk X (Ttddr+1) X (Tprd+1) 可以思考下面两个问题: 1、请计算在本例中最大定时时间? 2、该怎样用定时器查询方式实现LED闪烁。
• 3、操作步骤要点: (1)新建项目/新建文件/添加文件到项目/编 辑文件; (2)点“rebuild all”工具进行编译、汇编 和链接; (3)装载上一步生成的out文件; (4)点击“运行”按钮,观察小系统板D1闪烁。
• 4、汇编程序参考:(主程序文件)
中断向量表文件
链接命令表文件
• 5、C程序参考:(源程序均为C文件)
72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37
D G N D B C L K X 1 DGND HD1 C VDD INT 3 INT 2 INT 1 INT 0 NM I HB IL IAC K B DX2 B DX0 HD0 DGND 3.3V HR DY B FSX2 B FSX0 C VDD HPINT DGND B C LKX2 B C LKX0 B DR 2 HC T 1 B DR 0 B FSR 2 B FSR 0 B C LKR 2 B C LKR 0 DGND HC T 0 B C L K R 1 D G N D
如何用C语言开发DSP嵌入式系统_百度文库(精)
如何用C 语言开发DSP 嵌入式系统肖宛昂曾为民Xiao,Wanang Ceng,Weimin(华东交通大学肖宛昂曾为民摘要目前很多嵌入式系统以DSP 为核心构建,但是,采用汇编语言开发DSP 系统存在开发难度大、开发周期长、维护性差等缺点,应用C 语言开发DSP 系统是广大嵌入式开发者的迫切要求。
有关单片机的C 语言开发有相当多的资料可以参考,而DSP 系统的C 语言开发却很少见。
本文以TI 公司的DSP 器件TMS320F24X 系列为例,讲述怎样用C 语言开发一个完整的DSP 嵌入式系统。
关键词:嵌入式系统; DSP系统; C语言开发; TMS320F24X系列引言大家在开发嵌入式产品时首先会想到用控制器的汇编语言编写监控程序,主要原因是:①汇编语言生成的程序对应的二进制代码少,程序执行要比高级语言生成的程序快;②控制器刚问世时,没有相应的高级语言可供使用;③存储器的价格问题和寻址空间的限制。
以上所述问题目前已基本解决,在这就不阐述了。
实际情况是:在单片机的应用领域,开发者已开始使用C 语言进行开发。
大家发现用高级语言开发嵌入式产品是如此轻松,并且C 语言程序编译后的二进制代码也非常短小精练。
目前使用最多的数字信号处理器(DSP )是美国TI 公司的TMS320家族,而工业控制上用得最多的又是TMS320F2XX 系列。
TI 公司为每一个DSP 芯片提供了汇编语言和C 语言供开发者选用。
本人一直使用C 语言进行产品开发,而目前很少见到这方面的介绍、所以特撰此文,以TMS320F240为例,向各位同行推荐用C 语言开发DSP 嵌入式系统。
1 DSP的C 语言的特殊性大家在使用51系列C 语言时已经注意到,控制器的C 语言和PC 机上使用的C 有一个显著的特点:经常要对硬件操作,程序中有大量针对控制器内部资源进行操作的语句。
所以,开发者要明白怎样用C 语言来操纵控制器的内部资源,即怎样用C 语句操作寄存器和内部存储器等。
第15章 DSP的C语言编程
15.2.2 TMS320C2000 C语言的数据类型
注:在TMS320C2x/C2xx/C5x C语言中,字节长度为16位,sizeof操作符返回 的对象长度是以16位为字节长Байду номын сангаас的字节数。例如sizeof(int) = 1。
15.2.3 TMS320C2000 C语言的关键字 const(常数) ioport(I/O端口) interrupt(中断) near(近) far(远) volatile(可变的)
第15章
15.1 DSP C语言简介
DSP的C语言编程
DSP生产厂商及第三方为DSP软件开发提供了C编译器,使 得利用高级语言实现DSP程序的开发成为可能。在TI公司的 DSP软件开发平台CCS中,又提供了优化的C编译器,可以 对C语言程序进行优化编译,提高程序效率,目前在某些应 用中C语言优化编译的结果可以达到手工编写的汇编语言效 率的90%以上。DSP生产厂商和相关公司也在不断对C优化 编译器进行改进设计,相信日后C语言程序优化编译的效果 会有进一步的改善。 TMS320C2000系列提供有优化的C编译器,它支持ANSI (American National Standards Institute,美国国家标准 委员会)开发的C语言标准。该C语言标准是使用最广泛的C 语言标准,ANSI标准具有一些受目标处理器、运行期环境 或主机环境影响的C语言特性,从有效性或实现上的考虑, 这些特征在各种标准的C编译器之间可能有不同。
15.2.7 访问I/O空间
读写I/O空间的功能是TMS320C2000 C编译器对标准C的扩 展,是利用关键字ioport(I/O端口)来实现的。
该关键字的用法为: ioport type porthexnum; ioport指示这是定义一个端口变量的关键字。 type(类型)必须是char(字符)、short(短整型)、 int(整型)或对应的无符号类型。 porthexnum为定义的端口变量,其格式必须是“port” 后面跟一个16进制数,如“port000A”是定义访问I/O 空间地址0Ah的变量。
4C语言DSP程序设计
4C语言DSP程序设计1. DSP(Digital Signal Processing)是数字信号处理的缩写,是一种专门用来处理数字信号的技术和方法。
C语言是一种通用的高级编程语言,被广泛应用于DSP程序设计中。
在本文中,我们将介绍C语言在DSP程序设计中的应用。
2.首先,我们来了解一下C语言在DSP程序设计中的优势。
C语言具备较高的可移植性和良好的可扩展性,能够在不同的DSP平台上进行开发。
此外,C语言还具备较高的执行效率,可以快速地进行信号处理操作。
3.在C语言DSP程序设计中,通常需要使用到一些DSP开发工具和库。
例如,MATLAB是一种广泛应用于信号处理领域的工具,可以通过MATLAB提供的函数和工具包,生成C语言代码,并在DSP平台上运行。
此外,还有一些针对特定DSP平台的开发工具和库,例如TI的C6000系列开发工具和库等。
4.在C语言DSP程序设计中,常常需要使用到一些信号处理算法。
例如,滤波是一种常见的信号处理操作,可以通过C语言中的数组和循环结构,实现滤波算法。
此外,还有一些其他的信号处理算法,例如快速傅里叶变换(FFT)、自相关、互相关等,这些算法也可以通过C语言来实现。
5. 为了提高C语言DSP程序的执行效率,我们可以使用一些优化技术。
例如,使用inline关键字可以将一些函数内联到调用的地方,避免了函数调用的开销。
此外,还可以使用编译器提供的优化选项,例如开启优化级别、针对循环结构进行优化等。
6.在C语言DSP程序设计中,还需要考虑一些实时性的问题。
实时信号处理要求程序能够以实时的方式对信号进行处理,因此需要通过一些技术手段来保证程序的实时性。
例如,可以使用中断服务程序(ISR)来处理实时中断,确保程序能够快速地响应实时事件。
7.最后,C语言DSP程序设计中还需要注意一些代码质量的问题。
由于DSP程序往往是复杂的,因此需要注重代码的可读性和可维护性。
为了提高代码的质量,可以使用一些代码规范和开发工具,例如静态代码分析工具、单元测试框架等。
第4章DSP软件开发与C语言编程
30
段名称 .bss .stack .sysmem
未初始化段链接
内容 全局与静态变量 堆栈空间 malloc函数存储区
限制 64K数据 64K数据 64K数据
31
段(Section) .text .cint .pint .switch .const .bss .stack .sysmem
存储器映射表
存储器类型(Type of Memory) ROM 或RAM ROM 或RAM ROM 或RAM ROM 或RAM ROM 或RAM RAM RAM RAM
页面(Page) 0 0 0 0,1 1 1 1 1
32
4.3.2 链接命令文件
29
段名称 .text .cint
.pint .switch
.const
初始化段链接
描述 可执行代码和常量 已初始化的全局与静态变量的C初始 化记录 全局构造器(C++ constructor)表 实现switch语句表
限制 程序 64K数据
程序 程序/64K数据
已初始化的全局与静态const修饰变量, 64K数据 串常量
24
4.3.1 公共目标文件格式COFF
编译、汇编与链接程序建立的目标文件采用共用目标 文件格式(Common Object File Format, COFF),便于 模块化编程、管理代码段和存储器,即不必为程序代码或 变量指定目标地址。
汇编器根据命令用适当的段将各部分程序代码和数据 连在一起,构成目标文件。链接器分配存储单元,即把各 个段重新定位到目标存储器中。
18
Project菜单
19
View菜单
20
Debug菜单
21
C语言DSP开发
命令文件(.cmd文件)示例
C编译器产生如下两类段: (1).初始化段:其中包括数据表和执行代码。 ①. .text段:用于存放可执行代码和实型常量 ②. .cinit段:存放初始化变量表和常量表 ③. .const段:存放字符串常量、全局变量和静态 变量的定义及其初始化内容 ④. .switch段:存放switch语句建立的表格
比如说要使用sin函数,必须使用下列语句把 其头文件math.h包含进程序: #include〈math.h〉 … x=sin(y);
返回
南航自动化学院DSP技术应用实验室 南航自动化学院DSP技术应用实验室
C语言程序编写
• 采用任何文本编辑器,比如Windows的记事本 编写C程序。编写C程序时应注意: (1). 在一个C程序中必须并且只能有一个函数 名称为main(); (2).函数定义时,同时要声明变量的类型; (3).用户自己定义的子函数一般放在主程序之 前;若放在主程序之后,必须在程序开头声明 各子函数。
南航自动化学院DSP技术应用实验室 南航自动化学院DSP技术应用实验室
3.函数结束
函数结束返回时,必须恢复C环境: (1).处理要传递给调用者的返回值。 (2).如果使用了AR6和AR7,必须恢复。 (3).撤消为局部变量和临时值分配的空间。 (4).恢复原来的帧指针FP。 (5).把返回地址压入C2xx堆栈。 (6).返回。
南航自动化学院DSP技术应用实验室 南航自动化学院DSP技术应用实验室
7. 汇编模块中被C访问的标识符前要 加下划线
C编译器在所有C标识符前加下划线,所以 在汇编模块中被C访问的汇编标识符前也必须 加下划线。
用C语言开发DSP系统的全过程
一个合格的硬件工程师,应该都学,我推荐你先学习C语言,因为汇编入手太慢,写程序要以C为主,需要高速的或者底层的操作用内嵌汇编的方式。
汇编和c同样重要,相互配合,缺一不可!汇编的重要性:帮助你从根本上彻底和完全了解芯片的结构和性能,以及工作原理,如何使用。
在小的芯片上实现小的系统。
系统的调试。
尽管你使用了高级语言,在调试中可以帮助你了解C代码的性能和特点,甚至找到使用开发平台本身的BUG。
编写时序要求严格的代码,实现一些高级语言不易实现的功能。
从目前的技术和应用发展来看,对硬件工程师的要求越来越高。
以我的观点,作为单片机和嵌入式系统开发真正的高手,应具备以下几个方面的综合能力:硬件。
模拟、数字电路的雄厚基础,了解跟踪现在市场上的各种元器件的应用和发展,能够进行可靠、完善的电路设计以及PCB的设计。
软件。
不仅需要精通汇编语言,也要精通C语言,要有好的单片机系统程序设计理念和能力,学校中学的那些分支结构、循环结构等基本原理远远不够!要有基本的数据结构的知识。
否则你如何设计实现USB HOST读U盘的接口?如何实现嵌入式WEB系统?以及如何使用真正了解和使用RTOS?具备计算机网络和数字通信的基础知识,从根本上熟悉和了解各种协议的构造和实现,如:UART、RS232、SPI、I2C、USB、IEEE802、TCP/IP等。
计算机应用的高手。
熟练阅读英文资料。
热爱和喜欢电子技术,具备刻苦精神、踏踏实实,不弄虚作假,不浮躁。
多动手,勤实践。
有强烈的专业和钻研精神。
最后一条最重要!摘要:目前很多嵌入式系统以DSP 为核心构建,但是,采用汇编语言开发DSP 系统存在开发难度大、开发周期长、维护性差等缺点,应用C 语言开发DSP系统是广大嵌入式开发者的迫切要求。
有关单片机的C 语言开发有相当多的资料可以参考,而DSP 系统的C 语言开发却很少见。
本文以TI 公司的DSP 器件TMS320F24X 系列为例,讲述怎样用C 语言开发一个完整的DSP 嵌入式系统。
第15章 DSP的C语言编程
C编译器可在编译器输出的汇编语言程序中直接输出汇编指令或 编译器可在编译器输出的汇编语言程序中直接输出汇编指令或 语句。利用asm语句嵌入汇编语言程序,可实现一些C 语句。利用asm语句嵌入汇编语言程序,可实现一些C语言 asm语句嵌入汇编语言程序
13
实现起来比较麻烦的硬件控制功能。 实现起来比较麻烦的硬件控制功能。 硬件控制功能 asm语句在语法上就象是调用一个函数名为asm的函数, asm语句在语法上就象是调用一个函数名为asm的函数,函数参 语句在语法上就象是调用一个函数名为asm的函数 数是一个字符串: 数是一个字符串: asm (“assembler text”); 编译器会直接将“参数字符串”复制到输出的汇编语言程序中, 编译器会直接将“参数字符串”复制到输出的汇编语言程序中, 会直接将 因此必须保证参数双引号之间的字符串是一个有效的汇编语 因此必须保证参数双引号之间的字符串是一个有效的汇编语 双引号之间的字符串是一个 言指令。 言指令。 双引号之间的汇编指令必须以空格、制表符(TAB)、标记符 双引号之间的汇编指令必须以空格、制表符(TAB)、标记符 必须以空格 )、 (LABEL)或注释开头,这和汇编语言编程的要求是一致的。 LABEL)或注释开头,这和汇编语言编程的要求是一致的。
14
编译器不会检查此汇编语句是否合法,如果语句中有错误, 编译器不会检查此汇编语句是否合法,如果语句中有错误,在汇 不会检查此汇编语句是否合法 编的过程中会被汇编器指出。 编的过程中会被汇编器指出。 使用asm指令应小心不要破坏C语言的环境。如果C代码中插入跳 使用asm指令应小心不要破坏C语言的环境。如果C代码中插入跳 asm指令应小心不要破坏 转指令和标记符可能会引起不可预料的操作结果 可能会引起不可预料的操作结果。 转指令和标记符可能会引起不可预料的操作结果。能够改变 段或其它影响C语言环境的指令也可能引起麻烦。 段或其它影响C语言环境的指令也可能引起麻烦。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要:目前很多嵌入式系统以DSP 为核心构建,但是,采用汇编语言开发DSP 系统存在开发难度大、开发周期长、维护性差等缺点,应用C 语言开发DSP 系统是广大嵌入式开发者的迫切要求。
有关单片机的C 语言开发有相当多的资料可以参考,而DSP 系统的C 语言开发却很少见。
本文以TI 公司的DSP 器件TMS320F24X 系列为例,讲述怎样用C 语言开发一个完整的DSP 嵌入式系统。
大家在开发嵌入式产品时首先会想到用控制器的汇编语言编写*程序,主要原因是:一、汇编语言生成的程序对应的二进制代码少,程序执行要比高级语言生成的程序快。
二、控制器刚问世时,没有相应的高级语言可供使用。
三、存储器的价格问题和寻址空间的限制。
以上所述问题目前都基本上解决了,在这就不阐述了。
实际情况是:在单片机的应用领域,开发者开始使用C语言进行开发了。
大家发现用高级语言开发嵌入式产品是如此轻松,并且C语言程序编译后的二进制代码也非常短小精练。
目前使用最多的数字信号处理器(DSP)是美国TI公司的TMS320家族,而工业控制上用的最多的又是TMS320F2XX系列,TI公司为每一个DSP 芯片提供了汇编语言和C语言供开发者选用,本人一直使用C语言进行产品开发,而目前很少见到这方面的介绍,所以特撰此文以TMS320F240为例,向各位同行推荐用C语言开发DSP嵌入式系统。
1、DSP的C语言的特殊性大家在使用51系列C语言时已经注意到,控制器的C语言和PC机上使用的C有一个显著的特点:经常要对硬件操作,程序中有大量针对控制器内部资源进行操作的语句。
所以,开发者要明白怎样用C语言来操纵控制器的内部资源,既怎样用C语句操作寄存器和内部存储器等。
举个例子,在51汇编中我们写MOV A,#20H,汇编程序能够识别A是指累加器,而在51 C程序中我们写ACC=32;,编译器能够识别ACC是指累加器而不是一般的变量。
即每一个寄存器都有一个专有名字供开发者使用,它们定义在一个头文件reg51.h 中,程序员只需在程序的开始部分用#include“reg51.h”语句将该文件包含进来即可。
注意:这些寄存器的名字不能用做变量名。
同样,在TMS320F240的C语言中也有一个头文件C240.H定义各个寄存器的名称,这里摘录几条语句进行介绍。
比如:#define IMR ((PORT)0x0004)#define XINT1_CR ((PORT)0x07070)IMR 、XINT1_CR就对应两个寄存器,实际是寄存器的地址,用高级语言的说法是指针。
我们也在程序的开始部分用#include“c240.h”语句将该文件包含进来。
这样,在DSP的C 语言中使用它们只需在前面加一个星号(*),例如,*IMR=0X1010;/* 将16进制数1010H赋给IMR寄存器*/*XINT1_CR=0X0A0B0;/*将16进制数A0B0H赋给XINT1_CR寄存器*/开发者最好将c240.h这个文件打印出来,弄清楚各个寄存器的定义名称。
至于不涉及硬件的语法和ANSI 语法一样,需要注意的是,有些ANSI标准中的函数在DSP的编译器中不提供,读者可以参考DSP编译器的C语言手册。
搞清楚了这些特殊性,由汇编语言转到C语言开发是很容易的事,当然,没有汇编语言编程基础的人同样可以用C语言开发DSP应用系统。
有关嵌入式系统的C语言编程可参考《单片机与嵌入式系统应用》2001年1到6期上马忠梅的“嵌入式C编程技术”,本文不做讨论。
下面只针对以TMS320F240芯片为处理器的嵌入式C语言编程进行阐述,希望能够指导读者进行具体操作。
2、TMS320F240芯片的C语言开发过程简单地说,整个过程包括以下五个步骤:编辑C语言源程序编译源程序(注意编译参数)链接目标文件(注意用CMD文件)在线仿真固化程序下面分别进行阐述。
一源程序的编辑可以用任何一个编辑器书写源程序,如EDIT、NOTEPAD等,最后以.C为后缀存盘。
源代码可以写在一个C文件中,也可写在多个C文件中,有些预定义变量和函数原型声明可以集中放在一个头文件中。
注意事项:不要忘记在C程序的前面用#include “c240.h”将寄存器定义文件包括进来。
二源程序的编译源程序编辑好后可以用DSPCL编译程序进行编译,生成OBJ文件。
使用格式:DSPCL 源文件名参数例如:DSPCL EX1.C –V2XX –GK –MN常用参数的意义:V2XX:表示C编译器选择处理器2XX系列GK:保留编译生成的汇编文件(.ASM文件)MN:进行正常优化其他参数请参考DSP编译器的手册。
如果有多个源文件,分别编译。
每一个源文件经编译后产生一个OBJ文件和ASM文件。
三目标文件的链接(一)TI公司的COFF文件格式TI 公司新的汇编器和编译器创建的目标文件采用COFF的目标文件格式(Common Object File Format)采用COFF格式有利于模块化编程,为管理代码段和目标系统存储器提供更加强有力和灵活的方法。
基于COFF格式编写汇编程序或C语言程序时,不必为程序代码和变量指定目标地址,为程序编写和程序移植提供了极大的方便。
COFF格式的基本思想是:鼓励程序员在用汇编语言或C语言编程时运用代码块和数据块的概念。
这种块称为SECTION,是目标文件中的最小单位。
所有的块分为两大类:已初始化块和未初始化块,已初始化块包含程序代码和数据,未初始化块是为未初始化的数据在存储器中的保留块。
C编译器对C程序编译后产生已初始化块和未初始化块,已初始化块如.text 块、.const 块、.cinit块;未初始化块如.bss 块。
举个例子,当程序员用C语句float data[100];定义一个数组时不需要指定这100个数组元素的具体位置,编译器会在数据区预留所需空间,到链接时链接器会具体定位。
(二)链接器对块的处理链接器对块的处理有两个功能:其一,将COFF目标文件中的块用来建立程序块和数据块,并将这些块组合成可以被DSP芯片执行的COFF输出模块;其二,链接器为输出块指定存储位置。
链接器提供两个命令实现上述功能:MEMORY和SECTIONS。
MEMORY命令定义目标系统的存储器,程序员可以定义每一块存储器并指定起始地址和长度;SECTIONS命令用来定义输入块的组合和输出块在存储器中的存放位置。
若不用MEMORY和SECTIONS 命令,链接器采用缺省的分配算法;推荐使用这两个命令,但要注意这两个命令在CMD文件(链接器命令文件)中使用。
下面分析一个TMS320F240芯片的典型CMD 文件。
(假设文件名EX1.CMD)1、CMD文件的构成及其详细解释BOOT.OBJ /* F240的中断矢量表,参见后面的说明*/EX1.OBJ /* 源程序编译后对应的目标文件*//* 若程序有多个目标文件,一块写在这里*/-STACK 0X400 /* 设定系统堆栈*/-C /* ROM初始化*/-O EX1.OUT /* 输出的文件名*/-M EX1.MAP /* 输出映像文件名*/-L RTS2XX.LIB /* 链入RTS2XX.LIB库*/MEMORY /*MEMORY命令规定系统的存储器配置*/{PAGE 0:ROM0:origin=0000h,length=003fh /* FLASH ROM */PAGE 0:ROM1:origin=0040h,length=0200h /*FLASH ROM */PAGE 0:ROM2:origin=0240h,length=3000h /* FLASH ROM */PAGE 1:RAM_B2:origin=0060h,length=0020h /* 内部RAM B2 */PAGE 1:RAM_B1:origin=0300h,length=0100h /* 内部RAM B1 */PAGE 1:RAM_B0:origin=0100h,length=0100h /* 内部RAM B0 */PAGE 1:RAM_EX:origin=0d000h,length=2800h /* 外部扩展RAM */}SECTIONS /* SECTIONS 命令规定了程序中块的具体分配方法*/{.vectors:load=ROM0 /* 规定矢量表的存放位置*/.cinit:load=ROM1 /* C初始化表的存放位置*/.text:load=ROM2 /* 系统程序的存放位置*/.bss load=RAM_B0 /*未初始化数据的存放位置*/.const load=RAM_B1 /* 已初始化数据的存放位置*/}2、TMS320F240链接时所需的中断矢量表文件TMS320F240的目标文件在链接时要用到中断矢量表,中断矢量表用汇编语言编写,和具体的DSP芯片有关,假设TMS320F240的中断矢量表对应的汇编程序为BOOT.ASM,汇编后的文件名为BOOT.OBJ。
下面是一个典型的矢量表文件(假设程序名为BOOT.ASM)。
.port /* 定义中断函数的名字*/.globl _c_int0 /* 中断0对应的函数名*/.globl _c_int1 /* 中断1对应的函数名,以下语句的意义相同*/.globl _c_int2 /* 可以将中断函数名看作中断入口地址*/.globl _c_int3 /* 矢量表的存放不需程序员干预*/.globl _c_int4.globl _c_int5.globl _c_int6.globl _c_int7.globl _c_int8.sect “.vectors”/*用.sect命令自定义一个块,用于存放中断矢量表*/RSVECT B _c_int0 /* 中断0发生后,程序的跳转目的地址*/INT1 B _c_int1 /* 中断1发生后,则跳到c_int1()函数处*/INT2 B _c_int2 /* 意义同上,下同*/INT3 B _c_int3INT4 B _c_int4INT5 B _c_int5INT6 B _c_int6用汇编器汇编该程序,命令形式:DSPA BOOT.ASM –V2XX 生成BOOT.OBJ文件供链接器使用。
这样,我们就可以按如下形式在C源程序中编写中断函数:void c_intx()/* x为1—8中之一*/{中断程序的C语句系列;}注意事项:c_int0()是系统入口函数,用户不能编写。
经过上面对命令文件(CMD文件)和中断矢量表的介绍,接下来可以链接命令文件来生成所需要的OUT文件供DSP芯片执行或进行软仿真。
命令形式:DSPLNK CMD文件名例如:DSPLNK EX1.CMD另一种情况是,不使用CMD文件,使用缺省配置,简单介绍如下:命令形式:DSPLNK OBJ文件名参数例如DSPLNK EX1.OBJ BOOT.OBJ –O XX1.OUT –M XX1.MAP以上三步可以用下图描述:四程序的仿真EMURST 仿真器复位命令EMU2XXW EX1.OUT 载入COFF格式的二进制代码仿真运行,有关调试器的使用限于篇幅在此就不做讨论了。