2812功能单元使用

更新时间:2023-10-31 02:48:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第3章 TMS320X28xx处理器及其应用

例1、初始化锁相环及外设时钟函数

//--------------------------------------------------------------------------------------------------------------------- // 初始化锁相环及外设时钟函数: InitPll:

//--------------------------------------------------------------------------------------------------------------------- void InitPll(Uint16 val) {

volatile Uint16 iVol;

if (SysCtrlRegs.PLLCR.bit.DIV != val) {

EALLOW;

SysCtrlRegs.PLLCR.bit.DIV = val; EDIS;

// 在锁相环时钟频率切换过程中,只有当锁相环稳定后CPU才会切换到新的PLL设置。因此在设置完PLLCR后需要等待PLL稳定。PLL的切换时间大约等于131072个输入时钟周期。

DisableDog();

for(iVol= 0; iVol< ( (131072/2)/12 ); iVol++) { } } }

// 为降低系统功耗,不使用的外设时钟需要屏蔽。 // 但如果使用外设必须首先使能相应的外设时钟。 void InitPeripheralClocks(void) {

EALLOW;

// HISPCP/LOSPCP预定表寄存器设置 SysCtrlRegs.HISPCP.all = 0x0001; SysCtrlRegs.LOSPCP.all = 0x0002; // 使能使用的外设时钟

SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; SysCtrlRegs.PCLKCR.bit.EVBENCLK=1; SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1; SysCtrlRegs.PCLKCR.bit.SCIBENCLK=1; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=1; SysCtrlRegs.PCLKCR.bit.SPIENCLK=1; SysCtrlRegs.PCLKCR.bit.ECANENCLK=1; SysCtrlRegs.PCLKCR.bit.ADCENCLK=1; EDIS;

1

}

例2、.cmd格式文件举例

MEMORY {

PAGE 0 :

/* 本例中H0分成PAGE 0和PAGE 1

*/

/* BEGIN is used for the \ */ /* 如果从XINTF Zone 7空间boot,RESET装载复位向量, */ /*

其他复位矢量从BOOTROM中装载

*/

RAMM0 : origin = 0x000000, length = 0x000400 BEGIN : origin = 0x3F8000, length = 0x000002 PRAMH0 : origin = 0x3F8002, length = 0x0014FE BOOTROM

: origin = 0x3FF000,

length = 0x000FC0

RESET : origin = 0x3FFFC0,

length = 0x000002

PAGE 1 :

RAMM1 : origin = 0x000400, length = 0x000400 L0L1RAM

: origin = 0x008000, length = 0x002000 DRAMH0

: origin = 0x3f9500,

length = 0x000B00

}

SECTIONS {

/* 设置\模式:代码起始段(DSP281x_CodeStartBranch.asm) */ /* 然后重新定位用户代码开始入口。将该段放在H0的起始

*/

codestart : > BEGIN, PAGE = 0 ramfuncs : > PRAMH0 PAGE = 0 .text

: > PRAMH0, PAGE = 0 .cinit : > PRAMH0, PAGE = 0 .pinit

: > PRAMH0, PAGE = 0 .switch

: > RAMM0, PAGE = 0 .reset : > RESET, PAGE = 0, TYPE = DSECT/* 没用 */ .stack

: > RAMM1, PAGE = 1 .ebss : > DRAMH0, PAGE = 1 .econst : > DRAMH0, PAGE = 1 .esysmem

: > DRAMH0, PAGE = 1

DLOG

: >L0L1RAM, PAGE = 1

/********************************************************************/ /*IQmath 函数表定位: */ /********************************************************************/

/* 对于没有BOOTROM的器件使用:

*/

2

/*IQmathTables: load = BOOTROM, PAGE = 0 */ /* F2810/12 器件(Boot ROM内包含相应函数的查表信息) 使用:

*/

IQmathTables: load = BOOTROM, type = NOLOAD, PAGE = 0

/********************************************************************/ /*IQmath 函数定位:

*/

/********************************************************************/

IQmath: load = PRAMH0, PAGE = 0 }

例3、定时器中断应用举例

//============================================================== // 文件名称:Example_281xCpuTimer.c

// 功能描述:采用CPU Timer0定时,在定时器中断服务程序中记录中断的次数。

//

// 观察的变量:

// CpuTimer0.InterruptCount //

//==============================================================

#include \ // DSP281x Headerfile Include File #include \ // DSP281x Examples Include File

// 函数声明

interrupt void cpu_timer0_isr(void);

