2812功能单元使用
更新时间:2023-10-31 02:48:01 阅读量: 综合文库 文档下载
- 2812芯片功能推荐度:
- 相关推荐
第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
正在阅读:
2812功能单元使用10-31
安全方案10-01
致远OA-流程表单制作01-23
樱花小学生作文06-15
081-单位擅自实行年薪制,员工以拖欠工资为由要求经济补偿金获支持08-21
第3章-1 护理学的基本概念和护理理论教案 - 图文10-19
小学三年级上册数学复习计划08-25
2018年春部编人教版八年级语文下单元期中期末考试试卷及答案解析05-30
内科选择题10-01
网吧消防管理制度06-12
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 单元
- 功能
- 使用
- 2812
- 山东省东营市广饶县2013-2014学年第一学期期末质量调研七年级语文试题 新人教版
- 双串口2
- 消防部队车辆管理规定
- 公司金融资金时间价值练习及答案
- 基本二维绘图
- 苗族古文字符号及其内涵的丰富生活习俗 - 图文
- 2017-2018学年浙江省金华市十校高二上学期期末联考数学试题Word版含答案
- 2015-2016-1信息系统分析与设计题库-yy
- 《统计学基础(第2版)》(06511)参考答案
- 新基础教育十问
- 2017-2022年版农村社会养老保险产业政府战略管理与区域发展战略研究咨询报告目录
- 常用英语拟声词
- 附表5-实体工程安全及文明施工16版房建 - 图文
- 国际贸易融资套利风险研究
- 兴仁厂房施工组织设计
- 九年级科学上册 第五章《简单机械》教学案
- 大力推进信息管税,全面提高税收征管和科技工作水平
- 五精管理工作汇报材料(稿)9.10
- 《学前心理学》练习
- 2018年最新人教版七年级英语下册1-12单元知识点句型练习与解析