硬件准备
ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接
接口功能介绍
ADSP-BF533的 16 个 PF 接口都可以做为外部中断来使用。要使用 PF 的外部中断,需要为 PF 脚选择一个中断源,设置中断触发方式,为中断设置一个中断优先级,并且使能中断。
FIO_MASKA_D 和 FIO_MASKB_D:用来为 PF 管脚设置中断源,ADSP-BF53x 共有 PFA 和 PFB 两个中断源,通过选择配置这两个寄存器,使用不同的中断源。
SIC_IARx:设置中断优先等级。每个中断源都有一个默认的优先等级,如不对该寄存器配置,则可以使用默认的中断优先等级配置中断源。
从表中可以看出 PF 管脚相关的中断源 PFA 和 PFB 位于 SIC_IAR2,其默认配置值都为 5,根据其配置值,通过下表获知其对应的中断等级为 IVG12,如将 SIC_IAR2 配置值改为下表中的数值,则中断等级变为该数值对应的中断等级。
SIC_IMASK:中断屏蔽寄存器,使能中断使用。
函数:
register_handler(ik_ivg12, FlagA_ISR);
中断等级注册函数,该函数在头文件 “exception.h”中定义,定义该头文件后直接可以使用,其功能是告知中断管理器定义的中断标识符为 FlagA_ISR 和中断等级为 12 级。
EX_INTERRUPT_HANDLER(FlagA_ISR);
中断函数,该函数在头文件 “exception.h”中定义,当触发中断后,会进入该函数执行。
接口寄存器说明
SIC_IARx:中断等级设置寄存器
SIC_IMASK:中断屏蔽寄存器
核心代码分析
PF 口设置使用外部中断:
*pFIO_INEN |= PF0|PF1; //设置 PF0,PF1 输入使能
*pFIO_DIR &=~(PF0|PF1); //设置 PF0,PF1 为输入接口
*pFIO_EDGE |= PF0|PF1; //设置为沿触发
*pFIO_MASKA_D |= PF0|PF1; //使用中断源为 PFA,使能 PF 外部中断
配置外部中断:
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xffffffff;
*pSIC_IAR2 = 0xffff5fff; //设置中断等级参数为 5
register_handler(ik_ivg12, FlagA_ISR); //告知中断管理器使用中断等级为 12,中断标志为 FlagA_ISR
*pSIC_IMASK = 0x00080000; //使能外部中断
中断函数:
EX_INTERRUPT_HANDLER(FlagA_ISR) //设置中断函数标志为 FlagA_ISR
{
if(*pFIO_FLAG_D == PF0) //判断是否为 PF0 中断
{
printf(“interrupt is PF0!\n”);
}
else if(*pFIO_FLAG_D == PF1) //判断是否为 PF1 中断
{
printf(“interrupt is PF1!\n”);
}
*pFIO_FLAG_C = PF0|PF1; //清除中断标志
}
代码实现功能
通过 PF0 和 PF1 接口作为外部中断信号触发管脚,当有下降沿出发时进入中断函数,在中断函数中判断是哪一个 PF 脚设置了中断,打印出中断 PF 脚信息。
运行代码后,利用接地的导线触发 PF0 和 PF1 管脚,会进入相应的中断,打印出中断信息。
完整代码展示
#include
#include
#define pDEVICE_OE (volatile unsigned short *)0x20320000
#define PF0_SET 0x40
EX_INTERRUPT_HANDLER(FlagA_ISR);
void Set_PLL(unsigned int pmsel,unsigned int pssel)
{
unsigned int new_PLL_CTL;
*pPLL_DIV = pssel;
asm(“ssync;”);
new_PLL_CTL = (pmsel & 0x3f) << 9;
*pSIC_IWR |= 0xffffffff;
if (new_PLL_CTL != *pPLL_CTL)
{
*pPLL_CTL = new_PLL_CTL;
asm(“ssync;”);
asm(“idle;”);
}
}
void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0xffc07bb0;
*pEBIU_AMGCTL = 0x000f;
}
void Init_SDRAM(void)
{
*pEBIU_SDRRC = 0x00000817;
*pEBIU_SDBCTL = 0x00000013;
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}
void init_PF0_IN(void)
{
*pFIO_DIR &= ~PF0;
*pFIO_INEN |= PF0;
}
void Init_Flags(void)
{
*pFIO_INEN |= PF0|PF1;
*pFIO_DIR &=~(PF0|PF1);
*pFIO_EDGE |= PF0|PF1;
*pFIO_MASKA_D |= PF0|PF1;
}
void Init_Interrupts(void)
{
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xffffffff;
*pSIC_IAR2 = 0xffff5fff;
register_handler(ik_ivg12, FlagA_ISR);
*pSIC_IMASK = 0x00080000;
}
void Set_CPLD(void)
{
*pDEVICE_OE &= ~PF0_SET ; //设置CPLD释放PF0接口
}
EX_INTERRUPT_HANDLER(FlagA_ISR)
{
if((*pFIO_FLAG_D&PF0) == PF0)
{
printf(“interrupt is PF0!\n”);
}
else if((*pFIO_FLAG_D&PF1) == PF1)
{
printf(“interrupt is PF1!\n”);
}
*pFIO_FLAG_C = PF0|PF1;
}
void main(void)
{
Set_PLL(16,4);
Init_EBIU();
Init_SDRAM();
Set_CPLD();
Init_Flags();
Init_Interrupts();
while(1);
}