硬件准备
ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接
硬件设计原理图
功能介绍
ADSP-EDU-BF53x 开发板上扩展接口的 PORT2 和 PORT3 中引出了 6 个扩展 IO 接口输入接口,这些连接到了CPLD,通过 CPLD 将这些信号与 EBIU 总线和中断管脚 PF0 连接,并将中断数据地址映射在 CPLD 的当有扩展 IO有输入后,会触发 PF0 中断信号,同时可以通过 EBIU 总线访问中断功能映射到 CPLD 寄存器中的 INTERRUPT_DAT寄存器,通过访问该寄存器,可以获取键盘的中断源数据,通过读取 CPLD 的 EXT_IO_INDAT 寄存器,可以获取当前触发中断的扩展 IO 是哪一个。其寄存器映射如下:
DEVICE_OE 寄存器(读/写):
DEVICE_OE 寄存器地址:0x20320000
DEVICE_OE 寄存器设置硬件设备上一些控制管脚的电平状态。
DEVICE_OE 寄存器位功能:
PF0_SET:PF0 模拟 IIC 总线 SCL 接口或 PF0 中断功能使能
1:关闭 I2C_SCL 输入信号, 使能 PF0 中断信号
0:使能 I2C_SCL 输入信号,关闭 PF0 中断信号
使用中断时,将 PF0_SET 位设置为1。
EXT_IO_INDAT 寄存器(读唯一):
EXT_IO_INDAT 寄存器地址:0x203C0000
EXT_IO_INDAT 寄存器是扩展 IO 数据寄存器,通过该寄存器可以读取当前扩展 IO 是哪一个
EXT_IO_INDAT 寄存器位:
INTERRUPT_DAT 寄存器(读唯一):
INTERRUPT_DAT 寄存器地址:0x20360000
INTERRUPT_DAT 寄存器是板卡上所有中断资源的中断源数据寄存器,可以通过该寄存器数据判断出当前中断是哪一个设备产生的。
INTERRUPT_DAT 寄存器位功能:
当中断未触发时,读取的 Bit 位值为 1,当中断触发时,读取的 Bit 位值为 0,根据 Bit 位数据,获取中断设备。
SD_INF 为 SD 卡插入查询位,该 bit 位不会触发中断,只能通过读取该寄存器来查询 SD 卡是否插入。
硬件连接示意图
代码实现功能
代码实现了查询法和中断法两种读取扩展 IO 的方式,并将读到值与扩展 IO 位比较,打印出信息。
查询法:
需要将 main.c 文件中的宏开关“#define EXT_IN_INT_ENABLE”注释掉,运行代码后,程序会不停地扫描扩展 IO,等待扩展 IO 触发,扩展 IO 有被拉低后,则读取扩展 IO 位并打印出信息。
中断法:
需要将 main.c 文件中的宏开关“#define EXT_IN_INT_ENABLE”打开,运行代码后,程序会等待中断触发,中断触发后,判断是否为扩展 IO 中断,如果为扩展 IO 中断,则读取扩展 IO 位并打印出信息,否则退出中断等待下次中断触发。
测试步骤
- 将仿真器(ICE)与 ADSP-EDU-BF53x 开发板和计算机连接好。
- 先给 ADSP-EDU-BF53x 开发板上电,再为仿真器(ICE)上电。
- 运行 VisualDSP++ 5.0 软件,选择合适的 BF533 的 session 将仿真器与软件连接。
- 加载 VisualDSP++ 5.0 工程文件 BF53x_EXT_IN.dpj,编译并全速运行。
- 拉低扩展 IO。
代码会打印出以下信息。
程序源码
#include <cdefBF533.h>
#include <sys\exception.h>
#include “cpld.h”
//#define EXT_IN_INT_ENABLE
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_Flags(void)
{
*pFIO_INEN = 0x0001;
*pFIO_DIR = 0x0000;
*pFIO_EDGE = 0x0001;
*pFIO_POLAR = 0x0001;
*pFIO_MASKA_D = 0x0001;
}
void Init_Interrupts(void)
{
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xffffffff;
*pSIC_IAR2 = 0xffff5fff;
register_handler(ik_ivg12, FlagA_ISR);
*pSIC_IMASK = 0x00080000;
}
EX_INTERRUPT_HANDLER(FlagA_ISR)
{
unsigned char ext_io_data;
if(~*pINTERRUPT_DAT & EXT_IO_INT)
{
ext_io_data = ~*pEXT_IO_INDAT & 0x7F; //读外部IO状态
switch(ext_io_data)
{
case EXT_IN0: printf(“Ext_IO is EXT_IN0\n\r”); break;
case EXT_IN1: printf(“Ext_IO is EXT_IN1\n\r”); break;
case EXT_IN2: printf(“Ext_IO is EXT_IN2\n\r”); break;
case EXT_IN3: printf(“Ext_IO is EXT_IN3\n\r”); break;
case EXT_IN4: printf(“Ext_IO is EXT_IN4\n\r”); break;
case EXT_IN5: printf(“Ext_IO is EXT_IN5\n\r”); break;
case EXT_IN6: printf(“Ext_IO is EXT_IN6\n\r”); break;
default:
}
}
*pFIO_FLAG_C = 0x0001;
}
void main(void)
{
Set_PLL(16,4);
Init_EBIU();
printf(“Waiting ext_io input!\n”);
#ifdef EXT_IN_INT_ENABLE
Init_Interrupts();
ExtIO_Interrupt_Enable();
Interrupt_Enable();
Init_Flags();
#else
unsigned char ext_io_data;
while(1)
{
ext_io_data = ~*pEXT_IO_INDAT & 0x7F; //读外部IO状态
if(ext_io_data & EXT_IN0)
printf(“Ext_IO is EXT_IN0\n\r”);
if(ext_io_data & EXT_IN1)
printf(“Ext_IO is EXT_IN1\n\r”);
if(ext_io_data & EXT_IN2)
printf(“Ext_IO is EXT_IN2\n\r”);
if(ext_io_data & EXT_IN3)
printf(“Ext_IO is EXT_IN3\n\r”);
if(ext_io_data & EXT_IN4)
printf(“Ext_IO is EXT_IN4\n\r”);
if(ext_io_data & EXT_IN5)
printf(“Ext_IO is EXT_IN5\n\r”);
if(ext_io_data & EXT_IN6)
printf(“Ext_IO is EXT_IN6\n\r”);
}
#endif
while(1);
}