2812控制精确的1秒LED闪烁程序.docx

上传人:b****8 文档编号:10196920 上传时间:2023-02-09 格式:DOCX 页数:20 大小:223.31KB
下载 相关 举报
2812控制精确的1秒LED闪烁程序.docx_第1页
第1页 / 共20页
2812控制精确的1秒LED闪烁程序.docx_第2页
第2页 / 共20页
2812控制精确的1秒LED闪烁程序.docx_第3页
第3页 / 共20页
2812控制精确的1秒LED闪烁程序.docx_第4页
第4页 / 共20页
2812控制精确的1秒LED闪烁程序.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

2812控制精确的1秒LED闪烁程序.docx

《2812控制精确的1秒LED闪烁程序.docx》由会员分享,可在线阅读,更多相关《2812控制精确的1秒LED闪烁程序.docx(20页珍藏版)》请在冰豆网上搜索。

2812控制精确的1秒LED闪烁程序.docx

2812控制精确的1秒LED闪烁程序

第一个精确的1秒LED闪烁程序

1   程序特点

本程序使用F2812硬件,控制GPIOF14管脚上的一个LED做精确的1秒间隔闪烁,并且程序从Flash启动。

2   建立工程

2.1   文件

该工程包含以下文件:

注:

除了Main.c为自己写的之外,其他均为F2812DEMO自带的文件。

其中部分文件做了小小的修改,下文会详述

2.2建立工程

打开CCS3.1,选择Project—>New…,输入工程名,这里是MyFirstPjt,选择工程目录后点击确定,然后在左侧的工程管理窗口中选中MyFirstPjt.pjt,右键—>添加文件,将下列文件加入工程:

然后再次选中MyFirstPjt.pjt,右键—>ScanAllFileDependencies,CCS系统会自动搜索关联的文件,特别是.h头文件,并将所有.h头文件显示出来,如下图所示:

如果你看不到,请点击+号展开文件列表。

但注意此时并没有完成,还需要设置编译环境:

在左侧的工程管理窗口中选中MyFirstPjt.pjt,右键—>BulidOptions…做如下设置:

很关键的一个设置是必须设置头文件的搜索路径,CCS在编译时先搜索安装目录下的头文件,然后再搜索用户指定的路径,如果再找不到,就报错。

头文件的搜索路径设置如下:

其中$(Proj_dir)表示工程所在的目录,这里设置为“$(Proj_dir)\DSP281x_headers\include,$(Proj_dir)\DSP281x_common\include”多个路径中间用逗号隔开。

当然也可以设置绝对路径,但这样设置方便一些,便于在工程拷贝中不用再更改设置。

然后设置库和库的搜索路径:

这里使用了CCS3.1自带的库rts2800_ml.lib,该库位于CCS安装目录的C2000\cgtools\lib下,此库中带有bootloader的obj文件,以便于与用户的应用程序连接,大信号模式下用rts2800_ml.lib,小信号模式下用rts2800.lib。

2.3  编译

略,与众多IDE相似。

2.4  下载

首先确保安装了F2812的Flash烧写插件和仿真器的驱动,硬件连接好后,按CTRL+ALT+R以RESET仿真器,按ALT+C连接DSP和PC,点击CCS上的Tools下的F28xxOn-ChipFlashProgrammer即可下载。

具体步骤从略。

2.5   运行

断开仿真器,上电即可运行。

具体从略。

 

3    程序详解

3.1   Main.c

#include"DSP281x_Device.h"//DSP281xHeaderfileIncludeFile

#include"DSP281x_Examples.h"//DSP281xExamplesIncludeFile

#include"DSP281x_Gpio.h"//////

#include"DSP281x_XIntrupt.h"//////

externvoidDSP28x_usDelay(Uint32time);

voidmain(void)

{

InitSysCtrl();

DisableDog();

MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);

InitGpio();//初始化pio,gpiof14为输出

DINT;

IER=0x0000;

IFR=0x0000;

InitPieCtrl();

InitPieVectTable();//初始化中断向量表

for(;;)

{

GpioDataRegs.GPFTOGGLE.bit.GPIOF14=1;//gpiof14输出值翻转

DELAY_US(0xF4240);//DelayOnesecond

}

}

其中:

InitSysCtrl()主要用来配置DSP的时钟频率,该函数在DSP281x_SysCtrl.c文件中;

DisableDog()关闭看门狗,函数也在DSP281x_SysCtrl.c中;

MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart)这一句用来将将Flash中的DSP28x_usDelay()函数调入RAM中运行,下面将详解。

3.2  闪烁LED的实现

