资源描述
99,第,9,章,DSP,软件开发与,C,语言编程,9.1 集成开发环境CCS,9.2 DSP C工程文件,9.3 DSP C语言程序设计根底,9.4 DSP 外设存放器定义,9.5 典型的C文件举例,9.6 复位引导与Bootloader,9.7 片内Flash运行应用程序,DSP,开发工具与软件开发流程,1. DSP,开发工具,硬件,TI XDS510 (Extended Development System),硬件仿真器。,DSK(DSP Starter Kit),初学者开发套件。,评估,板。,DSP,教学实验系统 。,开发工具包括硬件、软件两局部。硬件局部主要是仿真器(Emulator),软件主要是集成开发环境CCS (Code Composer Studio)。,DSP开发系统(仿真器)有PCI插卡式、并口式、USB接口式,目前多用USB接口式,即DSP开发系统通过USB接口与PC机相连,开发系统通过JTAG基于扫描的仿真接口与用户目标板相连,实现DSP软硬件调试与程序烧写。,3,C,源文件,C,编译器,汇编,源文件,汇编器,汇编,源文件,COFF,目标,文件,链接器,可执行的,COFF,文件,宏,源文件,归档,器,宏库,归档器,目标,文件库,建库工具,运行时,支持库,EPROM,编程器,TMS320,DSP,调试工具,XDS Emulator with Debugger,绝对地址,列表器,HEX,代码,转换工具,Simulator,2.,软件开发流程,软件开发流程,1编辑:生成源程序*.asm, *.c、头文件(*.h),与命令文件(* d)。,2编译与汇编:生成目标文件(*.obj ,公共目标文件COFF格式)及列表文件(*.lst)。,3连接:生成可执行代码文件(*.out)及映射文件(*.map)。,4调试:通过JTAG接口下载到目标系统。,5) 通过JTAG接口将程序固化烧写到Flash 存储器 。,软件开发工具主要有源程序编辑器,(Editor),、编译器,(Compiler),、汇编器,(Assembler),、链接器,(Linker),、归档器,(Archiver),、运行时支持库,(Run-Time-Support Library),、库建立程序,(Library-build Utility),、,HEX,转换程序,(Hex Conversion Utility),、绝对列表器,(Absolute Lister),和交叉引用列表器,(Cross-Reference Lister),、调试工具,(Debugging tools),、,GEL,语言,(General Extension Language,,通用扩展语言,),、,DSP/BIOS,等。,3.,软件工具,DSP,开发工具与软件开发流程,CCS,的,简介,CCS,是一种针对,TMS320,系列,DSP,的集成开发环境,在,Windows,操作系统下,采用图形接口界面,提供有环境配置、源文件编辑、程序调试、跟踪和分析等工具。,CCS,有两种工作模式,即,软件仿真器模式:,脱离,DSP,芯片,在,PC,机上模拟,DSP,指令集和工作机制,主要用于前期算法实现和调试。,硬件,在线编程模式:,可以实时运行在,DSP,芯片上,与硬件开发板相结合在线编程和调试应用程序。,DSP,开发工具与软件开发流程,CCS,的组成,TMS,320,集成代码产生工具,用来对,C,语言、汇编语言或混合语言编程的,DSP,源程序进行编译汇编,并链接成为可执行的,DSP,程序。,CCS,集成开发环境,集编辑、编译、链接、软件仿真、硬件调试和实时跟踪等功能于一体。,DSP,软件开发与,C,语言编程,DSP,软件开发,与,C,语言编程,CCS,的主要功能,CCS的功能十分强大,它集成了代码的编辑、编译、链接和调试等诸多功能,而且支持C/C+和汇编的混合编程,其主要功能如下:,具有集成可视化代码编辑界面,用户可通过其界面直接编写C、汇编、 d文件等;,含有集成代码生成工具,包括汇编器、优化C编译器、链接器等,将代码的编辑、编译、链接和调试等诸多功能集成到一个软件环境中;,DSP,软件开发,与,C,语言编程,CCS,的主要功能,高性能编辑器支持汇编文件的动态语法加亮显示,使用户很容易阅读代码,发现语法错误;,工程工程管理工具可对用户程序实行工程管理。,根本调试工具具有装入执行代码、查看存放器、存储器、反汇编、变量窗口等功能,并支持C源代码级调试;,CCS,的主要功能,断点,工具,能在调试程序的过程中,完成硬件断点、软件断点和条件断点的设置;,探测点工具,可用于算法的仿真,数据的实时监视等;,分析工具,包括模拟器和仿真器分析,可用于模拟和监视硬件的功能、评价代码执行的时钟;,DSP,软件开发,与,C,语言编程,CCS,的主要功能,数据的图形显示工具,可以将运算结果用图形显示,包括显示时域/频域波形、眼图、星座图、图像等,并能进行自动刷新;,提供GEL工具。利用GEL扩展语言,用户可以编写自己的控制面板/菜单,设置GEL菜单项选择项,方便直观地修改变量,配置参数等;,DSP,软件开发,与,C,语言编程,1. CCS,软件安装与设置,驱动程序设置。,Simulator: PC模拟软件仿真。,Emulator: 实时DSP硬件仿真。,9.1,集成开发环境,CCS,CCS,主要工具,源程序编辑器(Editor)。,C编译器C Compiler。,汇编器Assembler。,连接器Linker。,调试工具(Debug)。,十六进制转换公用程序(Hex Conversion Utility)。,9.1,集成开发环境,CCS,2. CCS,主要菜单与功能,CCS,的功能可以通过菜单或工具条按钮实现。,主要的菜单项有,File,、,Edit,、,View,、,Project,、,Debug,等。,典型,CCS,运行界面,主菜单功能,菜 单 选 项,菜 单 功 能,File,文件,文件管理,载入执行程序、符号及数据、文件输入,/,输出等,Edit,编辑,文字及变量编辑。如剪贴、查找替换、内存变量和寄存器编辑等,View,查看,工具条显示设置。包括内存、寄存器和图形显示等,Project,项目,工程项目管理、工程项目编译和构建工程项目等,Debug,调试,设置断点、探测点,完成单步执行、复位等,Profiler,性能,性能菜单。包括设置时钟和性能断点等,Option,选项,选项设置。设置字体、颜色、键盘属性、动画速度、内存映射等,GEL,扩展功能,利用通用扩展语言扩展功能菜单,Tools,工具,工具菜单。包括管脚连接、端口连接、命令窗口、链接配置等,Window,视窗,窗口管理。包括窗口排列、窗口列表等,Help,帮助,帮助菜单。为用户提供在线帮助信息,9.1,集成开发环境,CCS,File,菜单,Project,菜单,View,菜单,Debug,菜单,3.,采用,CCS,开发应用程序的步骤,创立一个新工程(project)。,编辑源程序(*.asm, *.c)与连接命令文件(* d) 。,将文件添加到该工程中(*.asm, *.c, *.h, * d)。,编译汇编连接。,装载程序。,调试程序。,程序固化。,9.1,集成开发环境,CCS,4.,调试程序,连续运行与单步运行。,设置断点。,查看与修改存储单元。,查看与修改存放器内容。,观察和编辑变量。,程序Animate运行和数据图形显示。,9.1,集成开发环境,CCS,C工程(Project)几种根本文件,CCS工程文件(扩展名为.pjt)。由CCS自动生成。,源程序: 汇编语言文件(*.asm), C文件(*.c)。,头文件(*.h): 定义存放器映射地址,用户自定义的常量等。,例如,头文件定义了ADC存放器, 头文件定义了PIE中断矢量。,链接命令文件* d。,库文件*.lib。 运行时支持库。,目标文件 (*.obj):COFF公共目标文件格式。,列表文件 (*.lst):汇编生成的文件。,映射文件 (*.map): 存储器分配。,可执行代码文件 (*.out)。,9.2,DSP,C,工程文件,DSP28_ADC.C 外设AD的初始化函数,与外设AD相关。,DSP28_CpuTimers.CCPU定时器的初始化和配置函数,与CPU的定时器相关。,DSP28_包含了2812所有的中断函数,写中断时,只要将程序写在对应的函数内就可以。,DSP28_ECan.C外设CAN的初始化函数,与外设CAN相关。,DSP28_Ev.C外设EV的初始化函数,与外设EV相关。,DSP28_全局变量的定义,定义了2812的存放器结构变量和数据段分配的声明。,9.2,DSP,C,工程文件,以合众达实验箱,cputimer,为例,DSP28_Gpio.CGPIO,的初始化,函数和,GPIO,相关。,DSP28_InitPeripherals.C,所有外设的初始化函数,函数的内容是调用了,2812,各个外设的初始化函数。,DSP28_Mcbsp.CMcbsp,的初始化函数,,与,Mcbsp,相关。,DSP28_PIE,初始化,函数与中断相关。,DSP28_PIE,中断向量表定义以及,初始化。,9.2,DSP,C,工程文件,DSP28_Sci.C,外设,SCI,的初始化函数,,与外设,SCI,相关。,DSP28_Spi.C,外设,SPI,的初始化函数,,与外设,SPI,相关。,DSP28_,系统初始化,,对,开门狗,时钟等模块进行初始化,以保证,2812,正常工作,,非常重要。,DSP28_Xintf.C,外部接口的初始化函数。,DSP28_XIntrupt.C,外部中断的初始化函数。,main.C,main,函数所在的文件。,9.2,DSP,C,工程文件,几个文件非常重要;,DSP28_DefaultIsr.C (中断入口,DSP28_GlobalVariableDefs.C 存放器结构变量,DSP28_PieCtrl.C PIE初始化函数与中断相关, PIE中断向量表定义以及初始化,系统初始化,9.2,DSP,C,工程文件,COFF,的一般概念,TI公司的汇编器和链接器创立的目标文件采用一种称为COFF (Common Object File Format)的目标文件格式。,采用COFF目标文件格式非常有利于模块化编程,基于COFF目标文件格式编写汇编程序或高级语言程序时,不必为程序代码或变量指定目标地址。,9.2,DSP,C,工程文件,COFF,的一般概念,COFF,目标文件格式的核心是在编写,DSP,程序时,基于代码段和数据段的概念,,而不是一条条命令或一个个数据,这使得程序的可读性和可移植性大大增强。,9.2,DSP,C,工程文件,COFF,的一般概念,汇编器和链接器生成的目标文件,是一个可以由,DSP,器件执行的文件。,在编写汇编语言程序时,,COFF,采用代码段和数据段的形式,以便于模块化的编程,,这些代码段和数据段简称为段。汇编器和链接器提供一些伪指令来建立和管理各种各样的段。,9.2,DSP,C,工程文件,COFF目标文件都包含以下3种形式的段:,.text 段(文本段),通常包含可执行代码;,.data 段(数据段),通常包含初始化数据;,.bss 段(保存空间段),通常为未初始化变量保存存储空间。,COFF文件的根本单元,1.,段(,sections),9.2,DSP,C,工程文件,2. 段的根本类型,COFF目标文件中的段有两种根本类型。,初始化段, 未,初始化段,(1),初始化段,初始化段中包含有数据或程序代码。主要有:,.,text,段已初始化段;,.,data,段已初始化段;,.,sect,段,已初始化段,由汇编器伪指令建立,的自定义段。,COFF文件的根本单元,9.2,DSP,C,工程文件,(2),未初始化段,在存储空间中,为未初始化数据保存存储空间。,它包括:,.bss段未初始化段;,.usect段未初始化段,由汇编命令建立的命名段自定义段。,COFF文件的根本单元,9.2,DSP,C,工程文件,3.,段与目标存储器的对应关系,汇编器的任务:在汇编过程中,根据汇编命令用适当的段将各局部程序代码和数据连在一起,构成目标文件。,链接器的任务:就是分配存储单元,将目标文件中的段重新定位到目标系统的存储器中,这一过程称为定位或分配。,COFF文件的根本单元,9.2,DSP,C,工程文件,目标文件中的段与目标存储器之间的关系,目标文件,目标存储器,.,bss,.,data,.,text,RAM,FLASH,FLASH,9.2,DSP,C,工程文件,汇编器对段的处理,汇编器对段的处理是通过段伪指令来区别各个段的,并将段名相同的语句汇编在一起。,汇编器有5条伪指令可识别汇编语言程序的各个局部:,.,bss,.,usect,.,text,.,data,.,sect,定义未初始化段,定义未初始化段,定义已初始化段,定义已初始化段,定义已初始化段,9.2,DSP,C,工程文件,未初始化段是在DSP存储器中保存空间,通常它们被定位在RAM区。在目标文件中,这些段中没有确切内容。,由这些段定义的空间仅作为临时存储空间,在程序运行时,可以利用这些存储空间存放变量。,未初始化段分为默认的和命名的两种,分别由汇编器伪指令.bss和.usect产生。,1.,未初始化段,汇编器对段的处理,9.2,DSP,C,工程文件,(1),.,bss,伪指令,用于在bss段中保存假设干个空间。,格式:.bss 符号, 字数 ( .bss INDATA, 1 ),符号对应于保存的存储空间第一个字的变量名称。,可以让其他段引用,字数表示在bss段或标有名字的段中保存假设干个存储单元。,每调用一次.bss伪指令,汇编器在相应的段保存更多的空间。,1.,未初始化段,9.2,DSP,C,工程文件,(2),.,usect,伪指令,用于为指定的命名段保存假设干个空间。,格式: 符号 .usect “段名, 字数,段名,程序员为未初始化的命名段定义的名字。,每调用一次.usect伪指令,汇编器在指定的命名段保存更多的空间。,1.,未初始化段,9.2,DSP,C,工程文件,已初始化段中包含有,可执行代码或初始化数据。,这些段中的内容都在目标文件中,当加载程序时再放到,DSP,的存储器中。,已初始化段由.,text、.data,和.,sect,三个伪指令建立。,2.,已初始化段,9.2,DSP,C,工程文件,已初始化命令的句法:,.text 段起点,.data 段起点,.sect “段名,段起点,段起点是任选项。,假设选用,它为段程序计数器SPC定义一个起始值。,假设默认,那么SPC从0开始。,2.,已初始化段,9.2,DSP,C,工程文件,汇编器对段的处理,命名段由用户指定,与默认的.text,.data和.bss段的使用相同,但它们被分开汇编。,假设一局部可执行代码例如初始化程序不希望和.text段分配在一起,可将它们汇编进一个命名段,这样就可定位在与.text不同的地方。也可将初始化的数据汇编到与.data段不同的地方,或者将未初始化的变量保存在与.bss段不同的位置。,可用.usect和.sect两个伪指令产生命名段。,3. 命名段自定义段,9.2,DSP,C,工程文件,.usect伪指令产生类似.bss的段,为变量在RAM中保存存储空间。,.sect伪指令产生类似.text和.data的段,可以包含代码或数据。,命名段自定义段,产生命名段伪指令格式:,符号 .usect “段名,字数,.sect “段名,(例如:.sect “.vectors),9.2,DSP,C,工程文件,链接器对段的处理,链接器是开发,DSP,器件必不可少的开发工具之一,它对段处理时有2个主要任务:, 将一个或多个,COFF,目标文件中的各种段作为链接器的输入段,经链接后在一个执行的,COFF,输出模块中建立各个输出段;, 在程序装入时对其重新定位,为各个输出段选定存储器地址。,9.2,DSP,C,工程文件,初始化,段,包含可执行代码或常数表,。,C,编译器产生的初始化段有,.pint,、,.const,、,.econst,、,.text,、,.cinit,、,.switch,。,.text,段,包含可执行代码和常量,(constant),。,.cinit,段和,.pint,段,包含初始化变量和常量。,.const,段,包含串常量,全局变量、静态变量的声明和初始化。,.econst,段,包含串常量,全局变量、静态变量的声明和初始化。变量由,far const,修饰,或用大存储器模型,初始化后放进远,(far),存储器。,.switch,段,包含,switch,语句表。,9.2,DSP,C,工程文件,书,P429,C编译器产生的未初始化段有.bss、.ebss 、.stack、.sysmem和 .esysmem段。,.bss段,为全局和静态变量保存空间。,.ebss段,为全局和静态变量保存空间。变量由far 修饰,或用大存储器模型使用。,.stack段,为C系统堆栈。用于保护函数的返回地址、分配局部变量、调用函数时传递参数。,.sysmem段,为动态存储器分配保存空间, malloc函数使用。,.esysmem段,为动态存储器分配保存空间,far malloc函数使用。,9.2,DSP,C,工程文件,初始化段链接,段名称,描述,限制,.text,可执行代码和常量,程序,.cint,已初始化的全局与静态变量的,C,初始化记录,低,64K,数据,.pint,全局构造器,(C+ constructor),表,程序,.switch,实现,switch,语句表,程序,/,低,64K,数据,.const,已初始化的全局与静态,const,修饰变量,串常量,低,64K,数据,.econst,far costant,变量,数据任何位置,9.2,DSP,C,工程文件,未初始化段链接,段名称,内容,限制,.bss,全局与静态变量,低,64K,数据,.ebss,far,全局与静态变量,数据任何位置,.stack,堆栈空间,低,64K,数据,.sysmem,malloc,函数存储区,低,64K,数据,.esysmem,far malloc,函数存储区,数据任何位置,9.2,DSP,C,工程文件,存储器映射表,段,(Section),存储器类型,(Type of Memory),页面,(Page),.text,ROM,或,RAM,0,.cint,ROM,或,RAM,0,.pint,ROM,或,RAM,0,.switch,ROM,或,RAM,0,1,.const,ROM,或,RAM,1,.econst,ROM,或,RAM,1,.bss,RAM,1,.ebss,RAM,1,.stack,RAM,1,.sysmem,RAM,1,.esysmem,RAM,1,MEMORY,和,SECTIONS,伪指令,通常需要建立一个链接命令文件,在,cmd,文件中,有,2,条伪指令支持链接器对段的处理。,在链接器命令文件中,可使用,MEMORY,和,SECTIONS,伪指令。,为实际应用指定存储器结构和地址的映射。,定义存储器和配置段地址。,9.2,DSP,C,工程文件,书,430,MEMORY伪指令用来定义目标系统的存储器配置空间,包括对存储器各局部命名,以及规定它们的起始地址和长度。,SECTIONS伪指令该命令告诉链接器如何将输入段进行组合以及在存储器何处存放组合后的输出模块。,MEMORY 用来指定目标存储器结构。,SECTIONS 用来控制段的构成与地址分配。,9.2,DSP,C,工程文件,MEMORY,命令,MEMORY,命令定义目标系统中可以使用的存储器范围,每个存储器范围具有名字、起始地址和长度。一般形式为,MEMORY,PAGE 0,:,name: origin=constant, length=constant;,PAGE n,:,name: origin=constant, length=constant;,name,:存储器范围名字。可以是,18,个字符。,origin,或简写为,o,:存储器范围的起始地址。,length,或简写为,l,:存储器范围的长度。,PAGE:,指定存储器空间页面,最多为255页,,取决于目标存储器的配置。,每一个,PAGE,代表一个完全独立的地址空间。,通常,,PAGE 0,用于程序存储器;,PAGE 1,用于数据存储器。,MEMORY,指令,9.2,DSP,C,工程文件,SECTIONS,命令,SECTIONS,命令用于将输出各段定位到所定义的存储器,。,一般,形式为,SECTIONS,name: property, property, ,name: property, property, ,9.2,DSP,C,工程文件,SECTIONS,指令的句法:,SECTIONS,name:property,property,property,name:property,property,property,name:property,property,property,指令字,输出段,说明语句,段名:,定义输出段的名称。,属性,:,定义该段的内容和存储器的分配。,段名,SECTIONS,指令语法,属性,属性,属性,9.2,DSP,C,工程文件,例如:,.text: load=0x1000,.,text: loadROM,.,text: align=0x80,.,text: PAGE 0,将.,text,段定位到一个特定的地址。,将.,text,段定位到命名为,ROM,存储区。,将,.,text,段定位到从地址0,x80,开始。,将.,text,段定位到,PAGE 0。,SECTIONS,指令语法,SECTIONS,指令,9.2,DSP,C,工程文件,MEMORY,PAGE 0 :,PRAMH0 : origin = 0x3f8000, length = 0x001000,PAGE 1 :,/* SARAM */,RAMM0 : origin = 0x000000, length = 0x000400,RAMM1 : origin = 0x000400, length = 0x000400,/* Peripheral Frame 0: */,DEV_EMU : origin = 0x000880, length = 0x000180,FLASH_REGS : origin = 0x000A80, length = 0x000060,CSM : origin = 0x000AE0, length = 0x000010,XINTF : origin = 0x000B20, length = 0x000020,CPU_TIMER0 : origin = 0x000C00, length = 0x000008,CPU_TIMER1 : origin = 0x000C08, length = 0x000008,CPU_TIMER2 : origin = 0x000C10, length = 0x000008,PIE_CTRL : origin = 0x000CE0, length = 0x000020,PIE_VECT : origin = 0x000D00, length = 0x000100,9.2,DSP,C,工程文件,合众达,cputimer,工程,书,431,/* Peripheral Frame 1: */,ECAN_A : origin = 0x006000, length = 0x000100,ECAN_AMBOX : origin = 0x006100, length = 0x000100,/* Peripheral Frame 2: */,SYSTEM : origin = 0x007010, length = 0x000020,SPI_A : origin = 0x007040, length = 0x000010,SCI_A : origin = 0x007050, length = 0x000010,XINTRUPT : origin = 0x007070, length = 0x000010,GPIOMUX : origin = 0x0070C0, length = 0x000020,GPIODAT : origin = 0x0070E0, length = 0x000020,ADC : origin = 0x007100, length = 0x000020,EV_A : origin = 0x007400, length = 0x000040,EV_B : origin = 0x007500, length = 0x000040,SPI_B : origin = 0x007740, length = 0x000010,SCI_B : origin = 0x007750, length = 0x000010,MCBSP_A : origin = 0x007800, length = 0x000040,/* CSM Password Locations */,CSM_PWL : origin = 0x3F7FF8, length = 0x000008,/* SARAM,*/,DRAMH0 : origin = 0x3f9000, length = 0x001000,SECTIONS,/* Allocate program areas: */,.reset : PRAMH0,PAGE = 0,.text : PRAMH0, PAGE = 0,.cinit : PRAMH0, PAGE = 0,/* Allocate data areas: */,.stack : RAMM1, PAGE = 1,.bss : DRAMH0,PAGE = 1,.ebss : DRAMH0, PAGE = 1,.const : DRAMH0, PAGE = 1,.econst : DRAMH0, PAGE = 1,.sysmem : DRAMH0, PAGE = 1,将,H0,分为程序存储器和数据存储器,/* Allocate Peripheral Frame 0 Register Structures: */,DevEmuRegsFile : DEV_EMU, PAGE = 1,FlashRegsFile : FLASH_REGS, PAGE = 1,CsmRegsFile : CSM, PAGE = 1,XintfRegsFile : XINTF, PAGE = 1,CpuTimer0RegsFile : CPU_TIMER0, PAGE = 1,CpuTimer1RegsFile : CPU_TIMER1, PAGE = 1,CpuTimer2RegsFile : CPU_TIMER2, PAGE = 1,PieCtrlRegsFile : PIE_CTRL, PAGE = 1,PieVectTable : PIE_VECT, PAGE = 1,/* Allocate Peripheral Frame 2 Register Structures: */,ECanaRegsFile : ECAN_A, PAGE = 1,ECanaMboxesFile : ECAN_AMBOX PAGE = 1,/* Allocate Peripheral Frame 1 Register Structures: */,SysCtrlRegsFile : SYSTEM, PAGE = 1,SpiaRegsFile : SPI_A, PAGE = 1,SciaRegsFile : SCI_A, PAGE = 1,XIntruptRegsFile : XINTRUPT, PAGE = 1,GpioMuxRegsFile : GPIOMUX, PAGE = 1,GpioDataRegsFile : GPIODAT PAGE = 1,AdcRegsFile : ADC, PAGE = 1,EvaRegsFile : EV_A, PAGE = 1,EvbRegsFile : EV_B, PAGE = 1,ScibRegsFile : SCI_B, PAGE = 1,McbspaRegsFile : MCBSP_A, PAGE = 1,/* CSM Password Locations */,CsmPwlFile : CSM_PWL, PAGE = 1,9.3 DSP C语言程序设计根底,9.3.1 数据类型,9.3.2 C语言运算符与根本语句,9.4.3 函数,9.4.4 指针,9.4.5 编译预处理命令,9.4.6 C语言与汇编语言混合编程,9.4.7 C28x DSP编译器的关键字,C28x DSP,具有优化的,C,编译器,它支持,ANSI C,标准。还具有一些不同于标准,C,的特征。,DSP的根本数据类型如表所示,还具有数组、结构、联合等构造类型数据。,9.3.1,数据类型,9.3 DSP C语言程序设计根底,TMS320C28x C,的数据类型,C28x编译器根本数据类型,片内外设存放器通常通过结构与联合变量的方法进行访问。,1.,结构,例如,GPIO A口的MUX复用控制存放器可用位段结构表示,struct,GPAMUX_BITS ,unsigned int,PWM1_GPIOA0:1;/,第,0,位,unsigned int PWM2_GPIOA1:1;/unsigned int C2TRIP_GPIOA14:1;/unsigned int C3TRIP_GPIOA15:1;/,第,15,位,;,9.3.3,结构与联合,例如,GPIO D口的MUX复用控制存放器结构,struct GPDMUX_BITS unsigned int T1CTRIP_PDPA_GPIOD0:1;/第0位unsigned int T2CTRIP_PDPA_GPIOD1:1;/1unsigned int rsvd1:3;/4:2,保存unsigned int T3CTRIP_PDPA_GPIOD5:1;/5unsigned int T4CTRIP_PDPA_GPIOD6:1;/6unsigned int rsvd2:9;/15:7,保存;,当一个结构中有效字段位段的长度缺乏16位时,可以参加保存字段,以保证数据的完整性。,结构变量的定义与成员变量的引用,例如,,struct GPDMUX_BITS bit; /bit,为,GPDMUX_BITS,类型变量,bit.,T1CTRIP_PDPA_GPIOD0=1,联合体类型,可以将不同类型的数据存放在同一个地方,且占据同样大小的存储空间。,例如,定义联合体类型,GPDMUX_REG,,,union,GPDMUX_REG ,unsigned int,all;/all,为无符号整型变量,struct GPDMUX_BITS bit; /bit,为结构型变量,;,联合变量的定义与成员变量的引用,例如,,union GPDMUX_REG GPDMUX;,/GPDMUX,为联合类型变量,GPDMUX.all=1,;,/,将,D0,引脚定义为外设功能,其他为数字,I/O,2.,联合,9.3.3,结构与联合,联合可以出现在结构和数组中,结构和数组也可以出现在联合中。例如,结构类型,GPIO_MUX_REGS,,,struct GPIO_MUX_REGS union GPAMUX_REG GPAMUX;union GPDMUX_REG GPDMUX; ;,9.3.3,结构与联合,结构变量的定义与成员变量的引用,例如,,struct GPIO_MUX_REGS GpioMuxRegs;/,表示,GpioMuxRegs,是结构,GPIO_MUX_REGS,的一个变量。,可以采用点运算符的方法引用各成员变量;,GpioMuxRegs.,GPA,MUX.all=0x077F; /CAP1-3, PWM1-6,T1PWM,GpioMuxRegs.GPDMUX.bit.T1CTRIP_PDPA_GPIOD0=1; /,PDPINTA,GpioMuxRegs.GPDMUX.bit.T2CTRIP_SOCA_GPIOD1=,0,; /GPIOD1 GpioMuxRegs.GPDMUX.bit.T3CTRIP_PDPB_GPIOD5=,0;,/GPIOD5 GpioMuxRegs.GPDMUX.bit.T4CTRIP_SOCB_GPIOD6=,0,; /GPIOD6,例如:定义,GPIO A,口时,,采用一,条,C,语句,。定义,GPIO D,口时,采用了,4,条,C,语句。 编程风格可以编程者自己决定。,9.3.3,结构与联合,书,P437,与普通的C语言程序类似,DSP C程序是由假设干模块化的函数构成。函数是C程序的根本模块,子程序就是由函数来实现的。,用户可以根据需要定义自己的功能函数,也可以调用C编译器提供的标准函数库函数来完成某种特定的功能。,1,函数,9.3.4,函数与指针,C函数的一般格式为,类型函数名形式参数及其类型表,变量声明局部;,执行语句局部;,一个函数在程序中可以三种形态出现:函数定义Definition、函数调用和函数声明Declaration。函数定义相当于汇编语言中的一般子程序。函数调用相当于调用子程序。函数定义和函数调用不分先后,但假设调用在定义之前,那么在调用前必须先进行函数声明。函数声明是一个没有函数体的函数定义,而函数调用那么要求有函数名和实际参数表。,可以用指针的方法访问变量,用指针访问数组、结构、联合变量非常方便。,2,指针,例如,指向结构类型的指针变量,p,struct,GPDMUX_BITS *p;,struct,GPDMUX_BITS bit; p= bit,的成员,T1CTRIP_PDPA_GPIOD0,可用下述,3,种形式之一访问,bit.T1CTRIP_PDPA_GPIOD0 (*p). T1CTRIP_PDPA_GPIOD0 p-T1CTRIP_PDPA_GPIOD0,9.3.4,函数与指针,ANSI C,新标准,增加了一种,void *,指针类型,,即可以定义一个指针变量,但不指定它是指向哪一种数据类型,例,unsigned long,*,Source=(void*),地址,&PieVectTableInit,被,(void*),强制成了,void *,类型。指针,Source,为,unsigned long,类型。,例如,描述中断矢量表的指针,PINT,typedef,unsigned int,Unit16;/,定义一种类型,Uint16,Uint16 i;,typedef interrupt void (*PINT)(void); /,指针,PINT,指向中断函数,struct PIE_VECT_TABLE,PINT PIE1_RESERVED;,PINT PIE2_RESERVED;,C语言用指针访问数据存储器或片内外设存放器可以用指针方法实现。,从扩展的外设接口读取开关状态,然后输出到扩展的指示灯外设接口。,#define LBDS (*(unsigned int *)0xc0000) /扩展的外设存放器,指示灯,#define DIPS (*(unsigned int *)0xc0001) /扩展的外设存放器,开关,LBDS=DIPS;/读取拨码开关状态直接送指示灯显示,9.3.4,函数与指针,main( ),int,i;,unsigned int,* px, * py, * pz;,px=(unsigned int *)0x80000;,py=(unsigned int *)0x80100;,for ( i=0,pz=px;i16;i+,pz+ ),(*pz)=i,; /0x800000x8000F,单元赋值,015,for ( i=0,pz=py;i16;i+,pz+ ),(*pz)=0x1234;,/0x801000x8010F,单元赋值,0x1234,for ( i=0;i16;i+,px+,py+ ),(*py)=(*px);,/0x80000,开始的,16,个单元内容复制到,0x8010F,单元,while(1) ;,例:,将数据存储器,80000H,开始的,16,个单元复制到,80100H,开始的单元。,例: 扩展外部接口, 编写C程序将4个开关状态反响到4个指示灯。,#include DSP281x_Device.h / DSP281x Head file Include File,/ 定义指示灯控制存放器地址和存放器类型,#define LBDS (*(unsigned int *)0xc0000),/ 定义拨码开关控制存放器地址和存放器类型,#define DIPS (*(unsigned int *)0xc0001),main( ),InitSysCtrl();/初始化DSP时钟, 自定义函数,while ( 1 ),LBDS=DIPS;/读取拨码开关状态直接送指示灯显示,1. 宏定义 #define,#define Uint16 unsigned int,#define EINT asm(“ clrc INTM),#define EALLOW asm(“ EALLOW),2. 文件包含#include,#include ,#include “DSP281x_Device.h,9.3.5,宏定义、文件包含与条件编译,3.,条件,编译,#ifdef,标识符,程序段,1,#else,程序段,2,#endif,9.3.5,宏定义、文件包含与条件编译,通过#pragma可以定义自己的段。#pragma的语法格式如下所示。,# pragma CODE_SECTION(symbol,“section name);,# pragma DATA_SECTION(symbol,“section name);,1symbol是符号,可以是函数名或全局变量名。section name是用户自己定义的段名。,9.3.6 pragma,命令,9.3.6 pragma,命令,2CODE_SECTION用来定义代码段,DATA_SECTION用来定义数据段。,3不能在函数体内声明# pragma,必须在符号被定义和使用前使用# pragma。通过pragma伪指令告诉编译器如何对待特定的函数、对象或代码段。,如果需要代码链接到与.text不同的段,那么CODE_SECTION很有用。,1 CODE_SECTION 代码段,它为函数func在一个名为section name 的段(section)中指定空间。将一个代码对象连接到一个不同于.text段的空间时;该语法非常有用。,例,char bufferA80;,#pragma CODE_SECTION(funA, “codeA),char funA(int i);,void main( ), char c;,c=funA(1);,char funA(int i),return bufferAi ;,9.3.6 pragma,命令,2DATA_SECTION 数据段,它为符号symbol在一个名为section name 的段中指定空间。将一个数据对象连接到一个不同于.bss段的空间时;该语法非常有用。,例,#pragma DATA_SECTION(bufferB, “my_sect),char bufferB512;,数据块bufferB被定位于my_sect段中, my_sect段在 d文件中规定物理地址。,9.3.6 pragma,命令,在,C,程序中直接嵌入汇编语句。,独立的,C,模块和汇编模块接口。,独立编写,C,程序与汇编程序,分别编译、汇编生成目标代码模块,然后用连接器连接起来。,从,C,程序中访问汇编程序变量。,9.3.7 C,语言与汇编语言混合编程,在,C,程序中直接嵌入汇编语句,C程序嵌入汇编语句是一种直接的C模块和汇编模块接口方法。,可以在C程序中实现用C语言难以实现的一些硬件控制功能。,用这种方法在C程序中的关键局部用汇编语句代替C语句以优化程序。,缺点是比较容易破坏C环境,因为C编译器在编译嵌入了汇编语句的C程序时并不检查或分析所嵌入的汇编语句。,9.3.7 C,语言与汇编语言混合编程,1.,在,C,程序中直接嵌入汇编语句,直接在C语言程序中相应位置嵌入汇编语句,只需在汇编语句加上双引号和小括号,前面加asm标识符号,双引号内第一个字符应是空格。,即 asm 汇编语句,#define EINT asm( clrc INTM) /使能全局中断,#define DINT asm( setc INTM) /禁止全局中断,#define EALLOWasm( EALLOW) /解除存放器保护,#define EDIS asm( EDIS) /使能存放器保护,#define NOP asm( NOP ) /空操作,书,P441,9.3.7 C,语言与汇编语言混合编程,9.3.7 C,语言与汇编语言混合编程,C,语言与汇编语言混合编程,例:,1.,文件如下所示。,#include ,void main(),int a=10;,int b=10;,int sum;,addasm();,sum=add(a,b);,for(;);,9.3.7 C,语言与汇编语言混合编程,add(int add1,int add2),int c;,c=add1+add2;,return c;,9.3.7 C,语言与汇编语言混合编程,2.,文件如下所示,.fileaddasm.asm,.global _addasm,.text,_addasm:,MOV ACC, #10,MOV T, #2,ADD ACC, T,LRETR,C28x DSP C/C+,编译器,支持标准的,const,、,register,、,volatile,等关键字,还扩展了,cregister,、,interrupt,、,far,、,near,等关键字。,1.,关键字,const,该关键字可以优化存储器的分配。加,const,到任何变量的定义可以,确保其内的值不变。,9.3.8 C28x DSP,编译器关键字,2.,关键字,volatile,该关键字所定义的变量是可变的,,可以被其他硬件修改,,而不仅仅只能由,C,程序修改。优化器会尽量减少存储器的访问,所以有时必须禁止优化,特别是循环控制变量。,例如:,volatile,unsigned int *ctrl;,while(*ctrl != 0xff) ;,/,循环等待,直到,ctrl,地址的内容为,0xff,ctrl,指针所指向的地址不会优化成单次读,可以读取外部事件引起的单元内容的变化。,如果没有关键字,volatile,,,ctrl,指针所指向地址单元的内容在循环过程中不会发生变化,循环被优化成单次读,造成死循环。,9.3.8 C28x DSP,编译器关键字,3. 关键字cregster,该扩展关键字允许高级语言读/写控制存放器。,在F281x C中,cregister仅限于中断使能存放器IER和中断标志存放器IFR,程序中应有如下声明,extern cregister volatile unsigned int IER;,extern cregister volatile unsigned int IFR;,可以用|位或和&(位与)进行操作,例如,IFR|=0x100;,IFR,9.3.8 C28x DSP,编译器关键字,4.,关键字,interrupt,该扩展关键字用来说明函数是一个中断函数。,中断函数被定义成返回,void,类型,而且无参数,调用。,例如:,interrupt,void,int_handler( ),unsigned int flags;,9.3.8 C28x DSP,编译器关键字,#include DSP281x_Device.h / DSP281x Header file Include File,/定义指示灯存放器地址和存放器类型,#define LBDS (*( (unsigned int *)0xc0000) /指定地址的整型变量,void Delay(unsigned int nDelay);/延时子程序,函数声明,main( ),unsigned int
展开阅读全文