2812控制精确的1秒LED闪烁程序.docx
- 文档编号:10196920
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:20
- 大小:223.31KB
2812控制精确的1秒LED闪烁程序.docx
《2812控制精确的1秒LED闪烁程序.docx》由会员分享,可在线阅读,更多相关《2812控制精确的1秒LED闪烁程序.docx(20页珍藏版)》请在冰豆网上搜索。
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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2812 控制 精确 LED 闪烁 程序