| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-07-10 | gingko | 初次建立 | ===== 实验二十八:FSMC实验——文读写FPGA ===== ==== 一、 实验目的与意义 ==== - 了解STM32 FSMC结构。 - 了解STM32 FSMC特征。 - 掌握FSMC的使用方法。 - 掌握STM32 HAL库中FSMC属性的配置方法。 - 掌握KEIL MDK 集成开发环境使用方法。 ==== 二、 实验设备及平台 ==== - iCore4 双核心板[[https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22598974120.15.5923532fsFrHiE&id=551864196684|点击购买]]。 - JLINK(或相同功能)仿真器[[https://item.taobao.com/item.htm?id=554869837940|点击购买]]。 - Micro USB线缆。 - USB-Blaster 和USB线。 - Keil MDK 开发平台。 - STM32CubeMX开发平台。 - 装有WIN XP(及更高版本)系统的计算机。 ==== 三、 实验原理 ==== === 1、FSMC简介 === * FSMC(Flexible Static Memory Controller,可变静态存储控制器)是STM32系列采用的一种新型的存储器扩展技术。在外部存储器扩展方面具有独特的优势,可根据系统的应用需要,方便地进行不同类型大容量静态存储器的扩展。 * FSMC(Flexible Static Memory Controller,可变静态存储控制器)是STM32系列中内部集成256 KB以上FlaSh,后缀为xC、xD和xE的高存储密度微控制器特有的存储控制机制。之所以称为“可变”,是由于通过对特殊功能寄存器的设置,FSMC能够根据不同的外部存储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度,从而使得STM32系列微控制器不仅能够应用各种不同类型、不同速度的外部静态存储器,而且能够在不增加外部器件的情况下同时扩展多种不同类型的静态存储器,满足系统设计对存储容量、产品体积以及成本的综合要求。 * 可变存储控制器 (FMC) 包括以下3个存储控制器: * NOR/PSRAM 存储控制器。 * NAND 存储控制器。 * 同步DRAM (SDRAM/Mobile LPSDR SDRAM) 控制器。 === 2、FMC主要特性 === * FMC功能块可连接:同步/异步静态存储器、SDRAM存储器和NAND Flash。其主要用途有: * 将AHB数据通信事务转换为适当的外部器件协议。 * 满足外部存储器器件的访问时间要求。 * 所有外部存储器共享地址、数据和控制信号,但有各自的片选信号。FMC一次只能访问一个外部器件。 * FMC控制器的主要特性如下: * 连接静态存储器映射的器件: * –静态随机访问存储器(SRAM)。 * –NOR Flash/OneNAND Flash。 * –PSRAM(4个存储区域)。 * –带有硬件ECC的NAND Flash存储器,可检查多达8KB的数据。 * 连接同步DRAM(SDRAM/Mobile LPSDR SDRAM)存储器 * 支持突发模式,能够更快速地访问同步器件(如NOR Flash、PSRAM和SDRAM) * 可编程连续时钟输出以支持异步和同步访问 * 具有8位、16位或32位宽的数据总线 * 每个存储区域有独立的片选控制 * 每个存储区域可独立配置 * 写使能和字节通道选择输出,可配合PSRAM、SRAM和SDRAM器件使用 * 外部异步等待控制 * 16x32位深度写FIFO * SDRAM控制器具有可缓存的6x32位深度读FIFO(6x14位地址标记)。 * 写FIFO由所有存储控制器所共用,包括: * 写数据FIFO,用于存储要写入存储器的AHB数据(最多32位)以及AHB传输的一个控制位(突发或非连续模式)。 * 写地址FIFO,用于存储AHB地址(最多28位)以及AHB数据大小(最多2位)。在突发模式下工作时,将仅存储起始地址,但越过页边界时除外(适用于PSRAM和SDRAM)。在此情况下,AHB突发传输将分成两个FIFO条目。 === 3、FMC框图 === * 框图如下图所示。 {{ :icore4:icore4_arm_hal_28_1.png?direct |}} * FMC 包含以下主要模块: * AHB 接口(包括 FMC 配置寄存器)。 * NOR Flash/PSRAM/SRAM 控制器。 * SDRAM 控制器。 * NAND 控制器。 === 4、FPGA简介 === * FPGA(Field Programmable Gate Array)是在PAL、GAL等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。 * FPGA 器件属于专用集成电路中的一种半定制电路,是可编程的逻辑列阵,能够有效的解决原有的器件门电路数较少的问题。FPGA 的基本结构包括可编程输入输出单元,可配置逻辑块,数字时钟管理模块,嵌入式块RAM,布线资源,内嵌专用硬核,底层内嵌功能单元。由于FPGA具有布线资源丰富,可重复编程和集成度高,投资较低的特点,在数字电路设计领域得到了广泛的应用。FPGA的设计流程包括算法设计、代码仿真以及设计、板机调试,设计者以及实际需求建立算法架构,利用EDA建立设计方案或HD编写设计代码,通过代码仿真保证设计方案符合实际要求,最后进行板级调试,利用配置电路将相关文件下载至FPGA芯片中,验证实际运行效果。 * FPGA采用了逻辑单元阵列LCA(Logic Cell Array)这样一个概念,内部包括可配置逻辑模块CLB(Configurable Logic Block)、输入输出模块IOB(Input Output Block)和内部连线(Interconnect)三个部分。 现场可编程门阵列(FPGA)是可编程器件,与传统逻辑电路和门阵列(如PAL,GAL及CPLD器件)相比,FPGA具有不同的结构。FPGA利用小型查找表(16×1RAM)来实现组合逻辑,每个查找表连接到一个D触发器的输入端,触发器再来驱动其他逻辑电路或驱动I/O,由此构成了既可实现组合逻辑功能又可实现时序逻辑功能的基本逻辑单元模块,这些模块间利用金属连线互相连接或连接到I/O模块。FPGA的逻辑是通过向内部静态存储单元加载编程数据来实现的,存储在存储器单元中的值决定了逻辑单元的逻辑功能以及各模块之间或模块与I/O间的联接方式,并最终决定了FPGA所能实现的功能,FPGA允许无限次的编程。 === 5、原理图 === * STM32F767上自带有FMC控制器,本实验将实现STM32和FPGA通信,FPGA 内部建立RAM块,FPGA桥接STM32和RAM块,实验首先向RAM块内写入数据,然后读取RAM块内的数据并验证。下图为原理图。 {{ :icore4:icore4_arm_hal_28_2.png?direct |}} ==== 四、 实验程序 ==== === 1、主函数 === int main(void) { int i; /* MCU 配置 */ /* 重置所有外设,初始化Flash接口和 Systick. */ HAL_Init(); /* 配置系统时钟 */ SystemClock_Config(); /* 初始化所有已配置的外设 */ MX_GPIO_Init(); MX_FMC_Init(); //向FPGA RAM中写入数据 for(i = 0;i < 512;i ++){ fpga_write(i, 2 * i); } //从FPGA RAM中读取数据 for(i = 0;i < 512;i ++){ if(fpga_read(i) != 2*i){ while(1){ LED_RED_ON; HAL_Delay(500); LED_RED_OFF; HAL_Delay(500); } } } //测试成功 LED_GREEN_ON; while (1) { //通过映射寄存器来控制FPGA三色LED循环点亮 FPGA_LED_RED_ON; FPGA_LED_GREEN_OFF; FPGA_LED_BLUE_OFF; HAL_Delay(500); FPGA_LED_RED_OFF; FPGA_LED_GREEN_ON; FPGA_LED_BLUE_OFF; HAL_Delay(500); FPGA_LED_RED_OFF; FPGA_LED_GREEN_OFF; FPGA_LED_BLUE_ON; HAL_Delay(500); } } === 2、FMC初始化 === void MX_FMC_Init(void) { FMC_NORSRAM_TimingTypeDef Timing; /** 执行NOR1存储器初始化序列*/ hnor1.Instance = FMC_NORSRAM_DEVICE; hnor1.Extended = FMC_NORSRAM_EXTENDED_DEVICE; /* hnor1.Init */ hnor1.Init.NSBank = FMC_NORSRAM_BANK1; //指定将使用的NORSRAM存储设备。 hnor1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_ENABLE; //指定地址和数据值在数据总线上多路复用 hnor1.Init.MemoryType = FMC_MEMORY_TYPE_NOR; //外部存储器的类型。 hnor1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; //外部存储设备的宽度 hnor1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; //禁用闪存的突发访问模式 hnor1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; //等待信号极性 hnor1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; //FMC等待时间 hnor1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;// FMC写操作使能 hnor1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;// 禁用FMC等待信号 hnor1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;// 禁用FMC扩展模式 hnor1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; // 禁止FMC异步等待 hnor1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;// FMC禁止写突发 hnor1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC; // FMC连续时钟 hnor1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE; //FMC写FIFO hnor1.Init.PageSize = FMC_PAGE_SIZE_NONE; //FMC页大小 /* Timing */ Timing.AddressSetupTime = 7; Timing.AddressHoldTime = 1; Timing.DataSetupTime = 6; Timing.BusTurnAroundDuration = 0; Timing.CLKDivision = 0; Timing.DataLatency = 0; Timing.AccessMode = FMC_ACCESS_MODE_A; /* ExtTiming */ if (HAL_NOR_Init(&hnor1, &Timing, NULL) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } === 3、FMC宏定义 === #define fpga_write(offset,data) *((volatile unsigned short int *)(0x60000000 + (offset << 1))) = data #define fpga_read(offset) *((volatile unsigned short int *)(0x60000000 + (offset << 1))) //FPGA三色LED控制寄存器地址 #define FPGA_LED_RED 10 #define FPGA_LED_GREEN 11 #define FPGA_LED_BLUE 12 //控制寄存器值 #define ON 0 //点亮相应LED #define OFF 1 //关闭相应LED //ARM控制LED命令 #define FPGA_LED_RED_ON fpga_write(FPGA_LED_RED,ON) #define FPGA_LED_RED_OFF fpga_write(FPGA_LED_RED,OFF) #define FPGA_LED_GREEN_ON fpga_write(FPGA_LED_GREEN,ON) #define FPGA_LED_GREEN_OFF fpga_write(FPGA_LED_GREEN,OFF) #define FPGA_LED_BLUE_ON fpga_write(FPGA_LED_BLUE,ON) #define FPGA_LED_BLUE_OFF fpga_write(FPGA_LED_BLUE,OFF) ==== 五、 实验步骤 ==== - 把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连); - 将USB-Blaster与iCore4的JTAG调试口相连; - 将跳线帽插到USB UART; - 把iCore4(USB UART)通过Micro USB线与计算机相连,为iCore4供电; - 打开Quartus II开发环境,打开本实验工程; - 烧写程序到iCore4上; - 打开Keil MDK 开发环境,并打开本实验工程; - 烧写程序到iCore4上; - 也可以进入Debug模式,单步运行或设置断点验证程序逻辑。 ==== 六、 实验现象 ==== - 先烧写FPGA程序,再烧写ARM程序,ARM程序烧写完毕后即开始读写测试,测试成功,绿色ARM·LED常亮,测试失败,红色ARM·LED闪烁。 - 测试成功,ARM通过映射寄存器来控制FPGA三色LED循环点亮。