本工程的LED接到GPIOF14的管脚上,使用GPIO来控制LED的亮灭。

InitGpio()用来初始化GPIO,函数原型在Gpio.c中:

voidInitGpio(void)

{

//SetGPIOAportpins,AL(Bits7:

0)(input)-AH(Bits15:

8)(output)8bits

//InputQualifier=0,none

EALLOW;

GpioMuxRegs.GPFMUX.bit.XF_GPIOF14=0;//将/XPLLDIS配置为I/O

GpioMuxRegs.GPFDIR.bit.GPIOF14=1;//配置为output

EDIS;

}

其它的语句:

DINT;

IER=0x0000;

IFR=0x0000;

InitPieCtrl();

InitPieVectTable();//初始化中断向量表

可要可不要,作用从略。

GpioDataRegs.GPFTOGGLE.bit.GPIOF14=1;//gpiof14输出值翻转

语句的作用是将gpiof14的管脚电平取反,达到控制LED闪烁的目的。

3.3将Flash中的程序DSP28x_usDelay()调入RAM中运行

本程序为了实现精确的定时,使用了一个用汇编编写的延时函数DSP28x_usDelay(),该函数在文件DSP281x_usDelay.asm中,细节请阅读该文件。

为了调用该函数,在Main.c中做了如下声明:

externvoidDSP28x_usDelay(Uint32time);

该函数的定时仍然不够精确,因此在文件DSP281x_Examples.h中做了如下的宏定义修正:

#defineDELAY_US(A)DSP28x_usDelay(((((longdouble)A*1000.0L)/(longdouble)CPU_RATE)-9.0L)/5.0L)

函数DSP28x_usDelay(Uint32time)要想非常精确,必须在SARAM中运行,因此需要在运行时将其调入SARAM中。

为此,需要做如下工作:

首先,在DSP281x_usDelay.asm中使用

.sect"ramfuncs"

将该段代码定义到段“ramfuncs”中,段ramfuncs的位置在编译时指定,实际上由F2812.cmd文件中的如下语句来指定:

ramfuncsLOAD=FLASHD,PAGE=0,

RUN=RAML0,PAGE=1,

LOAD_START(_RamfuncsLoadStart),

LOAD_END(_RamfuncsLoadEnd),

RUN_START(_RamfuncsRunStart)

第1行表示该段的装载在PAGA0的FLASHD中(PAGA0和FLASHD的分段请见F2812.cmd文件,后文将有详解);

第2行表示该段的运行地址在PAGE1的RAML0中(PAGA1和RAML0的分段请见F2812.cmd文件,后文将有详解);

LOAD_START(_RamfuncsLoadStart)令编译器创建了一个变量RamfuncsLoadStart,该变量指向段ramfuncs的装载地址的首地址(LOAD_START为编译伪指令,请见CCS的帮助文档);

LOAD_START(_RamfuncsLoadEnd)令编译器创建了一个变量RamfuncsLoadEnd,该变量指向段ramfuncs的装载地址的末地址(LOAD_END为编译伪指令,请见CCS的帮助文档);

LOAD_START(_RamfuncsRunStart)令编译器创建了一个变量RamfuncsRunStart,该变量指向段ramfuncs的运行地址的首地址(LOAD_START为编译伪指令,请见CCS的帮助文档);

从第1和2行可以看出,段ramfuncs中的函数DSP28x_usDelay()的装载地址和运行地址是不同的,本程序中装载在Flash的块FLASHD中,而在SARAML0中运行,这只是目标,实际运行时DSP并会自动将Flash中的代码拷贝到SARAM中,因此需要手动添加代码来完成。

在C函数中,为了使用变量RamfuncsLoadStart、RamfuncsLoadEnd和RamfuncsRunStart,必须先声明,本工程在文件DSP281x_GlobalPrototypes.h中做了如下声明:

externUint16RamfuncsLoadStart;

externUint16RamfuncsLoadEnd;

externUint16RamfuncsRunStart;

然后就可以使用了。

在Main.c中,使用MemCopy()函数将段ramfuncs中的函数DSP28x_usDelay()的代码从装载地址RamfuncsLoadStart—RamfuncsLoadEnd拷贝到RamfuncsRunStart开始的SARAM空间中。

之后在程序运行时,只要调用DSP28x_usDelay()函数,都会自动地指向SARAM中相应的函数入口地址,这一点是自动完成的。

MemCopy()函数原型在MemCopy.c中,在DSP281x_GlobalPrototypes.h声明。

注意:

即使这样,定时仍然可能不精确,因为可能有中断打断DSP28x_usDelay()的运行,所以在调用之前要关中断。

4     如何从Flash启动

4.1   F2812的BootLoader工作原理

要让程序从Flash中启动,必须用到DSP的BootLoader。

那么什么是BootLoader呢?

      F2812内部有一块ROM,称为On-ChipROM,其结构如图所示:

从地址0x3FF000到0x3FFB50固化的是集中数学运算表(F2812内部地址是统一编址,寄存器、外设、ROM、RAM地址不重叠),包括正弦和余弦表,可以通过CCS的View—>Graph—>Image绘制出一个漂亮的1.25个正弦波形。

从0x3FFC00到0x3FFFC0固化的有BootLoader的程序,以及版本号、校验等信息。

详情请参考TI的“TMS320x281xDSPBootROMReferenceGuide(SPRU095B)”。

从0x3FFFC0到0x3FFFFF装载的是复位向量和CPU中断向量。

这些向量的映射在Debug模式下会映射到不同的位置,详情请参考TI的“TMS320x281xDSPBootROMReferenceGuide(SPRU095B)”。

那么DSPF2812从上电到启动过程中到底做了哪些工作?

1.      上电复位时,上电运行BootLoader根据MP/MC引脚的状态决定是从片外的3fffc0处(XINTFZone7)读取复位向量或者是从片内的OnChiprom的3fffc0处读取复位向量。

MC方式下从片内读取,MP方式下从片外读取。

复位向量位置见文件F2812.cmd中的PAGE0:

RESET:

origin=0x3FFFC0,length=0x000002

以及:

.reset:

>RESET,PAGE=0,TYPE=DSECT

2.      一般我们用的是MC方式,即从片内读取复位向量,在片内的rom3fffc0处有一个向量指向了一个程序InitBoot。

实际上该函数就从地址3fffc0开始。

复位后处理器从3fffc0处读取3ffc00这个地址,所以InitBoot程序从3ffc00处开始执行。

3.      3ffc00处开始的就是initboot过程。

首先根据IO管脚的状态判断该进入那一种引导方式,引导方式有:

4.      然后根据不同的引导方式来引导程序:

在SCITXA引脚为高电平时就是flashboot方式。

其它的方式还需要用户编写引导代码,详情见TI的“TMS320x281xDSPBootROMReferenceGuide(SPRU095B)”。

5.      然后调用ExitBoot函数,来配置硬件,设置寄存器等的初始值,设置运行环境等。

随后,此时置PC=3F7FF6(内部Flash引导模式时)。

因此地址0x3F7FF6是用户程序的入口,见F2812.cmd中:

BEGIN:

origin=0x3F7FF6,length=0x000002

codestart:

>BEGINPAGE=0

6.      在片内flash的3F7FF6和3F7FF7处一般会放有一个跳转指令。

本工程中,由一段代码来完成,见文件DSP281x_CodeStartBranch.asm:

作用是先关闭看门狗,然后跳转到c_int00,即LB_c_int00。

更具根据上文,DSP281x_CodeStartBranch.asm的代码必须从0x3F7FF6开始,所以程序中有这么一句:

.sect"codestart"

7.      执行这个跳转指令后程序就开始运行c_int00这个函数了,这个函数在rts的库中。

见CCS的安装目录下的C2000\cgtools\lib\rts.src。

实际上c_int00执行的是boot.asm,

8.      这个函数就是建立一个c程序的运行环境,等建立完c运行环境后c_int00调用main函数,详情见TI的“TMS320x281xDSPBootROMReferenceGuide(SPRU095B)”中的BootLoader的源代码。

C_int00可以看作是c程序的Main函数入口。

9.      main函数开始就是我们自己编写的应用程序了。

实际上,如果想让程序从Flash中启动,只要硬件配置正确,软件上只要将代码段.text定位到Flash中即可,剩下的全部由编译器自动完成。

关键是撰写正确的.cmd文件。

5     CMD文件详解

5.1   DSP281x_Headers_nonBIOS.cmd

该文件是为硬件的各种寄存器映射存储器地址分页和分配空间地址,一般是固定的,用户无权改动也不必改动,该文件适合在没有使用操作系统BIOS时使用。

使用时不必改动。

MEMORY