void main(void) {

// Step 1、初始化系统控制寄存器,PLL,看门狗,时钟位默认状态 // 该函数在后面的DSP28_SysCtrl.c文件中查找 InitSysCtrl();

// Step 2、GPIO初始化 本例中不使用 // InitGpio();

// Step 3、清除所有中断并初始化PIE中断向量表,禁止所有CPU中断 DINT;

// 初始化PIE 控制寄存器为其默认状态(所有PIE中断被禁止并且标志被清除) InitPieCtrl();

// 禁止所有CPU中断并清除所有中断标志

3

IER = 0x0000; IFR = 0x0000;

// 初始化PIE控制寄存器,参考DSP28_PieCtrl.c文件 InitPieVectTable();

// 将本例程所使用的中断向量重新映射,使其指向中断服务相应的程序 EALLOW;

PieVectTable.TINT0 = &cpu_timer0_isr; EDIS;

// Step 4、初始化所有外设(本例中不需要) // InitPeripherals();

InitCpuTimers(); // 在本例程中仅初始化Cpu定时器

// 配置 CPU-Timer 0 每间隔1秒产生一次中断

// 150MHz CPU 频率,周期为1秒 (采用微妙的形式描述) ConfigCpuTimer(&CpuTimer0, 100, 1500000); StartCpuTimer0();

// Step 5.、用户特定代码,使能中断 // 使能连接到CPU-Timer 0的CPU INT1 IER |= M_INT1;

// 使能位于PIE中的组1的第7个中断 TINT0 PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

// 使能全局中断,并配置位real-time debug模式 EINT; // 使能全局中断INTM ERTM;

// 使能全局 realtime 中断DBGM

// Step 6.、IDLE loop等待产生中断 for(;;); }

interrupt void cpu_timer0_isr(void) {

CpuTimer0.InterruptCount++; // 响应中断并准备接收更多的中断

PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }

4

//============================================================== //

// 文件名称:DSP281x_CpuTimers.c //

// 功能描述: DSP281x CPU 32-bit 定时器初始化及相关函数 //

//==============================================================

#include \ // 包含的DSP281x头文件 #include \ // DSP281x Examples 头文件

struct CPUTIMER_VARS CpuTimer0;

// CpuTimer 1 的 CpuTimer2 保留,由DSP BIOS & 其他RTOS使用 //struct CPUTIMER_VARS CpuTimer1; //struct CPUTIMER_VARS CpuTimer2;

//--------------------------------------------------------------------------- // 初始化CPU定时器

//--------------------------------------------------------------------------- // 该函数将3个定时器初始化为一个确定的状态 //

void InitCpuTimers(void) {

// CPU Timer 0 // 初始化各自定时器的寄存器指向相应的地址 CpuTimer0.RegsAddr = &CpuTimer0Regs; // 初始化定时器周期为最大值 CpuTimer0Regs.PRD.all = 0xFFFFFFFF;

// 初始化预定标计数器,分频系数为1 (时钟:SYSCLKOUT) CpuTimer0Regs.TPR.all = 0; CpuTimer0Regs.TPRH.all = 0; // 确认定时器处于停止计数状态 CpuTimer0Regs.TCR.bit.TSS = 1;

// 使用周期寄存器的值装载定时器计数寄存器 CpuTimer0Regs.TCR.bit.TRB = 1; // 复位中断计数标量InterruptCount = 0

CpuTimer0.InterruptCount = 0;

// CpuTimer 1 的 CpuTimer2 为 DSP BIOS & 其他RTOS保留 // 因此相应的定时器初始化代码被注释

// 初始化各自定时器的寄存器指向相应的地址

5

// CpuTimer1.RegsAddr = &CpuTimer1Regs; // CpuTimer2.RegsAddr = &CpuTimer2Regs; // 初始化定时器周期为最大值

// CpuTimer1Regs.PRD.all = 0xFFFFFFFF; // CpuTimer2Regs.PRD.all = 0xFFFFFFFF; // 确认定时器处于停止计数状态

// CpuTimer1Regs.TCR.bit.TSS = 1; // CpuTimer2Regs.TCR.bit.TSS = 1; // 使用周期寄存器的值装载定时器计数寄存器

// CpuTimer1Regs.TCR.bit.TRB = 1; // CpuTimer2Regs.TCR.bit.TRB = 1; // 复位中断计数标量

// CpuTimer1.InterruptCount = 0; // CpuTimer2.InterruptCount = 0; }

//--------------------------------------------------------------------------- // 配置Cpu定时器函数

//--------------------------------------------------------------------------- // 该函数初始化指定定时器的周期和频率

void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period) { Uint32 temp;

// 初始化周期

Timer->CPUFreqInMHz = Freq; Timer->PeriodInUSec = Period; temp = (long) (Freq * Period); Timer->RegsAddr->PRD.all = temp;

//设置预定标参数 (SYSCLKOUT):

Timer->RegsAddr->TPR.all = 0; Timer->RegsAddr->TPRH.all = 0;

// 初始化定时器控制寄存器

Timer->RegsAddr->TCR.bit.TSS = 1; // 1 = Stop timer, 0 = Start/Restart Timer Timer->RegsAddr->TCR.bit.TRB = 1; // 1 = reload timer Timer->RegsAddr->TCR.bit.SOFT = 1;

Timer->RegsAddr->TCR.bit.FREE = 1; // Timer Free Run

Timer->RegsAddr->TCR.bit.TIE = 1; // 0 = Disable/ 1 = Enable Timer Interrupt

//复位中断计数

Timer->InterruptCount = 0;

6

}

例4、利用事件管理器输出多种频率的正弦信号输出例程

//*************************************************************************** //

// 文件名称:EVsine.c //

// 主要功能:DSP28 T1PWM-输出产生正弦波, //

使能看门狗

//

//***************************************************************************

#include \ #include \

#pragma DATA_SECTION(sine_table,\); _iq30 sine_table[512];

// 函数原型声明 void Gpio_select(void); void InitSystem(void);

interrupt void T1_Compare_isr(void); // 定时器1中断服务程序

void main(void) { InitSystem(); // 初始化DSP内核寄存器

Gpio_select(); // 设置GPIO引脚功能

InitPieCtrl(); // 初始化外设中断扩展单元 ( 代码在: DSP281x_PieCtrl.c)

InitPieVectTable();

// 初始化外设中断扩展向量表( 代码在:DSP281x_PieVect.c )

// 重新映射定时器1(Timer 1)的比较中断入口

EALLOW;

// 允许更改保护的寄存器

PieVectTable.T1CINT = &T1_Compare_isr; EDIS; // 禁止更改保护的寄存器

// 使能T1比较中断:PIE-组2,中断5

PieCtrlRegs.PIEIER2.bit.INTx5=1;

// 使能 CPU INT2,GP -Timer1的比较中断连接到该中断 IER = 2;

7

// 全局中断使能,并使能具有更高优先级的适时调试方式 EINT; // 使能全局中断 INTM ERTM; // 使能全局适时中断DBGM

// 配置事件管理器A EVA

// 假定事件管理器A的时钟已经在InitSysCtrl()中使能; // T1/T2逻辑驱动T1PWM / T2PWM ; EvaRegs.GPTCONA.bit.TCMPOE = 1; // GP Timer 1 比较输出配置:低电平有效 EvaRegs.GPTCONA.bit.T1PIN = 1;

EvaRegs.T1CON.bit.FREE = 0; // 仿真操作时挂起 EvaRegs.T1CON.bit.SOFT = 0; // 仿真操作时挂起 EvaRegs.T1CON.bit.TMODE = 2; // 连续递增计数模式 EvaRegs.T1CON.bit.TPS = 0;

// 预定标系数 = 1 : 75 MHz EvaRegs.T1CON.bit.TENABLE = 0; // 禁止GP Timer 1操作 EvaRegs.T1CON.bit.TCLKS10 = 0; // 使用内部时钟 EvaRegs.T1CON.bit.TCLD10 = 0; // 等于0时比较装载 EvaRegs.T1CON.bit.TECMPR = 1;

// 使能比较操作

EvaRegs.T1PR = 1500;

EvaRegs.T1CMPR = EvaRegs.T1PR/2;

EvaRegs.EVAIMRA.bit.T1CINT = 1; EvaRegs.T1CON.bit.TENABLE = 1;

// 使能 GP Timer 1

while(1) {

EALLOW;

SysCtrlRegs.WDKEY = 0xAA;

// 看门狗操作

EDIS; }

}

// 通用IO选择 void Gpio_select(void) { EALLOW;

GpioMuxRegs.GPAMUX.all = 0x0;

// 所有GPIO端口配置成I/O方式

GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6 = 1; // T1PWM有效

GpioMuxRegs.GPBMUX.all = 0x0; GpioMuxRegs.GPDMUX.all = 0x0; GpioMuxRegs.GPFMUX.all = 0x0;

GpioMuxRegs.GPEMUX.all = 0x0;

8

GpioMuxRegs.GPGMUX.all = 0x0;

GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT 作为输入 GpioMuxRegs.GPBDIR.all = 0x0; // GPIO PORT 作为输入 GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT 作为输入 GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT 作为输入 GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 作为输入 GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT 作为输入

GpioMuxRegs.GPAQUAL.all = 0x0;

// 设置GPIO量化值为0

GpioMuxRegs.GPBQUAL.all = 0x0; GpioMuxRegs.GPDQUAL.all = 0x0; GpioMuxRegs.GPEQUAL.all = 0x0; EDIS; }

// 系统初始化

void InitSystem(void) { EALLOW;

SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗

// 0x00E8 禁止看门狗,预定标系数Prescaler = 1

// 0x00AF 使能看门狗,预定标系数Prescaler = 64 SysCtrlRegs.SCSR = 0;

// 看门狗产生RESET SysCtrlRegs.PLLCR.bit.DIV = 10;

// 设置系统锁相环倍频系数5

SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟预定标系数:除以2 SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟预定标系数:除以4

// 使能本应用程序使用的外设时钟 SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; SysCtrlRegs.PCLKCR.bit.EVBENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0; SysCtrlRegs.PCLKCR.bit.SPIENCLK=0; SysCtrlRegs.PCLKCR.bit.ECANENCLK=0; SysCtrlRegs.PCLKCR.bit.ADCENCLK=0; EDIS;

}

// CPU定时器1中断服务子程序

9

