很久以前的BF531的笔记,觉得有用分享出来。摘自于open dsp
ADSP-BF53x 处理器上有16 个PF 接口,这些接口就是通常所有的IO 接口,通过寄存器配置,每一个PF 接口都可以作为外部中断接口。
Blackfin 处理器的IO 使用与单片机不同,在使用前必须对该接口进行初始化,如告知接口的方向,如配置为输出接口,则直接配置输出接口电平信号,如配置为输入接口,需打开输入使能开关,配置输出信号触发方式,是否中断触发,是否双极性触发等等。初始化完成后,才能使用PF 接口。
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 脚置低
#gpio中断
ADSP-BF53x 的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”中定义,当触发中断后,会进入该函数执行。
##例子代码分析:
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; //清楚中断标志
}
PLL(Phase Locked Loop)是ADSP-BF53x 的内核和时钟设置的机制,叫做锁相环。通过PLL 配置当前处理器工作的
内核和系统时钟。
EBIU 接口是ADSP-BF53x 的外部总线接口,ADSP-BF53x 的EBIU 接口共有16 根数据线,19 根地址线,支持同步
的SDRAM 接入和异步的总线外设接入,ADSP-BF53x 的异步EBIU 接口共有4 个BANK,每个BANK 1MByte,
支持各种总线接口设备。
#BF53x_SPI
SPI 接口是4 线串口,可以连接SPIFLASH,SPI 接口的AD,DA 等等。ADSP-BF53x 的SPI 接口支持主机模式和从机模式,它有7 个SPI 从机片选,在主机模式下,它同时可以挂载7 个SPI 设备,还可以在主机模式或从机模式下进行BOOT 启动。
1、MOSI 主输入从输出接口,根据主机和设备模式确定功能
2、MISO 从输入主输出接口,根据主机和设备模式确定功能
3、SCK SPI时钟
4、SPISELx SPI设备选则接口
5、SPISS SPI从机片选接口
SPI 接口时钟最快可以到系统时钟的1/4,其配置公式为:
SCK Frequency = (Peripheral clock frequency SCLK)/(2 x SPI_BAUD)
1、SPI_CTL SPI 控制寄存器,配置SPI 工作模式及相位等
2、SPI_FLG SPI 从机选择寄存器,用于选择使用哪一个片选控制设备
3、SPI_STAT SPI 状态寄存器,获取SPI 当前工作状态
4、SPI_TDBR SPI 数据传输寄存器
5、SPI_RDBR SPI 数据接收寄存器
6、SPI_SHADOW SPI_RDBR 的影子寄存器,可用于读取数据
##例子代码分析
*pSPI_BAUD=2; //配置速率为1/4 系统时钟 SPI 速率 = SCLK/2*SPI_BAUD
*pSPI_FLG |=FLS2; //选择SPISEL2 接口
*pSPI_CTL = 0x1001|CPHA| CPOL; //配置模式为手动片选模式
*pSPI_CTL = (*pSPI_CTL | SPE); //使能SPI 接口
*pSPI_FLG &= ~FLG2; //将SPISEL2 拉到0
while(!(*pSPI_STAT & SPIF)); //查看SPI 传输状态是否完成
*pSPI_TDBR = 0x55; //将数据送入SPI 传输数据寄存器
*pSPI_FLG |= FLG2; //将SPISEL2 拉到1,完成数据传输
*pSPI_FLG &= ~FLG2; //将SPISEL2 拉到0
while(*pSPI_STAT & RXS)//查看SPI 传输状态是否有数据需要接收
i = *pSPI_RDBR; //读取数据
*pSPI_FLG |= FLG2; //将SPISEL2 拉到1,完成数据传输
ADSP-BF53x 的SPI 接口支持手动片选和自动片选两种模式,通过SPI_CTL 寄存器的CPHA 和CPOL 位配置, 例子代码采用的是手动片选模式,每次读取数据和数据读取结束后需要通过代码来选通和关闭片选.
ADSP-BF53x 上有3 个通用定时器,每个定时器有三种模式:
1. 脉冲宽度调制模式(PWM_OUT)
2. 脉冲宽度计数捕获模式(WDTH_CAP)
3. 外部事件模式(EXT_CLK)
##接口寄存器说明
TIMERx_CONFIG 定时器配置寄存器,用于设置定时器工作模式
TIMERx_WIDTH 定时器宽度寄存器,设置输出波形脉冲宽度
TIMERx_PERIOD 定时器周期寄存器,设置输出波形的周期
TIMERx_COUNTER 定时器计数寄存器,读取捕获的脉冲数量
TIMER_ENABLE 定时器使能寄存器
TIMER_DISABLE 定时器关闭寄存器
TIMER_STATUS 定时器状态寄存器
代码实现了将定时器配置为 PWM_OUT 模式,通过定时器中断来定时一个0x00800000 个系统的时间长度,定
时完成后,在中断内打印信息。
定时器没有单独的计时功能,所以如果计时,可以采用 PWM_OUT 模式,利用定时器中断来进行计时,同时
在芯片的TIMER0 管脚上,会有PWM 波形输出。
*pTIMER0_CONFIG = 0x0019; //配置定时器为PWM 模式
*pTIMER0_PERIOD = 0x00800000; //设置周期为0x00800000 个系统时钟
*pTIMER0_WIDTH = 0x00400000; //设置脉宽为0x00400000 个系统时钟
*pTIMER_ENABLE = 0x0001; //使能Timer0
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xffffffff;
*pSIC_IAR2 = 0xfffffff4; //配置中断等级数据为4
register_handler(ik_ivg11, TIMER0_ISR); //注册中断等级为11,标识符为TIMER0_ISR
*pSIC_IMASK = 0x00010000;
EX_INTERRUPT_HANDLER(TIMER0_ISR) //标识符为TIMER0_ISR 的中断函数
{
*pTIMER_STATUS = 0x0001; //清除定时器中断标志
printf("timer0 interrupt !\n"); //打印信息
}
UART(Universal Asynchronous Receiver/Transmitter (UART) port)接口,是全双工通用的串行接口,由RX 和TX两根线组成,扩展RS232 芯片可以直接和计算机串口通讯,通常作为调试用的命令和数据通讯接口。
UART_THR UART 传输数据寄存器
UART_RBR UART 接收缓存寄存器
UART_DLL UART 波特率配置低8 位寄存器
UART_DLH UART 波特率配置高8 位寄存器
UART_IER UART 中断使能寄存器
UART_IIR UART 中断识别寄存器
UART_LCR UART 线路控制寄存器
UART_MCR UART 调制控制寄存器
UART_LSR UART 线路状态寄存器
UART_SCR UART 暂存寄存器
UART_GCTL UART 全局控制寄存器
##例子代码分析
*pUART_GCTL=0x0009;
*pUART_LCR=0x0080;// DLAB=1 允许访问DLL 和DLH
*pUART_DLL=div; //将变量div 的值写入波特率配置寄存器
*pUART_DLH=div>>8; //DLL DLH 分别赋值
*pUART_LCR=0x0003;// 允许访问 RBR THR 和IER
*pUART_IER=0x0001;// 接收中断允许
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xf3ffffff; // UART 中断等级设置
*pSIC_IAR2 = 0xffffffff;
register_handler(ik_ivg10, UART_ISR); // 注册UART 中断等级为10,标志为UART_ISR
*pSIC_IMASK = 0x00004000; //使能UART 中断
*pUART_THR=TXbuf[i]; //向UART 传输数据寄存器写数据
while(!(*pUART_LSR&0x0020)); //等待传输完成
EX_INTERRUPT_HANDLER(UART_ISR) //UART 接收数据中断函数
{
if(*pUART_LSR&DR) //判断是否有新的数据。
{
if(cont>512) //防止buff 溢出,测试代码,将接收到的数据重复写入512 字节的buff
cont = 0;
RXbuf[cont]=*pUART_RBR; //读取数据
cont++;
}
}
代码实现了配置波特率为 9600,设定了数据接收中断,运行代码后,会将数组Txbuf 中的字符串通过串口发送出,当接收到数据后,会进入中断函数读取数据。
PPI(Parallel Peripheral Interface )接口在ADSP-BF53x 上常用于视频信号和同步数据的传输,是半双工接口,支持数据的采集和数据的传输。
ADSP-BF533x 上有一个16Bit 的PPI 接口,最高速度可以到系统时钟的1/2,有视频信号传输使用的行、列、场是三个同步信号,支持ITU656,ITU601 等模式,可兼容大部分视频相关的芯片。
PPI 接口自身不能产生时钟信号,所以PPICLK 信号必须由外部设备或者晶振提供,它没有专门的行,列同步信号管脚,在使用PPI 时,需采用与其复用的Timer1 和Timer2 管脚来作为行列同步信号管脚,PPI 接口的场同步管脚FS3 与PF3 脚复用,该信号是在传输电视视频信号时,指示当前传输的信号是奇场还是偶场信号,在通常不使用的情况下,该管脚必须下拉。PPI 接口与其他接口不同,他没有发送和接收数据的寄存器,不能采用Core 来操作数据,只能采用DMA 传输。PPI 接口管脚与复用定义:
PPI_CONTROL PPI 控制寄存器,用于配置PPI 工作模式
PPI_STATUS PPI 状态寄存器
PPI_COUNT PPI 传输计数寄存器,设置图像一条线由多少数据组成
PPI_DELAY PPI 延时计数寄存器,设置在传输时延时多少个时钟开始采数据
PPI_FRAME PPI 帧寄存器,用来设置一幅完整图像一帧的线条数
*pDMA0_START_ADDR = 0; //配置PPIDMA 数据起始地址
*pDMA0_X_COUNT = 480; //配置DMA 一行要传输多少次数据
*pDMA0_X_MODIFY = 2; //配置每次传输行地址的增量
*pDMA0_Y_COUNT = 286; //配置要传输多少行数据
*pDMA0_Y_MODIFY = 2; //配置每次列数据地址的增量
*pDMA0_CONFIG = 0x1034; //配置DMA 工作模式
*pPPI_CONTROL = 0x781e; //配置PPI 工作偶是
*pPPI_DELAY = 0; //配置时钟延时为0
*pPPI_COUNT = 479; //配置PPI 每行要传输480 次
*pPPI_FRAME = 286; //配置每帧图像有286 行
*pTIMER1_PERIOD = 525; //配置行同步信号产生的周期
*pTIMER1_WIDTH = 41; //配置行同步信号宽度
*pTIMER1_CONFIG = 0x00a9;//配置行同步信号工作模式
*pTIMER2_PERIOD = 150150;//配置列同步信号产生的周期
*pTIMER2_WIDTH = 5250; //配置列同步信号宽度
*pTIMER2_CONFIG = 0x00a9; //配置列同步信号工作模式
*pDMA0_CONFIG |= 0x1; //使能DMA
asm("ssync;"); //系统同步
*pPPI_CONTROL |= 0x1; //使能PPI
asm("ssync;"); //系统同步
*pTIMER_ENABLE|= 0x0006; //使能行场同步信号
asm("ssync;"); //系统同步
//PPI 的行场同步信号与TIMER1 和TIMER2 复用,所以要配置TIMER 寄存器来启动PPI 的同步信号。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/peace1213/article/details/47175885