实验三 定时器及中断实验
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三定时器及中断实验
一、实验目的
1)熟悉VC5402的定时器工作原理。
2)掌握VC5402定时器的编程控制方法。
3)学会使用定时器的中断方式来控制程序执行方法。
4)掌握外部中断的控制方法,理解DSP对于中断的响应的过程。
5)学习并掌握混合编程的方法。
二、实验设备
1)微机一台、DSP硬件仿真器一台、DSP实验箱一台。
2)程序及链接命令文件见:D:\ EXPER\EXP3目录下的.asm 、.cmd、.C 和.lib文件。三、开关设置
将开关K9拨到右边,即仿真器选择连接右边的CPU2。然后将实验箱上的SW2(不是CPU板上的)设置为ON ON OFF ON ,即单脉冲按钮产生的中断给CPU2的中断INT2。
1)创建新的项目,添加源程序和链接命令文件,编译链接后载入执行程序。
2)连续运行程序,观察由发光管LED5~8所指示的变化,读懂程序理解为何每秒变化1次。
在中断向量表中定时器中断向量入口地址处设置断点,然后连续执行程序,从断点处再单步执行程序,理解中断向量程序的挂接方法,同时学会中断向量地址的计算方法。3)按几下单脉冲按钮,观察发光管LED1~4所发生的相应变化。与定时中断类似设置断点进行程序跟踪调试。
4)分别在中断向量表中定时器和外中断2的向量入口地址处设置断点,然后连续执行程序,从断点处再单步执行程序,理解中断向量程序的设置方法。同时还要根据实验书后附录3(中断向量表)理解并掌握中断向量的入口地址的计算方法。
五、实验报告
1)发光管LED5~8每秒钟闪烁一次是如何算得的?
2)查实验书后中断屏蔽寄存器,说明中断初始化的方法。
3)若将定时周期改为2秒,应如何修改程序?都有哪些方法?给出程序段
4)若将外部中断2(INT2)改为外部中断0时(INT0), 要求执行按下单脉冲按键时led1~4发生变化,应如何修改程序?注意:电路方面要调节SW2为 ON ON OFF OFF 。
5) 思考题:如何用c语言调用汇编子程序?如何实现不同汇编程序之间相互调用?怎样在
c程序中嵌入汇编语句?
五、源程序及链接命令文件
1、主程序EXP03.C
/************************************************
* FileName: EXP03.C *
* Description: 定时器中断实验*
* Write by: lanrunze *
* Date: 2004-2-10 *
* Update: 2006-3-10 *
*************************************************/
//因为使用了混合编程,所以必须添加 rts.lib 到项目文件中
//观察程序时使用DEBUG--GO MAIN来使程序跳转到程序的执行入口
//使用外中断2时 SW2= on on off on
//使用外中断0时 SW2= on on off off
//本实验使用单按钮产生外部中断
#include
interrupt void timer(); //定义定时器中断服务子程序
interrupt void int2c(); //定义外部中断服务子程序
extern void initial(); //定义外部初始化子程序
extern void porta(); //定义外部端口操作子程序
extern void portb();
extern void portc();
extern void portd();
int flag1=0; //端口输出标志,用于端口输出控制
int flag2=0; //端口输出标志,用于端口输出控制
unsigned int Out_flag = 0;
interrupt void timer() //定时器中断子程序,数存单元作计数器例子
{
*(int *)0x300=*(int *)0x300+1; //时钟中断计数,使用绝对寻址方式
if(*(int *)0x300 >= 1000) //计数超过 1000次
{
*(int *)0x300=0;
if(flag1==0)
{
flag1=1;
porta(); //调用PORTC汇编子程序
}
else
{
flag1=0;
portb(); //调用PORTB汇编子程序
}
//asm(" intr 18");//用于软件仿真时,产生软件中断,中断序号18,中断入口为外中断2 }
return;
}
interrupt void int2c() //外部中断服务子程序,变量作计数器例子
{
static int INT2_INT_NUM = 0; //定义整形计数器
INT2_INT_NUM++; //每次中断则计数器加1
if(INT2_INT_NUM % 2 == 0 ) //每两次按键XF闪烁一次
Out_flag = 0;
else
Out_flag = 1;
if( INT2_INT_NUM >= 1000 )
INT2_INT_NUM = 0;
if(flag2==0)
{
flag2=1;
portc(); //调用PORTC汇编子程序
}
else {
flag2=0;
portd(); //调用PORTD汇编子程序
}
}
main()
{
initial();//C调用汇编子程序
while(1){ //等待定时器和外部中断,转去执行中断服务子程序
asm(" nop");//C中嵌入汇编指令例子
if(Out_flag == 0 )//通过中断中标志位来控制端口
asm(" ssbx XF"); //点亮XF灯
else
asm(" rsbx XF"); //熄灭XF灯
}
}
2、初始化子程序 initial.asm
.title "initia.asm "
.mmregs
.global _initial ;定义可以外部调用的子程序
.text
;查看DSP的CLKMD寄存器内容,并查看实验书附录中clkmd寄存器初值 ;以及晶振频率来获得时钟运行频率
_initial: ;初始化子程序入口
ssbx INTM ; INTM=1,禁止所有可屏蔽中断
ld #0, DP ; 设置数据页指针DP=0
stm #0x3FF2,PMST
stm #0x0000,SWWSR;
ldm PMST,A ;修改IPTR
and #0x3f,A ;去掉IPTR
or #0x3f80,A ;IPTR位等于3F80
stlm a,PMST
stm #0, CLKMD ; 切换CPU内部PLL到分频模式
Statu: ldm CLKMD, A