interrupt void T1_Compare_isr(void) {

static int index=0;

// 每次定时器中断,清除看门狗定时器计数器t SysCtrlRegs.WDKEY = 0x55; EDIS;

_IQ30mpy(sine_table[index]+_IQ30(0.9999),EvaRegs.T1PR/2),EvaRegs.T1PR,0);

// Serve watchdog #1

EALLOW;

EvaRegs.T1CMPR =EvaRegs.T1PR - _IQsat(

index +=4;

// 查表时间隔4个数据取一个

if (index >511) index = 0;

// 复位定时器1比较中断标志 EvaRegs.EVAIFRA.bit.T1CINT = 1;

// 响应该中断并允许从组2中接收更多的中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; }

//===================================================================== // 代码结束

//=====================================================================

//*************************************************************************** //

// 文件名称: DSP281x_Headers_nonBIOS.cmd //

// 功能描述: DSP281x 外设寄存器连接命令文件 // // // 连接器cmd文件将在dsp28头文件中定义的外设结构体 // 分配到正确的存储器映射空间

// 在不使用DSP/BIOS时,该连接文件包含外设中断向量表PieVectorTable. //

如果使用DSP/BIOS,则不包含外设中断向量表PieVectorTable

//***************************************************************************

MEMORY {

PAGE 0: /* 程序存储空间 */ PAGE 1: /* 数据存储空间 */

DEV_EMU : origin = 0x000880, length = 0x000180 /* 器件仿真寄存器 */ PIE_VECT

: origin = 0x000D00, length = 0x000100 /* PIE 中断向量

*/ FLASH_REGS

: origin = 0x000A80, length = 0x000060

/* FLASH 寄存器

*/

10

CSM

:origin = 0x000AE0,length = 0x000010 :origin = 0x000B20, length = 0x000020 :origin = 0x000C00, length = 0x000008 :origin = 0x000CE0, length = 0x000020 :origin = 0x006000, length = 0x000040 :origin = 0x006040, length = 0x000040 :origin = 0x006080, length = 0x000040 :origin = 0x0060C0, length = 0x000040 /*密码模块寄存器 /*外设接口寄存器

*/ */

XINTF

CPU_TIMER0 PIE_CTRL ECANA

/*CPU定时器0寄存器 /* PIE 控制寄存器 /*eCAN 局部接收屏蔽 /*eCAN消息对象标签 */ */ */ (CPU定时器1和2预留给BIOS)*/

/*eCAN控制和状态寄存器 */

ECANA_LAM ECANA_MOTS ECANA_MOTO /*eCAN 对象超时寄存器 */

ECANA_MBOX :origin = 0x006100, length = 0x000100 /* eCAN邮箱 SYSTEM :origin = 0x007010, length = 0x000020 /*系统控制寄存器 SPIA :origin = 0x007040, length = 0x000010 /* SPI 寄存器 SCIA

:origin = 0x007050, length = 0x000010 /* SCI-A 寄存器

XINTRUPT :origin = 0x007070, length = 0x000010 /* 外部中断寄存器 GPIOMUX :origin = 0x0070C0, length = 0x000020 /* GPIO 复用 寄存器 GPIODAT :origin = 0x0070E0, length = 0x000020 /* GPIO 数据 寄存器 ADC :origin = 0x007100, length = 0x000020 /* ADC 寄存器

EVA :origin = 0x007400, length = 0x000040 /*事件管理器A 寄存器 EVB :origin = 0x007500, length = 0x000040 /*事件管理器B 寄存器 SCIB

:origin = 0x007750, length = 0x000010 /* SCI-B 寄存器

MCBSPA :origin = 0x007800, length = 0x000040 /* McBSP 寄存器 CSM_PWL

:origin = 0x3F7FF8, length = 0x000008

/* FLASHA. CSM密码

}

SECTIONS {

PieVectTableFile : > PIE_VECT, PAGE = 1

/*** 外设振帧 0 寄存器结构定义 ***/

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

/*** 外设振帧 1 寄存器结构定义 ***/ SysCtrlRegsFile : > SYSTEM, PAGE = 1 SpiaRegsFile : > SPIA, PAGE = 1 SciaRegsFile

: > SCIA,

PAGE = 1 XIntruptRegsFile : > XINTRUPT, PAGE = 1 GpioMuxRegsFile

: > GPIOMUX, PAGE = 1 GpioDataRegsFile : > GPIODAT PAGE = 1 AdcRegsFile

: > ADC,

PAGE = 1

*/ */ */ */ */ */ */ */

*/ */ */ */ */

11

EvaRegsFile : > EVA, PAGE = 1 EvbRegsFile : > EVB, PAGE = 1 ScibRegsFile : > SCIB,

PAGE = 1 McbspaRegsFile

: > MCBSPA,

PAGE = 1

/*** 外设振帧 2 寄存器结构定义 ***/ ECanaRegsFile

: > ECANA, PAGE = 1 ECanaLAMRegsFile : > ECANA_LAM PAGE = 1 ECanaMboxesFile : > ECANA_MBOX PAGE = 1 ECanaMOTSRegsFile : > ECANA_MOTS PAGE = 1 ECanaMOTORegsFile : > ECANA_MOTO

PAGE = 1

/*** 安全密码模块结构定义 ***/ CsmPwlFile : > CSM_PWL,

PAGE = 1

}

//*************************************************************************** //

// 文件名称:F2812_EzDSP_RAM_lnk.cmd // 功能描述:连接文件 //

//*************************************************************************** MEMORY { PAGE 0 :

/* 本例中将H0分成PAGE 0 和 PAGE 1两个部分 */ /* BEGIN 用于 \引导模式

*/

/* 当从XINTF Zone 7引导时,RESET装载复位向量; */ /* 否则复位向量从boot ROM装载 */

RAMM0 : origin = 0x000000, length = 0x000400

BEGIN : origin = 0x3F8000, length = 0x000002 PRAMH0 : origin = 0x3F8002, length = 0x000FFE

RESET

: origin = 0x3FFFC0, length = 0x000002

PAGE 1 :

RAMM1 : origin = 0x000400, length = 0x000400

DRAMH0

: origin = 0x3f9000, length = 0x001000 }

SECTIONS

12

{

codestart : > BEGIN, PAGE = 0 ramfuncs : > PRAMH0 PAGE = 0 .text : > PRAMH0, PAGE = 0 .cinit : > PRAMH0, PAGE = 0 .pinit : > PRAMH0, PAGE = 0 .switch : > RAMM0, PAGE = 0 .reset : > RESET,

PAGE = 0, TYPE = DSECT /* 不用 */

.stack : > RAMM1, PAGE = 1 .ebss : > DRAMH0, PAGE = 1 .econst : > DRAMH0, PAGE = 1 .esysmem : > DRAMH0, PAGE = 1 }

//*************************************************************************** //

// 文件名称:EVsin.cmd //

// 功能描述:连接文件定义数据表 //

//***************************************************************************

MEMORY { PAGE 1: /* Data */

ROM : origin = 0x3FF000, length = 0x000400 /* Boot ROM available if MP/MCn=0 */ }

SECTIONS { IQmathTables : > ROM PAGE = 1, TYPE = NOLOAD }

例5、SPI和DAC TLV 5617接口例程

//=========================================================== //

// 文件名称:SPI_DAC5617 //

13

// TITLE: DSP28 SPI - DAC TLV5617A,

// 采用CPU Timer0产生定时周期50ms,输出锯齿波 //

使能看门狗,在主函数中刷新计数器

//

//===========================================================

#include \

// 函数原形声明

void Gpio_select(void); void InitSystem(void); void SPI_Init(void);

