EPI (External Peripheral Interface) 翻译为片外设备接口,是一种用于连接片外设备或存储器的高速并行接口。
片外设备有多种工作方式,能够实现与各种片外设备的无缝连接。片外设备接口实际上与普通位处理器的地址/
数据总线非常相似,只不过片外设备只允许链接一种类型的设备。此外,片外设备还有一些增强的功能例如:
uDMA支持、支持时钟控制、支持片外FIFO缓冲。
EPI模块具有以下特性:
- 8位/16位/32位专用并行总线,用于连接片外设备或存储器
- 存储器接口支持自动步进式连续访问,且不受数据总线宽度的影响,因此能够实现直接从SDRAM、SRAM或Flash存储器中运行代码。
- 内置阻塞/非阻塞式读操作
- 用微型直接内存访问(uDMA)有效地传输数据
通用模式。
同步动态随机访问存储器(SDRAM)模式:
支持16位宽的SDRAM(单数据率),频率最高50MHz;支持低成本SDRAM,最大可达64M;内置自动刷新功能,
可访问任意快(block)或行(bank);负我那个地址/数据管教,竭力控制管脚数目。
主机总线模式:
传统8位/16位微控制器总线接口;可兼容许多常见的微控制器总线,如PIC,ATmega,8051,或其他单片机。还
能访问SRAM、NorFlash以及其他类型的并行总线接口设备,非复用模式下寻址能力为1Mb;支持地址/数据总
线复用和非复用;支持多种片选模式,如ALE、CSn、双CSn、ALE。
通用模式:
可用于同CPLD或FPGA进行快速数据交换,数据宽度可达32位;数据传输速度可达150MB/S,可选配置4~20地
址,支持时钟输出信号,读写选通信号。
并行GPIO:
1~32位必须经由FIFO输入输出,速度可控;使用自定义的外设操作或数字设备。
个人认为EPI优点在于其使用地址映射,向相应的地址(或者无地址线)写入数据并自动产生的时序,取代了传统
的根据时序编程的繁琐步骤,并大大提高的数据传输速度,减少阻塞,提高访问速度。
看一张EPI内部结构图:
当需要直接读写片外设备时,直接写相应的地址映射,一次最多可写4或5个字而不会发生阻塞,与此相反,读操
作在数据返回之前将始终阻塞。举例来说:基址为0xA000 0000 当需要向外部地址为0的设备写数据时,先定义
指针unsigned int *pointer =0xA000 0000 ;则使用语句: pointer0[+addr]=data ; 即可完成一次写数据操作。
LM3SXXX的EPI模块有一个寄存器(EPIBAUD)控制数据传输速度;EPIBAUD寄存器COUNT0 位,COUNT0为0时,
SYS_CLK=EPICLK,COUNT0不为零时,EPI_CLK = SysClk/((count0/1+1)*2)
这里讲一下主机总线模式(HB8/HB16):
主机总线模式支持地址数据复用/不复用;地址数据线各自有专用的管脚;连续读子模式;下图为EPI主机总线模
式下时序图:
HB8/HB16读操作时序图:
下图是EPI引脚图:
注:由于项目中使用HB8模式,所以主要介绍HB8,地址数据总线不复用:
以下为初始化代码:
#include "inc/hw_types.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "inc/hw_epi.h"
#include "driverlib/gpio.h"
#include "driverlib/epi.h"
#include "EPI0.h"
#define EPI_PORTC_PINS (GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4)
#define EPI_PORTD_PINS (GPIO_PIN_6 ) //WR
#define EPI_PORTE_PINS (GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTH_PINS (GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2 | \
GPIO_PIN_1 | GPIO_PIN_0)
volatile unsigned char *data;
void EPI_Init(void)
{
// The EPI0 peripheral must be enabled for use.
// 使能EPI接口
SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0);
//
// 使能各个使用的IO口
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
GPIOPinConfigure(GPIO_PH3_EPI0S0);//D0
GPIOPinConfigure(GPIO_PH2_EPI0S1);//D1
GPIOPinConfigure(GPIO_PC4_EPI0S2);//D2
GPIOPinConfigure(GPIO_PC5_EPI0S3);//D3
GPIOPinConfigure(GPIO_PC6_EPI0S4);//D4
GPIOPinConfigure(GPIO_PC7_EPI0S5);//D5
GPIOPinConfigure(GPIO_PH0_EPI0S6);//D6
GPIOPinConfigure(GPIO_PH1_EPI0S7);//D7
GPIOPinConfigure(GPIO_PE0_EPI0S8);//A0
GPIOPinConfigure(GPIO_PE1_EPI0S9);//A1
GPIOPinConfigure(GPIO_PH4_EPI0S10);//A2
GPIOPinConfigure(GPIO_PH5_EPI0S11);//A3
GPIOPinConfigure(GPIO_PD6_EPI0S29);//WR
// Configure the GPIO pins for EPI mode. All the EPI pins require 8mA
// drive strength in push-pull operation. This step also gives control of
// pins to the EPI module.
GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS);
GPIOPinTypeEPI(GPIO_PORTD_BASE, EPI_PORTD_PINS);
GPIOPinTypeEPI(GPIO_PORTE_BASE, EPI_PORTE_PINS);
GPIOPinTypeEPI(GPIO_PORTH_BASE, EPI_PORTH_PINS);
// Sets the clock divider for the EPI module. In this case set the
// divider to 48, making the EPIClock = SysClk/((count0/1+1)*2).
EPIDividerSet(EPI0_BASE, 48);
//
// Sets the usage mode of the EPI module. EPI_MODE_HB8
//
EPIModeSet(EPI0_BASE, EPI_MODE_HB8);
// 使用相同波特率 地址数据不复用 cs信号 字节读取
EPIConfigHB8Set(EPI0_BASE, EPI_HB8_MODE_ADDEMUX | EPI_HB8_WRWAIT_0
| EPI_HB8_RDWAIT_0 | EPI_HB8_CSCFG_CS, 0);//在这里启用了片选信号,实际并没有配置
// 映射到片外外设地址0xA000 0000
EPIAddressMapSet(EPI0_BASE, EPI_ADDR_PER_SIZE_256B | EPI_ADDR_PER_BASE_A);
while(HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_INITSEQ) //等待配置完成
{
}
data = (unsigned char *)0xA0000000;
data[0]=0x00; //output 0x00 at address 0x00
}
其他模式参照HB8也可以完成;
以上就是个人对EPI HB8的学习与理解。新手上路,求指导 ^_^