利用事件管理器产生四个匹配事件控制四盏灯实验
一、实验目的
1、通过对做实验进一步了解DSP的工作原理。
2、检测一学期上课效果。
二、实验要求
1、利用事件管理器模块的定时器的四匹配事件中的中断来控制D6、D7、D8、D9显示。
三、实验器材
合众达DSP开发板以及装有ccs3.3的笔记本电脑
四、实验内容以及方法
本次实验操作主要是涉及到事件管理器中断,基本设想是事件管理器包含EVA和EVB两个,一共四个通用定时器,正好可以产生上溢、下溢、比较、周期中断,每次中断产生时候,所对应的LED灯置位,当所对应的LED灯显示亮的时候就证明这种中断已经产生,所对应的程序流程图已经程序和说明如下:
Main函数基本流程如下
中断函数程序流程图如下:
由程序流程图写得程序如下:
主函数:
/******************************************************************/
/*Copyright (C), ; 华东交通大学 */
/* Module Name : */
/* File Name : main.c */
/* Author : */
/* Create Date : 20##/12/27 */
/* Version : */
/* Function : 四个匹配事件控制四盏灯 */
/* Description : */
/* Support : */
/******************************************************************/
/*****************头文件********************/
#include "DSP28_Device.h"
#include "ext_inf.h"
/****************端口宏定义*****************/
/****************常量宏定义*****************/
void delay_loop(void);
/***************全局变量定义****************/
/****************函数声明*******************/
interrupt void EVA_Timer1_isr(void);
interrupt void EVA_Timer2_isr(void);
interrupt void EVB_Timer3_isr(void);
interrupt void EVB_Timer4_isr(void);
/*------------------------------------------*/
/*形式参数:void */
/*返回值:void */
/*函数描述:主函数 */
/*------------------------------------------*/
void main(void)
{
InitSysCtrl();
DINT;
InitPieCtrl(); //初始化PIE控制寄存器
IER=0x0000; //禁止CPU中断
IFR=0x0000; //清楚CPU中断标志
InitPieVectTable(); //初始化PIE中断向量表
EALLOW; //允许更改
PieVectTable.T1PINT = &EVA_Timer1_isr;
PieVectTable.T2CINT = &EVA_Timer2_isr;
PieVectTable.T3OFINT = &EVB_Timer3_isr;
PieVectTable.T4UFINT = &EVB_Timer4_isr;
EDIS; //禁止更改
InitEv();
PieCtrl.PIEIER2.bit.INTx4 =1; //使能PIE中断INT2.4( T1PINT)
PieCtrl.PIEIER3.bit.INTx2 =1 ; //使能PIE中断INT3.2(T2CINT)
PieCtrl.PIEIER4.bit.INTx7 =1; //使能PIE中断INT4.7(T3OFINT)
PieCtrl.PIEIER5.bit.INTx3 =1 ; //使能PIE中断INT5.3(T4UFINT)
IER |= (M_INT2|M_INT3|M_INT4|M_INT5); //开CPU中断
EINT; //使能全局中断INTM
ERTM; //使能全局实时中断DBGM
for(;;);
//等待中断
}
interrupt void EVA_Timer1_isr(void)
{
*LED = 1; //置1
delay_loop(); //延时
EvaRegs.EVAIMRA.bit.T1PINT = 1; //中断标志寄存器置位
EvaRegs.EVAIFRA.all = BIT7; //中断屏蔽寄存器使能
PieCtrl.PIEACK.all =PIEACK_GROUP2; //响应中断
}
interrupt void EVA_Timer2_isr(void)
{
*LED=2; //置2
delay_loop(); //延时
EvaRegs.EVAIMRB.bit.T2CINT = 1; //中断标志寄存器置位
EvaRegs.EVAIFRB.bit.T2CINT = 1; //中断屏蔽寄存器使能
PieCtrl.PIEACK.all = PIEACK_GROUP3; //响应中断
}
interrupt void EVB_Timer3_isr(void)
{
*LED = 4; //置4
delay_loop(); //延时
EvbRegs.EVBIMRA.bit.T3OFINT = 1; //中断标志寄存器置位
EvbRegs.EVBIFRA.bit.T3OFINT = 1; //中断屏蔽寄存器使能
PieCtrl.PIEACK.all = PIEACK_GROUP4; //响应中断
}
interrupt void EVB_Timer4_isr(void)
{
*LED = 8; //置8
delay_loop(); //延时
EvbRegs.EVBIMRB.bit.T4UFINT = 1; //中断标志寄存器置位
EvbRegs.EVBIFRB.bit.T4UFINT = 1; //中断屏蔽寄存器使能
PieCtrl.PIEACK.all = PIEACK_GROUP5; //响应中断
}
void delay_loop() //延时函数
{
float i;
for (i = 0; i < 25000; i++) {}
}
以上是main函数。之所以要加延时是因为频率过高。肉眼来不及看得清,
在事件管理器中的函数如下:
#include "DSP28_Device.h"
//---------------------------------------------------------------------------
// InitEv:
//---------------------------------------------------------------------------
// This function initializes to a known state.
//
void Init_Eva_Timer1(void);
void Init_Eva_Timer2(void);
void Init_Evb_Timer3(void);
void Init_Evb_Timer4(void);
void InitEv(void)
{
Init_Eva_Timer1();
Init_Eva_Timer2();
Init_Evb_Timer3();
Init_Evb_Timer4();
}
void Init_Eva_Timer1(void)
{
EvaRegs.GPTCONA.all=0; //设置定时器1寄存器
EvaRegs.T1PR = 0xE4E1; // 周期值
EvaRegs.T1CMPR = 0x0000; // 比较值
EvaRegs.EVAIMRA.bit.T1PINT = 1; //使能周期GP定时器1的中断位
EvaRegs.EVAIFRA.bit.T1PINT = 1;
EvaRegs.T1CNT = 0x0000; //清除定时器计数值
EvaRegs.T1CON.all = 0x1742; //递增计数,标参数128,内部时钟,使能比较,使用自己的周期
}
/*********************************************************************************************************
** 函数名称: Init_Eva_Timer2
** 功能描述: 初始化定时器2函数,设置为比较匹配触发中断,定时为100ms
** 当T1CNT值等于T1CMPR时候,触发中断
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 返 回:无
** 作 者:
** 日 期: 20##年11月22日
** 修 改 者:
** 日 期:
*********************************************************************************************************/
void Init_Eva_Timer2(void)
{
EvaRegs.GPTCONA.all = 0; //设置定时器2寄存器
EvaRegs.T2PR = 0xE4E1; // 周期值
EvaRegs.T2CMPR = 0xE4E1; // 比较值
EvaRegs.EVAIMRB.bit.T2CINT = 1; //使能周期GP定时器2的中断位
EvaRegs.EVAIFRB.bit.T2CINT = 1;
EvaRegs.T2CNT = 0x0000; //清除定时器计数值
EvaRegs.T2CON.all = 0x1746; //递增计数,标参数128,内部时钟,使能比较,使用自己的周期
}
/*********************************************************************************************************
** 函数名称: Init_Evb_Timer3
** 功能描述: 初始化定时器3函数,设置为上溢时间触发中断,定时为100ms
** 当T1CNT值等于0xFFFFh时候,触发中断
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 返 回:无
** 作 者:
** 日 期: 20##年11月22日
** 修 改 者:
** 日 期:
*********************************************************************************************************/
void Init_Evb_Timer3(void)
{
EvbRegs.GPTCONB.all = 0; //设置定时器3寄存器
EvbRegs.T3PR = 0xFFFF; // 周期值
EvbRegs.T3CMPR = 0xFFFF; // 比较值
EvbRegs.EVBIMRA.bit.T3OFINT = 1; //使能周期GP定时器3的中断位
EvbRegs.EVBIFRA.bit.T3OFINT = 1;
EvbRegs.T3CNT = 0x1B1E; //设置定时器计数值
EvbRegs.T3CON.all = 0x1746; //递增计数,标参数128,内部时钟,使能比较,使用自己的周期
}
/*********************************************************************************************************
** 函数名称: Init_Evb_Ti mer4
** 功能描述: 初始化定时器4函数,设置为下溢时间触发中断,定时为100ms
** 当T1CNT值等于0x0000h时候,触发中断
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 返 回:无
** 作 者:
** 日 期: 20##年11月22日
** 修 改 者:
** 日 期:
*********************************************************************************************************/
void Init_Evb_Timer4(void)
{
EvbRegs.GPTCONB.all = 0; //设置定时器3寄存器
EvbRegs.T4PR = 0x7270; // 周期值
EvbRegs.T4CMPR = 0x7270; // 比较值
EvbRegs.EVBIMRB.bit.T4UFINT = 1; //使能周期GP定时器3的中断位
EvbRegs.EVBIFRB.bit.T4UFINT = 1;
EvbRegs.T4CNT = 0x0000; //设置定时器计数值
EvbRegs.T4CON.all = 0x1742; //连续增减计数,标参数128,内部时钟,使能比较,使用自己的周期
}
在事件管理器中的皆为递增计数模式,外部晶振位30MHZ,
定时器输入脉冲=(1/30MHZ)×1/PLL×HISPCP×定时器预定标系数
可以看出以上为128,可以算的输出脉冲为100ms,设置定时器时候,计算好数据,设置相应使能位,当触发时候即可进入相应中断。
五、实验现象
可以看见四盏LED灯闪烁,表明四个中断都产生过。
六、实验心得
通过本次实验检测,对DSP的很多寄存器加深了了解,特别是事件管理器部分,在程序调试阶段一定要仔细耐心,设置断点调试,对于不懂的地方要多翻书虚心向有经验的同学请教。