void DAC_Update(char channel,int value); interrupt void cpu_timer0_isr(void); // 定时器中断

void main(void) { int Voltage_A = 0;

int Voltage_B = 511;

InitSystem(); // 初始化处理器内核寄存器

Gpio_select();

// 设置IO功能

InitPieCtrl();

// 调用外设中断扩展初始化单元 PIE-unit ( 代码 : DSP281x_PieCtrl.c) InitPieVectTable();

// 初始化 PIE vector向量表 ( 代码 : DSP281x_PieVect.c )

// 重新映射 PIE - Timer 0的中断

EALLOW;

// 解除寄存器保护 PieVectTable.TINT0 = &cpu_timer0_isr; EDIS;

// 使能寄存器保护

InitCpuTimers();

// 配置 CPU-Timer 0 周期50 ms:

// 150MHz CPU 频率, 50000 微妙中断周期

ConfigCpuTimer(&CpuTimer0, 150, 50000);

// 使能PIE内的 TINT0 : Group 1 interrupt 7 PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

// 使能 CPU INT 1 (CPU定时器0中断) IER = 1;

14

// 全局中断使能和更高优先级的实时调试事件 EINT; // 全局中断使能INTM ERTM; // 使能实时调试中断DBGM

CpuTimer0Regs.TCR.bit.TSS = 0;

SPI_Init(); while(1) {

while(CpuTimer0.InterruptCount < 3); // 等待定时中断3次

CpuTimer0.InterruptCount = 0; DAC_Update('B',Voltage_B);

DAC_Update('A',Voltage_A); if (Voltage_A++ > 511) Voltage_A = 0;

if (Voltage_B-- < 0) Voltage_B = 511;

EALLOW;

SysCtrlRegs.WDKEY = 0xAA;

// 看门狗控制

EDIS; } }

void Gpio_select(void) { EALLOW;

GpioMuxRegs.GPAMUX.all = 0x0;

// 所有GPIO引脚配置为I/O

GpioMuxRegs.GPBMUX.all = 0x0; GpioMuxRegs.GPDMUX.all = 0x0;

GpioMuxRegs.GPFMUX.all = 0xF;

GpioMuxRegs.GPEMUX.all = 0x0; GpioMuxRegs.GPGMUX.all = 0x0;

GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPBDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPDDIR.all = 0x0;

// GPIO PORT 配置为输入 GpioMuxRegs.GPDDIR.bit.GPIOD0 = 1; // DAC的/CS使能信号 GpioMuxRegs.GPDDIR.bit.GPIOD6 = 1; // EEPROM的/CS使能信号 GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPGDIR.all = 0x0;

// GPIO PORT 配置为输入 GpioDataRegs.GPBDAT.all = 0x0;

// GPIO PORT 配置为输入 GpioDataRegs.GPDDAT.bit.GPIOD0 = 1;

// DAC的/CS信号处于无效状态

GpioDataRegs.GPDDAT.bit.GPIOD5 = 1; // EEPROM的/CS信号处于无效状态

15

GpioMuxRegs.GPAQUAL.all = 0x0;

// 设置所有 GPIO 输入的量化值等于0

GpioMuxRegs.GPBQUAL.all = 0x0; GpioMuxRegs.GPDQUAL.all = 0x0; GpioMuxRegs.GPEQUAL.all = 0x0; EDIS; }

void InitSystem(void) {

EALLOW;

SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗

// 0x00E8 禁止看门狗,预定标系数Prescaler = 1

// 0x00AF 不禁止看门狗, 预定标系数Prescaler = 64 SysCtrlRegs.SCSR = 0;

// 看门狗产生复位

SysCtrlRegs.PLLCR.bit.DIV = 10; // 配置处理器锁相环,倍频系数为5

SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟分频系数: 2 SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟分频系数: 4

// 使用的外设时钟时钟设置:

// 一般不使用的外设的时钟禁止,降低系统功耗 SysCtrlRegs.PCLKCR.bit.EVAENCLK=0; SysCtrlRegs.PCLKCR.bit.EVBENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0; SysCtrlRegs.PCLKCR.bit.SPIENCLK=1; //使能SPI时钟

SysCtrlRegs.PCLKCR.bit.ECANENCLK=0; SysCtrlRegs.PCLKCR.bit.ADCENCLK=0; EDIS; }