{

PAGE0:

/*ProgramMemory*/

PAGE1:

/*DataMemory*/

DEV_EMU:

origin=0x000880,length=0x000180/*deviceemulationregisters*/

PIE_VECT:

origin=0x000D00,length=0x000100/*PIEVectorTable*/

FLASH_REGS:

origin=0x000A80,length=0x000060/*FLASHregisters*/

CSM:

origin=0x000AE0,length=0x000010/*codesecuritymoduleregisters*/

XINTF:

origin=0x000B20,length=0x000020/*externalinterfaceregisters*/

CPU_TIMER0:

origin=0x000C00,length=0x000008/*CPUTimer0registers(CPUTimer1andTimer2arereservedforBIOS)*/

PIE_CTRL:

origin=0x000CE0,length=0x000020/*PIEcontrolregisters*/

ECANA:

origin=0x006000,length=0x000040/*eCANcontrolandstatusregisters*/

ECANA_LAM:

origin=0x006040,length=0x000040/*eCANlocalacceptancemasks*/

ECANA_MOTS:

origin=0x006080,length=0x000040/*eCANmessageobjecttimestamps*/

ECANA_MOTO:

origin=0x0060C0,length=0x000040/*eCANobjecttime-outregisters*/

ECANA_MBOX:

origin=0x006100,length=0x000100/*eCANmailboxes*/

SYSTEM:

origin=0x007010,length=0x000020/*Systemcontrolregisters*/

SPIA:

origin=0x007040,length=0x000010/*SPIregisters*/

SCIA:

origin=0x007050,length=0x000010/*SCI-Aregisters*/

XINTRUPT:

origin=0x007070,length=0x000010/*externalinterruptregisters*/

GPIOMUX:

origin=0x0070C0,length=0x000020/*GPIOmuxregisters*/

GPIODAT:

origin=0x0070E0,length=0x000020/*GPIOdataregisters*/

ADC:

origin=0x007100,length=0x000020/*ADCregisters*/

EVA:

origin=0x007400,length=0x000040/*EventManagerAregisters*/

EVB:

origin=0x007500,length=0x000040/*EventManagerBregisters*/

SCIB:

origin=0x007750,length=0x000010/*SCI-Bregisters*/

MCBSPA:

origin=0x007800,length=0x000040/*McBSPregisters*/

CSM_PWL:

origin=0x3F7FF8,length=0x000008/*PartofFLASHA.CSMpasswordlocations.*/

}

SECTIONS

{

PieVectTableFile:

>PIE_VECT,PAGE=1

/***PeripheralFrame0RegisterStructures***/

DevEmuRegsFile:

>DEV_EMU,PAGE=1

FlashRegsFile:

>FLASH_REGS,PAGE=1

CsmRegsFile:

>CSM,PAGE=1

XintfRegsFile:

>XINTF,PAGE=1

CpuTimer0RegsFile:

>CPU_TIMER0,PAGE=1

PieCtrlRegsFile:

>PIE_CTRL,PAGE=1

/***PeripheralFrame1RegisterStructures***/

SysCtrlRegsFile:

>SYSTEM,PAGE=1

SpiaRegsFile:

>SPIA,PAGE=1

SciaRegsFile:

>SCIA,PAGE=1

XIntruptRegsFile:

>XINTRUPT,PAGE=1

GpioMuxRegsFile:

>GPIOMUX,PAGE=1

GpioDataRegsFile:

>GPIODATPAGE=1

AdcRegsFile:

>ADC,PAGE=1

EvaRegsFile:

>EVA,PAGE=1

EvbRegsFile:

>EVB,PAGE=1

ScibRegsFile:

>SCIB,PAGE=1

McbspaRegsFile:

>MCBSPA,PAGE=1

/***PeripheralFrame2RegisterStructures***/

ECanaRegsFile:

>ECANA,PAGE=1

ECanaLAMRegsFile:

>ECANA_LAMPAGE=1

ECanaMboxesFile:

>ECANA_MBOXPAGE=1

ECanaMOTSRegsFile:

>ECANA_MOTSPAGE=1

ECanaMOTORegsFile:

>ECANA_MOTOPAGE=1

/***CodeSecurityModuleRegisterStructures***/

CsmPwlFile:

>CSM_PWL,PAGE=1

}

5.2   F2812.cmd

MEMORY

{

PAGE0:

/*ProgramMemory*/

/*Memory(RAM/FLASH/OTP)blockscanbemovedtoPAGE1fordataallocation*/

ZONE0:

origin=0x002000,length=0x002000/*XINTFzone0*/

ZONE1:

origin=0x004000,length=0x002000/*XINTFzone1*/

RAML0:

origin=0x008000,length=0x001000/*on-chipRAMblockL0*/

ZONE2:

origin=0x080000,length=0x080000/*XINTFzone2*/

ZONE6:

origin=0x100000,length=0x080000/*XINTFzone

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1