目的:
理解FLAG可编程作为输入输出引脚,并且能够利用按键进行相应FLAG(FLAG0,FLAG1)标志的输入来相应的FLAG标志(FLAG2,FLAG3)输出来控制与之相连的LED。掌握外部中断和定时器中断的设置以及其响应过程,理解外部硬件可以直接与IRQx相连来产生外部硬件中断进行相应的处理。
任务:
1:通过改变Flag输出状态控制LED亮灭
2:通过外部中断IRQ0控制DMA传输
3:通过外部中断IRQ0控制Flag输出状态
4:利用timer0定时器中断控制Flag输出状态
1. 通过改变Flag输出状态控制LED亮灭
原理:
EZ-KIT Lite评估板上每个DSP都有4个Flag Pins,这是一种可以控制方向(input\output)的管脚。在评估板上这些管脚有2个接Button按钮,有2个接LED,他们在电路板上的分布如下图:
在上面图中,我已经把按键和LED灯实际名称如(如LED4,SW9)和DSP上的名称(如flag2,flag0)都对应起来,下表简单介绍了这些Flag Pins的作用:也就是说,每片DSP上的Flag0和Flag1作为按键Button输入,而Flag2和Flag3作为LED输出。
Flag0和Flag1作为按键:
Flag0和Flag1作为按键,当它们初始化为输入后,在没有按下时为低电平(注意中间有个反相器),而按下按键时为高电平。所以SQSTAT寄存器在按下按键时FLG0或FLG1才为1,这样可以使用判断语句来查询状态,判断是否按下。
Flag2和Flag3作为LED:
Flag2和Flag3作为LED,当她们初始化为输出后,FLAGREG中的FLAG2_OUT或FLAG3_OUT位,对其置位对应的LED才亮,而清零则LED熄灭。
Flag Pins的寄存器:
四个FLGA3-0管脚,都可配置为输入或输出,系统上电后默认是输入;
1.FLAGREG:(FLAGx_EN =0)输入,(FLAGx_EN =1)输出
2.输出时:FLAGREG中的FLAGx_OUT位,对其置位或清零
3 .输入时:SQSTAT中的FLGx位,查看状态。或者使用条件指令中的FLAGx_IN标志。
FLAGREG寄存器
SQSTAT寄存器中的FLGx位
调试步骤:
1)打开VisualDSP++,并新建一个工程文件,命名为”test3_1”,保存路径选择”D:\DSP\”;
2)新建C语言源程序文件,命名为” Flag.c”,并将文件添加至工程,并理解程序源代码;
3)新建或选择一个相应的调试会话Session (评估测试模式下的调试会话);
4)检查EZ-KIT板各SW设置是否正确,如下图;
5)用仿真器将PC与EZ-KIT板连接;
6)连接EZ-KIT板电源线,LED1(POWER)点亮、LED8(RESET)点亮,EZ-KIT板开始自动复位,复位完成后LED8熄灭,LED3点亮(USB MONITOR,注意此LED实际位置在USB上方),则表示EZ-KIT板与PC已经正常连接。
7)编译工程,在弹出的处理器选择窗口中,选择处理器A作为本次试验的处理器(即将DSP B[ID1]后面的仿真文件路径剪切到DSP A[ID0]后面的仿真文件路径框中),然后运行程序,观察实验板右下方LED的亮灭情况;
结果:
1)按照实验步骤,完成参考代码1实验,并记录实验现象;
2)按照实验步骤,理解参考代码2,并验证预期试验现象(按键控制LED在点亮和熄灭两种状态下切换);
3)修改程序代码2,使FLAG0_A对应的按键控制FLAG2_A输出(LED4)在熄灭和闪烁两种状态间切换。
参考源代码:
代码1:
#include<stdio.h>
#include<builtins.h>
#include<sysreg.h>
#include<defts201.h>
#define SET_FLAG_OUT(x) __builtin_sysreg_write(__FLAGREGST, (x) );
#define CLR_FLAG_OUT(x) __builtin_sysreg_write(__FLAGREGCL, (~(x)) );
int main( void )
{
int i;
__builtin_sysreg_write(__FLAGREGST, FLAGREG_FLAG2_EN | FLAGREG_FLAG3_EN); //将FLAG2, FLAG3设为输出模式,用于LED闪烁
__builtin_sysreg_write(__FLAGREGCL, ~( FLAGREG_FLAG0_EN|FLAGREG_FLAG1_EN) ); //将FLAG0, FLAG1设为输入模式,用于按键
while(1) {
SET_FLAG_OUT(FLAGREG_FLAG2_OUT);
CLR_FLAG_OUT(FLAGREG_FLAG3_OUT);
for(i=0; i<8000000; i++);
SET_FLAG_OUT(FLAGREG_FLAG3_OUT);
CLR_FLAG_OUT(FLAGREG_FLAG2_OUT);
for(i=0; i<8000000; i++);
}
}
代码2:
#include<stdio.h>
#include<builtins.h>
#include<sysreg.h>
#include<defts201.h>
#define SET_FLAG_OUT(x) __builtin_sysreg_write(__FLAGREGST, (x) );
#define CLR_FLAG_OUT(x) __builtin_sysreg_write(__FLAGREGCL, (~(x)) );
int main( void )
{
int i;
__builtin_sysreg_write(__FLAGREGST, FLAGREG_FLAG2_EN | FLAGREG_FLAG3_EN); //将FLAG2, FLAG3设为输出模式,用于LED闪烁
__builtin_sysreg_write(__FLAGREGCL, ~( FLAGREG_FLAG0_EN|FLAGREG_FLAG1_EN) ); //将FLAG0, FLAG1设为输入模式,用于按键
static int button0=0, button1=0;
static int led0=0, led1=0;
int sqstat=0;
while(1){
//如果button0按下,反转button0状态
sqstat = __builtin_sysreg_read(__SQSTAT);
if( sqstat & ( 1<<SQSTAT_FLG_P) ){ //按下按键为高电平
for(i=0; i<800000; i++); //按键消抖延时
sqstat = __builtin_sysreg_read(__SQSTAT);
if( sqstat & ( 1<<SQSTAT_FLG_P) )
button0 = ! button0;
}
//如果button1按下,反转button1状态
sqstat = __builtin_sysreg_read(__SQSTAT);
if( sqstat & ( 2<<SQSTAT_FLG_P) ){
for(i=0; i<800000; i++); //按键消抖延时
sqstat = __builtin_sysreg_read(__SQSTAT);
if(sqstat & ( 2<<SQSTAT_FLG_P) )
button1 = ! button1;
}
//根据button0状态,点亮/熄灭LED2
if(button0 == 0){
CLR_FLAG_OUT(FLAGREG_FLAG2_OUT);
} else {
SET_FLAG_OUT(FLAGREG_FLAG2_OUT);
}
//根据button1状态,点亮/熄灭LED3
if(button1 == 0){
CLR_FLAG_OUT(FLAGREG_FLAG3_OUT);
} else {
SET_FLAG_OUT(FLAGREG_FLAG3_OUT);
}
for(i=0; i<4000000; i++);
}
}