interrupt void cpu_timer0_isr(void) {

CpuTimer0.InterruptCount++;

// 每个定时器中断清除一次看门狗计数器 EALLOW; SysCtrlRegs.WDKEY = 0x55;

// 看门狗控制

EDIS;

16

// 响应中断并允许系统接收更多的中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }

void SPI_Init(void) { }

void DAC_Update(char channel, int value) { }

//===================================================================== // 代码结束

//=====================================================================

int i;

GpioDataRegs.GPDDAT.bit.GPIOD0 = 0; if (channel == 'B')

SpiaRegs.SPITXBUF = 0x1000 + (value<<2);

// 发送数据到DAC缓冲

// 将数据传送到DAC-A并刷新DAC-B的缓冲 // 等待传输结束 // 等待DAC结束 // DAC的/CS无效

// 对SPI接收缓冲空读操作使SPI复位

if (channel == 'A')

SpiaRegs.SPITXBUF = 0x8000 + (value<<2); while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; for (i=0;i<100;i++); i = SpiaRegs.SPIRXBUF;

GpioDataRegs.GPDDAT.bit.GPIOD0 = 1;

// DAC的/CS有效

SpiaRegs.SPICCR.all = 0x004F; // Bit 7 , Reset = 0 : // Bit 6 , 时钟极性 = 1 // Bit 5 , 保留

// Bit 4 , SPILBK = 0 // Bit 3-0, Chars = 1111 // Bit 7-5 : 保留

// Bit 4 , 过载 INT Enable = 0 // Bit 3 , Clock-Phase = 1 // Bit 2 , Master/Slave = 1 // Bit 1 , Talk = 1

// Bit 0 , SPI INT ENA = 0 SpiaRegs.SPIBRR = 124;

// SPI通信波特率 = LSPCLK / ( SPIBRR + 1) // //

= 37,5 MHz / ( 124 + 1 )

// SPI退出复位

= 300 kHz

:禁止接收器过载中断 :半个周期的延时 :MASTER模式 :使能传输 :禁止SPI

SpiaRegs.SPICTL.all =0x000E;

: 非循环模式 : 16 bit 数据传输

: 在SPICLK的下降沿输出数据

// 结合相位控制CLOCK PHASE = 1 : 在SPICLK的下降沿半个周期前输出数据

SpiaRegs.SPICCR.bit.SPISWRESET = 1;

17

例6、CAN总线消息发送例程

//===================================================================== // 发送操作代码 // 文件名称: F2812_CANv0.c

//

// 功能描述: DSP28 CAN 传输测试 // CPU Timer0 ISR周期 50 ms // 看门狗使能,在主循环中处理 // CAN 消息 : 发送一个字节的数据 // CAN通信速率: 100KBPS // 扩展标识符 : 0x1000 0000 //

使用的邮箱 :Mailbox #5 //

//=====================================================================

#include \

// 函数原型声明

void Gpio_select(void); void InitSystem(void); void InitCan();

interrupt void cpu_timer0_isr(void); // 定时器0中断服务程序

void main(void) { struct ECAN_REGS ECanaShadow; InitSystem(); // 初始化DSP内核寄存器 Gpio_select();

// 配置GPIO复用功能寄存器

InitPieCtrl();

// 调用外设中断扩展初始化单元 PIE-unit ( 代码 : DSP281x_PieCtrl.c)

InitPieVectTable(); // 初始化 PIE vector向量表 ( 代码 : DSP281x_PieVect.c )

// 重新映射 PIE - Timer 0的中断

EALLOW; // 解除寄存器保护

PieVectTable.TINT0 = &cpu_timer0_isr; EDIS; // 使能寄存器保护

InitCpuTimers();

// 配置 CPU-Timer 0 周期50 ms:

// 150MHz CPU 频率, 50000 微秒中断周期

ConfigCpuTimer(&CpuTimer0, 150, 50000);

18

// 使能PIE内的 TINT0 : Group 1 interrupt 7 PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

// 使能 CPU INT 1 (CPU定时器0中断) IER = 1;

// 全局中断使能和更高优先级的实时调试事件 EINT; // 全局中断使能INTM ERTM; // 使能实时调试中断DBGM

InitCan(); // 初始化CAN模块

/* 写消息标识符 MSGID */

ECanaMboxes.MBOX5.MSGID.all = 0x10000000; ECanaMboxes.MBOX5.MSGID.bit.IDE = 1; // 扩展标识符 /* 配置 Mailbox 5 作为发送邮箱 */

ECanaShadow.CANMD.all = ECanaRegs.CANMD.all; ECanaShadow.CANMD.bit.MD5 = 0;

ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;

/* 使能邮箱 */

ECanaShadow.CANME.all = ECanaRegs.CANME.all;

ECanaShadow.CANME.bit.ME5 = 1;

ECanaRegs.CANME.all = ECanaShadow.CANME.all;

/* 在消息控制寄存器中写 DLC 区 */

ECanaMboxes.MBOX5.MSGCTRL.bit.DLC = 1;

CpuTimer0Regs.TCR.bit.TSS = 0; while(1) {

while(CpuTimer0.InterruptCount < 20)

{

//等待定时器0

EALLOW;

SysCtrlRegs.WDKEY = 0xAA;

// 看门狗控制

EDIS;

}

CpuTimer0.InterruptCount = 0;

// 定时器中断复位

ECanaMboxes.MBOX5.MDL.byte.BYTE0 = (GpioDataRegs.GPBDAT.all>>8 ) ;

ECanaShadow.CANTRS.all = 0;

ECanaShadow.CANTRS.bit.TRS5 = 1; // 设置 TRS for mailbox under test

ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;

19

while(ECanaRegs.CANTA.bit.TA5 == 0 ) {} // 等待 TA5 bit 置位..

ECanaShadow.CANTA.all = 0; ECanaShadow.CANTA.bit.TA5 = 1;

// 清除 TA5

ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;

} }

void Gpio_select(void) { EALLOW;

GpioMuxRegs.GPAMUX.all = 0x0;

// 所有GPIO引脚配置为I/O

GpioMuxRegs.GPBMUX.all = 0x0; GpioMuxRegs.GPDMUX.all = 0x0; GpioMuxRegs.GPFMUX.all = 0x0;

GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1; //CAN引脚配置

GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1;

GpioMuxRegs.GPEMUX.all = 0x0; GpioMuxRegs.GPGMUX.all = 0x0;

GpioMuxRegs.GPADIR.all = 0x0;

// GPIO PORT 配置为输入

GpioMuxRegs.GPBDIR.all = 0x00FF; // GPIO B15-B8 配置为输入 , B7-B0配置为输出 GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT 配置为输入

GpioMuxRegs.GPAQUAL.all = 0x0; // 设置所有 GPIO 输入的量化值等于0

GpioMuxRegs.GPBQUAL.all = 0x0; GpioMuxRegs.GPDQUAL.all = 0x0; GpioMuxRegs.GPEQUAL.all = 0x0; EDIS; }

void InitSystem(void) {

EALLOW;

SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗 // 0x00E8 禁止看门狗,预定标系数Prescaler = 1

// 0x00AF 不禁止看门狗, 预定标系数Prescaler = 64 SysCtrlRegs.SCSR = 0;

// 看门狗产生复位

SysCtrlRegs.PLLCR.bit.DIV = 10;

// 配置处理器锁相环,倍频系数为5 20

//=============================================================== // Adc.c文件代码结束

//==============================================================

//============================================================== // 文件名称: Adc_isr.c

// 功能描述:存储ADC采样结果到\ //

调用FIR函数并存储滤波后的结果到\

// 采用低通滤波FIR,5阶

//

//==============================================================

#include \#include \

extern _iq IQssfir(_iq*, _iq*, Uint16); short int AData[512]={0};

#define AdcFsVoltage _IQ(3.0) // ADC 满量程电压 #define AdcBufLen

512

// ADC 结果缓冲长度 _iq AdcBuf[AdcBufLen]; // ADC 结果缓冲 _iq AdcBufFiltered[AdcBufLen]; // 滤波后的ADC结果缓冲 #define N 5

// 滤波器长度

_iq xDelay[N] = {0, 0, 0, 0, 0};

// filter coefficients

_iq coeffs[N] = {1000*_IQ(0.0625),1000* _IQ(0.25), 1000*_IQ(0.375), 1000*_IQ(0.25), _IQ(0.0625)};

interrupt void ADC_FIR_INT_ISR(void)

{ static Uint16 ibuf=0;

int i=5; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

/*** Manage the ADC registers ***/ AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;

// 复位SEQ1到CONV00状态 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // 清楚ADC SEQ1中断标志

/***读取ADC结果: 1) 将无符号16-bit结果转换成32-bit IQ16格式 2) 将IQ16格式转换为IQ格式 3) 根据ADC满量程定标

***/

AData[ibuf]=AdcRegs.ADCRESULT0>>4; AdcBuf[ibuf] = _IQmpy(AdcFsVoltage, _IQ16toIQ( (_iq)AdcRegs.ADCRESULT0));

36

/*** 调用滤波函数 ***/ xDelay[0] = AdcBuf[ibuf];

AdcBufFiltered[ibuf] = IQssfir(xDelay, coeffs, N);

ibuf++;

if(ibuf == AdcBufLen) { ibuf = 0; i=0; }

else i=1;

}

//=============================================================== // Adc_isr.c文件代码结束

//==============================================================

37

SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟分频系数: 2 SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟分频系数: 4

// 使用的外设时钟时钟设置:

// 一般不使用的外设的时钟禁止,降低系统功耗 SysCtrlRegs.PCLKCR.bit.EVAENCLK=0; SysCtrlRegs.PCLKCR.bit.EVBENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0; SysCtrlRegs.PCLKCR.bit.SPIENCLK=0;

SysCtrlRegs.PCLKCR.bit.ECANENCLK=1; // 使能CAN模块的时钟 SysCtrlRegs.PCLKCR.bit.ADCENCLK=0; EDIS; }

interrupt void cpu_timer0_isr(void) {

CpuTimer0.InterruptCount++;

// 每个定时器中断清除一次看门狗计数器 EALLOW; SysCtrlRegs.WDKEY = 0x55;

// 看门狗控制

EDIS;

// 响应中断并允许系统接收更多的中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }

void InitCan(void) { asm(\ EALLOW\

/* 通过eCAN寄存器配置RX和TX引脚作为发送接收*/

ECanaRegs.CANTIOC.bit.TXFUNC = 1; ECanaRegs.CANRIOC.bit.RXFUNC = 1;

/* 配置 eCAN 工作在 HECC模式 - (请求访问邮箱16 到 31) */ // HECC模式和使能时间标签功能 ECanaRegs.CANMC.bit.SCB = 1;

/* 配置位的时间参数 */

21

ECanaRegs.CANMC.bit.CCR = 1 ; // 设置 CCR = 1

while(ECanaRegs.CANES.bit.CCE != 1 ) {} //等待 CCE bit置位..

ECanaRegs.CANBTC.bit.BRPREG = 99; ECanaRegs.CANBTC.bit.TSEG2REG = 2; ECanaRegs.CANBTC.bit.TSEG1REG = 10;

ECanaRegs.CANMC.bit.CCR = 0 ; // 设置 CCR = 0 while(ECanaRegs.CANES.bit.CCE == !0 ) {} // 等待 CCE bit清0..

/* 禁止所有邮箱 */

ECanaRegs.CANME.all = 0; // 写 MSGIDs之前发出请求

asm(\ EDIS\

}

/***************************************************/ /* 150 MHz SYSCLKOUT 时eCAN的时序配置 */ /***************************************************/ /*

下表给出在BT = 15 SP=80%时,BRP不同的配置方式CAN的通信速率

---------------------------------------------------

BT = 15, TSEG1 = 10, TSEG2 = 2, Sampling Point = 80% ---------------------------------------------------

1 Mbps : BRP+1 = 10 : CAN clock = 15 MHz 500 kbps : BRP+1 = 20 : CAN clock = 7.5 MHz 250 kbps : BRP+1 = 40 : CAN clock = 3.75 MHz 125 kbps : BRP+1 = 80

: CAN clock = 1.875 MHz

100 kbps : BRP+1 = 100 : CAN clock = 1.5 MHz 50 kbps : BRP+1 = 200 : CAN clock = 0.75 MHz

-------------------------------------------------------------

BT = 25时,通过改变 TSEG1 & TSEG2 获得的不同的采样点 -------------------------------------------------------------

TSEG1 = 18, TSEG2 = 4, SP = 80% TSEG1 = 17, TSEG2 = 5, SP = 76% TSEG1 = 16, TSEG2 = 6, SP = 72% TSEG1 = 15, TSEG2 = 7, SP = 68% TSEG1 = 14, TSEG2 = 8, SP = 64%

BT = 25时,BRP不同的配置方式CAN的通信速率

22

1 Mbps : BRP+1 = 6 500 kbps : BRP+1 = 12 250 kbps : BRP+1 = 24 125 kbps : BRP+1 = 48 100 kbps : BRP+1 = 60 50 kbps : BRP+1 = 120 */

//===================================================================== // 代码结束

//=====================================================================

例7、使用FIFO缓冲发送数据

//===================================================================== //

// 文件名称: SCI_interruptFIFO.c

//

// 功能描述: DSP28 SCI - 同计算机通信,采用超级中断接受数据 //

间隔2秒DSP向计算机发送字符\

// SCI配置 : 波特率 9600 ,数据长度 8 Bit , 无极性 , 1位停止位 // TX缓冲空,触发SCI-TX INT 中断 // CPU CORE 定时器0中断触发第一次传输 // SCI TX FIFO 存放16个字节

//=====================================================================

#include \

// 使用的函数原型声明

void Gpio_select(void); void InitSystem(void); void SCI_Init(void);

interrupt void cpu_timer0_isr(void); interrupt void SCI_TX_isr(void);

// 全局变量

char message[]={\int index =0;

// 字符串指针

void main(void)

23

{ InitSystem(); // 初始化DSP内核寄存器 Gpio_select();

// 配置GPIO复用功能寄存器

InitPieCtrl();

// 调用外设中断扩展初始化单元 PIE-unit ( 代码 : DSP281x_PieCtrl.c)

InitPieVectTable(); // 初始化 PIE vector向量表 ( 代码 : DSP281x_PieVect.c )

// 重新映射 PIE - Timer 0的中断

EALLOW; // 解除寄存器保护 PieVectTable.TINT0 = &cpu_timer0_isr; EDIS; // 使能寄存器保护

InitCpuTimers();

// 配置 CPU-Timer 0 周期50 ms:

// 150MHz CPU 频率, 50000 微妙中断周期

ConfigCpuTimer(&CpuTimer0, 150, 50000);

// 使能PIE内的 TINT0 : Group 1 interrupt 7 PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // 使能 CPU INT1 (连接到CPU-Timer 0中断) IER = 1;

EALLOW; // 解除寄存器保护 PieVectTable.TXAINT = &SCI_TX_isr; EDIS; // 使能寄存器保护

// 使能PIE内的 SCI_A_TX_INT中断 PieCtrlRegs.PIEIER9.bit.INTx2 = 1;

// 使能 CPU INT 9 IER |= 0x100;

// 全局中断使能和更高优先级的实时调试事件 EINT; // 全局中断使能INTM ERTM; // 使能实时调试中断DBGM

CpuTimer0Regs.TCR.bit.TSS = 0; // 启动定时器0 SCI_Init(); while(1)

{

24

while(CpuTimer0.InterruptCount < 40) // 等待50ms * 40 {

EALLOW;

SysCtrlRegs.WDKEY = 0xAA;

// 看门狗控制

EDIS; }

CpuTimer0.InterruptCount = 0; // 复位清零 SciaRegs.SCIFFTX.bit.TXINTCLR = 1 ;

// 清除中断标志

} }

void Gpio_select(void) { EALLOW;

GpioMuxRegs.GPAMUX.all = 0x0;

// 所有 GPIO 端口配置为I/O

GpioMuxRegs.GPBMUX.all = 0x0; GpioMuxRegs.GPDMUX.all = 0x0; GpioMuxRegs.GPFMUX.all = 0x0;

GpioMuxRegs.GPFMUX.bit.SCIRXDA_GPIOF5 = 1; //配置 SCI-RX GpioMuxRegs.GPFMUX.bit.SCITXDA_GPIOF4 = 1; //配置 SCI-TX GpioMuxRegs.GPEMUX.all = 0x0; GpioMuxRegs.GPGMUX.all = 0x0;

GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPBDIR.all = 0x00; // GPIO PORT 配置为输入 GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPGDIR.all = 0x0;

// GPIO PORT 配置为输入

GpioMuxRegs.GPAQUAL.all = 0x0; // 设置所有 GPIO 输入的量化值等于0 GpioMuxRegs.GPBQUAL.all = 0x0; GpioMuxRegs.GPDQUAL.all = 0x0; GpioMuxRegs.GPEQUAL.all = 0x0; EDIS; }

void InitSystem(void) {

EALLOW;

SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗 // 0x00E8 禁止看门狗,预定标系数Prescaler = 1

// 0x00AF 不禁止看门狗, 预定标系数Prescaler = 64 25

SysCtrlRegs.SCSR = 0; // 看门狗产生复位

SysCtrlRegs.PLLCR.bit.DIV = 10; // 配置处理器锁相环,倍频系数为5

SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟分频系数: 2 SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟分频系数: 4

// 使用的外设时钟时钟设置:

// 一般不使用的外设的时钟禁止,降低系统功耗 SysCtrlRegs.PCLKCR.bit.EVAENCLK=0; SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;

SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1; // 使能SCI模块的时钟 SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0; SysCtrlRegs.PCLKCR.bit.SPIENCLK=0; SysCtrlRegs.PCLKCR.bit.ECANENCLK=0; SysCtrlRegs.PCLKCR.bit.ADCENCLK=0; EDIS; }

void SCI_Init(void) {

SciaRegs.SCICCR.all =0x0007;

// 1bit 停止位 无循环模式

// 无极性, 字符长度:8 bits, // 异步模式, 空闲线协议 SciaRegs.SCICTL1.all =0x0003;

// 使能 TX, RX, 内部 SCICLK,

// 禁止 RX ERR, SLEEP, TXWAKE

SciaRegs.SCIHBAUD = 487 >> 8 ; // 波特率:9600(LSPCLK = 37.5MHz) ; SciaRegs.SCILBAUD = 487 & 0x00FF;

SciaRegs.SCICTL2.bit.TXINTENA = 1; // 使能SCI发送中断

SciaRegs.SCIFFTX.all = 0xE060;

// bit 15 = 1 : 退出复位

// bit 14 = 1 : 使能FIFO增强模式 // bit 13 = 1 : 使能 TX FIFO操作 // bit 6 = 1 : CLR TXFFINT-标志 // bit 5 = 1 : 使能TX FIFO匹配

// bit 4-0 : 如果TX FIFO等于0,产生TX-ISR中断

SciaRegs.SCICTL1.all =0x0023; // 使SCI退出复位

}

interrupt void cpu_timer0_isr(void) {

CpuTimer0.InterruptCount++;

26

// 每个定时器中断清除一次看门狗计数器 EALLOW; SysCtrlRegs.WDKEY = 0x55;

// 看门狗控制

EDIS;

// 响应中断并允许系统接收更多的中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }

//===================================================================== // SCI_A 发送中断服务程序 // 发送字符串 message[]

//===================================================================== interrupt void SCI_TX_isr(void) { if (index < 26) SciaRegs.SCITXBUF=message[index++]; // 重新初始化PIE为下一次 SCI-A TX准备接收下一次中断 PieCtrlRegs.PIEACK.all = 0x0100; //响应中断

}

//===================================================================== // 代码结束.

//=====================================================================

例8、使用FIFO缓冲接收数据

//==================================================================== //

// 文件名称: SCI_TXRXintFIFO.c

//

// 功能描述: DSP28 SCI - 同计算机通信,采用超级中断接收发送数据 // DSP等待从计算机接收数据\并向计算机发送\// SCI配置 : 波特率 9600 ,数据长度 8 Bit , 无极性 , 1位停止位 // TX缓冲空触发SCI-TX INT 中断 // CPU CORE 定时器0中断触发第一次传输 // SCI TX FIFO 存放16个字节

//====================================================================

#include \

// 使用的函数原型声明

void Gpio_select(void); void SpeedUpRevA(void);

27

void InitSystem(void); void SCI_Init(void);

interrupt void SCI_TX_isr(void); interrupt void SCI_RX_isr(void);

// 全局变量

char message[]={\

void main(void) { InitSystem(); // 初始化DSP内核寄存器 Gpio_select();

// 配置GPIO复用功能寄存器

InitPieCtrl();

// 调用外设中断扩展初始化单元 PIE-unit ( 代码 : DSP281x_PieCtrl.c)

InitPieVectTable(); // 初始化 PIE vector向量表 ( 代码 : DSP281x_PieVect.c )

EALLOW; // 解除寄存器保护

PieVectTable.TXAINT = &SCI_TX_isr; PieVectTable.RXAINT = &SCI_RX_isr; EDIS; // 使能寄存器保护

// 使能PIE中的SCI_A_TX_INT中断 PieCtrlRegs.PIEIER9.bit.INTx2 = 1; // 使能PIE中的SCI_A_RX_INT中断 PieCtrlRegs.PIEIER9.bit.INTx1 = 1;

// 使能 CPU INT 9 IER |= 0x100;

// 全局中断使能和更高优先级的实时调试事件 EINT; // 全局中断使能INTM ERTM; // 使能实时调试中断DBGM

SCI_Init(); while(1) { EALLOW;

SysCtrlRegs.WDKEY = 0x55; // 看门狗控制 SysCtrlRegs.WDKEY = 0xAA;

EDIS;

} }

28

void Gpio_select(void) { EALLOW;

GpioMuxRegs.GPAMUX.all = 0x0;

// 所有 GPIO 端口配置为I/O

GpioMuxRegs.GPBMUX.all = 0x0; GpioMuxRegs.GPDMUX.all = 0x0; GpioMuxRegs.GPFMUX.all = 0x0;

GpioMuxRegs.GPFMUX.bit.SCIRXDA_GPIOF5 = 1; //配置 SCI-RX GpioMuxRegs.GPFMUX.bit.SCITXDA_GPIOF4 = 1; //配置 SCI-TX GpioMuxRegs.GPEMUX.all = 0x0; GpioMuxRegs.GPGMUX.all = 0x0;

GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPBDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 配置为输入 GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT 配置为输入

GpioMuxRegs.GPAQUAL.all = 0x0; // 设置所有 GPIO 输入的量化值等于0

GpioMuxRegs.GPBQUAL.all = 0x0; GpioMuxRegs.GPDQUAL.all = 0x0; GpioMuxRegs.GPEQUAL.all = 0x0; EDIS; }

void InitSystem(void) {

EALLOW;

SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗 // 0x00E8 禁止看门狗,预定标系数Prescaler = 1

// 0x00AF 不禁止看门狗, 预定标系数Prescaler = 64 SysCtrlRegs.SCSR = 0;

// 看门狗产生复位

SysCtrlRegs.PLLCR.bit.DIV = 10;

// 配置处理器锁相环,倍频系数为5

SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟分频系数: 2 SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟分频系数: 4

// 使用的外设时钟时钟设置:

// 一般不使用的外设的时钟禁止,降低系统功耗 SysCtrlRegs.PCLKCR.bit.EVAENCLK=0; SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;

SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1; // 使能SCI模块的时钟

29

SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0; SysCtrlRegs.PCLKCR.bit.SPIENCLK=0; SysCtrlRegs.PCLKCR.bit.ECANENCLK=0; SysCtrlRegs.PCLKCR.bit.ADCENCLK=0; EDIS; }

void SCI_Init(void) {

SciaRegs.SCICCR.all =0x0007;

// 1bit 停止位 无循环模式

// 无极性, 字符长度:8 bits, // 异步模式, 空闲线协议 SciaRegs.SCICTL1.all =0x0003;

// 使能 TX, RX, 内部 SCICLK,

// 禁止 RX ERR, SLEEP, TXWAKE

SciaRegs.SCIHBAUD = 487 >> 8 ; // 波特率:9600(LSPCLK = 37.5MHz) ; SciaRegs.SCILBAUD = 487 & 0x00FF;

SciaRegs.SCICTL2.bit.TXINTENA = 1; // 使能SCI发送中断 SciaRegs.SCICTL2.bit.RXBKINTENA = 1; // 使能SCI接收中断 SciaRegs.SCIFFTX.all = 0xE060;

// bit 15 = 1 : 退出复位

// bit 14 = 1 : 使能FIFO增强模式 // bit 13 = 1 : 使能 TX FIFO操作 // bit 6 = 1 : CLR TXFFINT-标志 // bit 5 = 1 : 使能TX FIFO匹配

// bit 4-0 : 如果TX FIFO等于0,产生TX-ISR中断

SciaRegs.SCIFFRX.all = 0xE065; // Rx 中断级设置为5 SciaRegs.SCICTL1.all =0x0023; // 使SCI退出复位

}

//==================================================================== // SCI_A 发送中断服务程序 // 发送字符串 message[]

//==================================================================== interrupt void SCI_TX_isr(void) { int i;

for(i=0;i<16;i++)SciaRegs.SCITXBUF=message[i];

// 重新初始化PIE为下一次 SCI-A TX准备接收下一次中断 PieCtrlRegs.PIEACK.all = 0x0100; //响应中断

}

30

interrupt void SCI_RX_isr(void) { int i;

char buffer[16];

for (i=0;i<16;i++) buffer[i]= SciaRegs.SCIRXBUF.all;

if (strncmp(buffer, \ { SciaRegs.SCIFFTX.bit.TXFIFOXRESET =1; SciaRegs.SCIFFTX.bit.TXINTCLR = 1 ;

}

SciaRegs.SCIFFRX.bit.RXFIFORESET = 0; // 复位 FIFO指针 SciaRegs.SCIFFRX.bit.RXFIFORESET = 1; // 使能操作

SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // 清除FIFO INT中断标志 PieCtrlRegs.PIEACK.all = 0x0100; // 响应中断

}

//==================================================================== // 代码结束.

//==================================================================== 例9、ADC应用举例

//============================================================== //

// 文件名称:ADC_Fir.c // 功能描述:主程序

// DSP28 T1PWM 输出产生2KHz的方波信号 // 定时器2产生ADC启动信号 //

启动看门狗并在主程序中处理

//

//==============================================================

#include \

// 函数声明

void Gpio_select(void); void InitSystem(void);

interrupt void T1_Compare_isr(void); // EVA-T1 比较中断 interrupt void ADC_FIR_INT_ISR(void); // ADC 服务中断

void main(void)

31

InitSystem();

// 初始化DSP内核寄存器

Gpio_select();

// 设置GPIO工作模式

InitPieCtrl();

// 初始化 PIE单元 ( code : DSP281x_PieCtrl.c)

InitPieVectTable(); // 初始化PIE中断向量表 ( code : DSP281x_PieVect.c )

InitAdc(); // 初始化ADC

// 从新映射EVA-T1比较和ADC中断 EALLOW;

PieVectTable.T1CINT = &T1_Compare_isr; PieVectTable.ADCINT = &ADC_FIR_INT_ISR; EDIS;

// 使能EVA-T1CMPR INT (位于组2中断5) PieCtrlRegs.PIEIER2.bit.INTx5 = 1; // 使能CPU INT1 (ADC) 和INT2(EVA-Timer1 比较): IER |= 3;

// 全局使能中断 EINT; ERTM;

// 配置事件管理器EVA

// T1/T2驱动T1PWM / T2PWM输出逻辑 EvaRegs.GPTCONA.bit.TCMPOE = 1; // GP Timer 1比较设置为地有效 EvaRegs.GPTCONA.bit.T1PIN = 1;

// timer2 周期标志启动ADC EvaRegs.GPTCONA.bit.T2TOADC = 2;

EvaRegs.T1CON.all = 0x1002; // 配置T1为递增计数模式

EvaRegs.T1PR = 37500;

// 2KHz PWM EvaRegs.T1CMPR = EvaRegs.T1PR/2; // 50% 占空比 EvaRegs.EVAIMRA.bit.T1CINT = 1; // 使能T1CMPR中断 EvaRegs.T1CON.bit.TENABLE = 1; // 启动定时器 EvaRegs.T2CON.all = 0x0000; / 禁止定时器2

EvaRegs.T2CNT = 0x0000;

// 清楚定时器2计数寄存器

EvaRegs.T2PR = 1499;

// 50KHz (HSPCLK = 2和T2TPS = 1) 32

{

EvaRegs.T2CON.all = 0x1040; // 使能定时器

while(1) {

EALLOW;

SysCtrlRegs.WDKEY = 0xAA;

// 看门狗处理

EDIS; }

}

void Gpio_select(void) { EALLOW;

GpioMuxRegs.GPAMUX.all = 0x0;

// 所有GPIO设置为I/O

GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6 = 1;

// T1PWM 有效

GpioMuxRegs.GPBMUX.all = 0x0; GpioMuxRegs.GPDMUX.all = 0x0; GpioMuxRegs.GPFMUX.all = 0x0;

GpioMuxRegs.GPEMUX.all = 0x0; GpioMuxRegs.GPGMUX.all = 0x0;

GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT配置为输入 GpioMuxRegs.GPBDIR.all = 0x0; // GPIO PORT配置为输入 GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT配置为输入 GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT配置为输入 GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT配置为输入 GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT配置为输入

GpioMuxRegs.GPAQUAL.all = 0x0; // 设置GPIO输入量化值为0

GpioMuxRegs.GPBQUAL.all = 0x0; GpioMuxRegs.GPDQUAL.all = 0x0; GpioMuxRegs.GPEQUAL.all = 0x0; EDIS; }

void InitSystem(void) {

EALLOW;

SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗 // 0x00E8 禁止看门狗,预定标系数Prescaler = 1

// 0x00AF 不禁止看门狗, 预定标系数Prescaler = 64

SysCtrlRegs.SCSR = 0;

// 看门狗产生复位

SysCtrlRegs.PLLCR.bit.DIV = 10; // 配置处理器锁相环,倍频系数为5

33

SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟分频系数: 2 SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟分频系数: 4

// 使用的外设时钟时钟设置:

// 一般不使用的外设的时钟禁止,降低系统功耗 SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; SysCtrlRegs.PCLKCR.bit.EVBENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0; SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0; SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0; SysCtrlRegs.PCLKCR.bit.SPIENCLK=0; //使能SPI时钟

SysCtrlRegs.PCLKCR.bit.ECANENCLK=0; SysCtrlRegs.PCLKCR.bit.ADCENCLK=1; EDIS; }

interrupt void T1_Compare_isr(void) {

// 中断处理服务程序处理看门狗 EALLOW; SysCtrlRegs.WDKEY = 0x55;

EDIS;

// 响应EVA-Timer1比较中断 EvaRegs.EVAIFRA.bit.T1CINT = 1; // 响应该中断,准备接收更多的中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; }

//=============================================================== // ADC_Fir.c文件代码结束

//==============================================================

//=============================================================== // 文件名称: Adc.c // 功能描述:ADC初始化

//===============================================================

#include \

void DelayUs(volatile Uint16);

34

void InitAdc(void) {

/*** ADC 模块复位 ***/ AdcRegs.ADCTRL1.bit.RESET = 1; // 复位ADC模块

asm(\

// 必须等待12个周期(最差情况)以便复位有效

/*** ADC 上电次序 ***/

AdcRegs.ADCTRL3.all = 0x00C8;

// 首先为ref和bandgap电路上电

DelayUs(5000); // ADCPWDN置位前等待5ms AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // ADCPWDN=1使ADC主模块上电 DelayUs(20);

// 等待20us

/***配置ADC寄存器 ***/ AdcRegs.ADCMAXCONV.all = 0x0000; AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 2;

// 转换通道2

AdcRegs.ADCTRL1.all = 0x2710;

AdcRegs.ADCTRL2.all = 0x0900;

/*** 使能ADC中断 ***/ PieCtrlRegs.PIEIER1.bit.INTx6 = 1; IER |= 0x0001;

}

// AdcInit()结束

/********************************************************************* * 函数:DelayUs() * *********************************************************************/ void DelayUs( volatile Uint16 Usec ) {

while( Usec-- )

// 1us loop at 150MHz CPUCLK

{ asm(\

}

} // end DelayUs()

35

本文来源:https://www.bwwdw.com/article/sjh2.html

Top