ADSP-BF533的开发,有手就行(三)GPIO(含源代码)
BF533的GPIO详解
作者的话
BF533是ADI Blackfin系列DSP处理器里的最经典型号,这个DSP我用了20年,单就这一颗DSP来讲,我相信国内应该没有比我更资深的了,下面就来说一说这颗DSP。
这颗IC是Blackfin里的经典款,由于Blackfin系列DSP均是同一个内核,在我看来,会用BF533,就约等于会用ADI Blackfin全系列DSP。实际上也确实是这样,我本人是从2002年开始用BF533,后面继续做了BF527,BF524,BF537,BF547,BF548,BF561,BF518,BF512,BF504,BF506,BF592,BF706,BF707,BF609,BF608;几乎每一颗ADSP,我都有基于项目做过软硬件的开发,而这一切的基础就是BF533。
这个系列,我计划从内核架构开始,到外设、驱动、典型算法、软件应用、uclinux、ucos等方面,来说一说这颗DSP。
硬件准备
ADSP-EDU-BF533开发板:BF533全功能开发板
产品链接:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-5192690539.11.5c1d42b3yniNnQ&id=39598018589
AD-HP530ICE仿真器:ADI DSP专用仿真器
产品链接:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-5192690539.11.52dfbfa3xB7JE7&id=38007242820
AD-CMOS:CMOS摄像头子卡
AD-MEMS:ADI MEMS三轴加速度传感器子卡
AD-ADC:ADC采集子卡
AD-LCD:2.4寸LCD子卡
硬件链接
正文正式开始
我们从最基础的GPIO开始,先讲外设,这玩意不管是单片机,还是ARM,又或是FPGA,甚至SOC的芯片,都有GPIO,有共性,就好理解,让我们看看在ADI的DSP里头,GPIO是怎么一回事吧。
接口功能介绍
ADSP-BF53x 处理器上有 16 个 Programmable Flag 接口,简称 PF 接口,这些接口就是通常所有的 IO 接口,通过寄存器配置,可以输出电平和感知接口电平,每一个 PF 接口都可以作为外部中断接口。
在单片机上,通常如果设置一个 IO 接口输出时,直接将输出信号值付给该接口,如果作为输入时,直接通过该接口读取即可。
而Blackfin 处理器的 IO 使用与单片机不同,在使用前必须对该接口进行初始化,如告知接口的方向,如配置为输出接口,则直接配置输出接口电平信号,如配置为输入接口,需打开输入使能开关,配置输出信号触发方式,是否中断触发,是否双极性触发等等。初始化完成后,才能使用 PF 接口。
接口寄存器说明
核心代码分析
输入接口配置:
将 PF0 接口配置为输入接口,并且读出接口电平状态。
*pFIO_DIR &= ~PF0; //设置 PF0 为输入
*pFIO_INEN |= PF0; //输入使能
i = *pFIO_FLAG_D; //读取数据
输出接口配置:
将 PF0 接口配置为输出接口,使用两种方式设置 PF0 输出高低电平。
*pFIO_DIR |= PF0; //设置 PF0 为输出
*pFIO_FLAG_S |= PF0; //PF0 脚置高
*pFIO_FLAG_C |= PF0; //PF0 脚置低
*pFIO_FLAG_D |= PF0; //PF0 脚置高
*pFIO_FLAG_D &= ~PF0; //PF0 脚置低
代码实现功能
工程 BF53x_GPIO_IN.dpj 实现了读取 PF0 接口状态并打印出 PF 接口状态数据。
工程 BF53x_GPIO_OUT.dpj 实现了通过 PF0 接口不断的输出高低变化的电平。
完整源码展示
这里有两个工程,一个工程是IN,一个工程是OUT:
IN:
#include <cdefBF533.h>
#define pDEVICE_OE (volatile unsigned short *)0x20320000
#define PF0_SET 0x40
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 Set_CPLD(void)
{
*pDEVICE_OE &= ~PF0_SET ; //设置CPLD释放PF0接口
}
void main(void)
{
int i;
Set_PLL(16,4);
Init_EBIU();
Init_SDRAM();
Set_CPLD();
Init_PF0_IN();
while(1)
{
i = *pFIO_FLAG_D;
printf("PF data is %d\n",i);
}
}
OUT:
#include <cdefBF533.h>
#define pDEVICE_OE (volatile unsigned short *)0x20320000
#define PF0_SET 0x40
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_OUT(void)
{
*pFIO_DIR |= PF0;
}
void Set_CPLD(void)
{
*pDEVICE_OE &= ~PF0_SET ; //设置CPLD释放PF0接口
}
void main(void)
{
int i;
Set_PLL(16,4);
Init_EBIU();
Init_SDRAM();
Set_CPLD();
Init_PF0_OUT();
while(1)
{
*pFIO_FLAG_S |= PF0; //PF0脚置高
*pFIO_FLAG_C |= PF0; //PF0脚置低
*pFIO_FLAG_D |= PF0; //PF0脚置高
*pFIO_FLAG_D &= ~PF0; //PF0脚置低
}
}
关于ADI的DSP GPIO的原理以及源代码有任何问题均可以随时问我,本人很懂。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)