STM32H743-ARM例程41-FMC_INDEP

目录

实验平台

硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器

软件:最新版本STM32CubeH7固件库STM32CubeMX v6.10.0,开发板环境MDK v5.35TCP&UDP测试工具,串口工具putty

网盘资料包:链接: https://pan.baidu.com/s/1Y3nwaY4SMxfoUsdqPm2R3w?pwd=inba 提取码: inba

FSMC的地址映射

  FMC是Flexible memory controller的缩写,译为灵活的静态存储控制器。它可以用于驱动包括PSRAM、SDRAM以及NAND FLSAH类型的存储器,也可以用于驱动液晶屏幕等模块。

  FSMC连接好外部存储器并初始化后,就可以直接通过访问地址来读写数据。因为外接的存储单元是映射到STM32的内部寻址空间的。FMC的地址映射如下所示。由于使用了FMC_NE1(FMC_CS)引脚作为片选信号,我们使用的是ARM的BANK1地址空间。

FSMC框图剖析

  如下图所示,GT7000核心板上,FMC协议需要ARM与FPGA之间有这么多IO相连,具体引脚的功能如下:

(1)FMC_CS(片选信号):低电平片选信号有效,高电平失能(默认状态为高:失能);

(2) FMC_NADV(地址有效信号):上升沿锁存地址的低位(FSMC复用地址模式时有用,独立地址模式是不用);

(3) FMC_RD(读信号):读数据信号,低电平有效,上升沿锁存数据,高电平失能(默认状态为高:失能);

(4) FMC_WR(写信号):写数据信号,低电平有效,上升沿锁存数据,高电平失能(默认状态为高:失能);

(5) FMC_AB23:16:地址总线;

(6) FMC_DB31:0:数据总线。

  相信细心的小伙伴们已经发现了,GT7000的FMC地址总线并不是从0位开始的,而是从16位开始的,这么做主要的目的是因为:STM32还配有一块SDRAM,占用了FMC地址线的0~15位。

  FMC分为两种通信模式:独立地址模式和复用地址模式。独立地址模式意味着地址总线只能用来传输地址数据,那么可使用的地址线只有FMC_AB23:16共8根,可访问的地址空间只有256个。如果独立地址模式下地址空间不够用,我们还可以使用复用地址模式,复用地址模式意味着地址总线+数据总线上的数据作为地址,那么整个BANK的地址空间都可以使用。

  当使用独立地址模式时,地址数据在ARM端需要左移18位才能被正常解析;在复用地址模式下,地址数据在ARM端要左移2位才能被正常解析。(在STM32使用32位数据位宽时,访问地址必须先左移2位.,才能正确输出地址信号)详见STM32参考手册22.6.1章节。

FMC读写FPGA的时序

  FMC外设支持输出多种不同的时序以便控制不同的存储器,共有ABCD四种模式,这里我们使用的是A模式读写,下图为FMC模式A的读时序。

FMC模式A的写时序如下。

  本次实验内容为,将STM32H743的引脚连接到FPGA,FMC配置为非复用模式,向FPGA发送和接受数据。本实验为了验证ARM和FPGA之间的数据传输是否正确,在STM32程序中自动生成数据,通过FMC向FPGA写数据并读回进行对比判断。两组数据相同,说明通信正常;不同,则说明通信异常。FPGA内部例化了RAM(RAM IP核的使用详见后面单双口RAM数据存取实验),用于缓存STM32发过来的数据,并对FMC的信号进行处理,实现数据的接收。

  所谓独立地址模式,就是A23:16地址线只发送地址,DB15:0数据传输线只发送数据。本实验FPGA例化的RAM深度为256字节,所以地址线需要占用A23:16的8位。由于地址线和数据线是相互独立的,因此不需要NADV信号进行判断,驱动较为简单。

STM32CubeMX生成工程

我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置FMC部分如下图所示:




实验步骤

  1、依据前面相关章节所述,新建一个名为fmc_indep的工程。双击桌面Vivado 2020.2图标打开Vivado开发环境,按如下操作步骤进行。

(1)起始页------点击Create Project;

(2)向导起始页------点击Next;

(3)Project Name界面------工程名fmc_indep,设置工程路径,点击Next;

(4)Project Type界面------选择RTL Project,点击Next;

(5)Default Part界面------Family选择Artix-7,Speed grade选择-2,GT7000 100T的核心板,Package选择fgg484,在过滤后的结果中选择目标器件为xc7a100tfgg484-2;GT7000 200T的核心板,Package选择fbg484,在过滤后的结果中选择目标器件为xc7a200tfbg484-2,点击Next;

(6)New Project Summary界面------确认无误后,点击Finish完成。

建立好的工程如下图所示。

  2、新建工程设计文件。具体步骤如下。

(1)主窗口左侧边栏Project Manager下点击Add Sources;

(2)Add Source弹窗选择Add or create design sources,点击Next;

(3)Add or Create Design Source弹窗点击Create File;

(4)Create Source File弹窗,File name设置为fmc_indep,其它默认,点击OK;

(5)以相同方式添加fmc_ctrl.v和led_ctrl.v文件;

(6)Add or Create Design Source窗口点击Finish;

(7)Define Module弹窗点击OK,之后的弹窗点击Yes,文件新建完成。如下图所示,Source窗口文件已经加入工程了。

  3、添加并配置PLL IP核使其输出100MHz时钟。具体步骤如下。

(1)主窗口左侧边栏Project Manager下点击IP Catalog;

(2)IP Catalog窗口搜索框内输入CLOCK,点击搜索;

(3)双击Clocking Wizard,弹出配置窗口;

(4)Clocking Options标签页下,Input Clock Information中clk_in1时钟频率修改为50;

(5)Output Clocks标签页下,Enable Optional Inputs/Outputs for MMCM/PLL中取消勾选reset和locked;

(6)其余选项保持默认,点击OK,Generate Output Products弹窗点击Generate。

  4、添加并配置RAM IP核。具体步骤如下。

(1)主窗口左侧边栏Project Manager下点击IP Catalog;

(2)IP Catalog窗口搜索框内输入block memory,点击搜索;

(3)双击Clocking Wizard,弹出配置窗口;

(4)将IP核命名为my_ram;

(5)在Port A Options标签页中,设置数据位宽为32bit,设置读写深度为256,Operating Mode选择No Change,取消勾选Primitives Output Register;

(6)其余选项保持默认,点击OK,在Generate Output Products弹窗点击Generate。

  5、接下来进行Verilog代码的设计。

csharp 复制代码
//--------------------wire---------------------------------//
wire rd = (fmc_csn | fmc_rdn);
wire wr = (fmc_csn | fmc_wrn);

//--------------------clk----------------------------------//
reg wr_clk1,wr_clk2;    

always @(posedge clk_100m or negedge rst_n)
    begin
        if(!rst_n)
            begin
                wr_clk1 <= 1'd1;
                wr_clk2 <= 1'd1;
            end
        else
            {wr_clk2,wr_clk1} <= {wr_clk1,wr};  //wr打一拍
    end
    
wire clk = (!wr_clk1 | !rd);
    
//--------------------db_out-------------------------------//
wire [31:0]db_out;
assign fmc_db = !rd ? db_out : 32'hzzzz;

wire [31:0] db_in;
assign db_in = fmc_db;

//--------------------my_ram-------------------------------//
my_ram my_ram_inst(
    .clka(clk),
    .ena(1'b1),//ram使能
    .wea(!wr&rd),//ram 读写使能信号,高电平写入,低电平读出
    .addra(fmc_ab),
    .dina(db_in),
    .douta(db_out)
);

  6、将上面的设计内容进行分析和综合直至没有错误以及警告,给信号约束一下引脚,最终生成bit流文件。

  7、给板子接上下载器和电源,如下图所示。

  8、将生成的bit流文件下载进板子。

注:Vivado集成开发环境可以参考网盘资料包GT7000_REV1.0\11_FPGA实验例程包\1_vivado开发环境安装

实验现象

(1)FPGA程序下载完成后,核心板上FPGA LED灯每隔0.5秒钟亮一下,按住FPGA RST按键后复位,FPGA LED灯熄灭,松开后FPGA LED灯继续闪烁;

(2)使用putty软件打开串口,端口号在Windows设备管理器中查看,波特率设为115200,点击"Open"打开putty串口终端。

(3)打开ARM工程,将ARM工程编译并下载进GT7000内。可以看到putty串口终端中打印如下信息。绿色打印的数据为ARM生成并写入FPGA后,又从FPGA内读出来的数据,OK 说明数据无误。

(4)也可以在FPGA工程中添加ILA,观察读写时序。

相关推荐
老k一步步来6 小时前
STM32 HAL库CAN通信核心函数详解,参数以及作用
stm32·单片机·嵌入式硬件
gwf2166 小时前
SSD读写速度深度解析:顺序读写vs随机读写、IOPS、延迟,你的硬盘性能到底怎么看?
git·嵌入式硬件·缓存·github·智能硬件
Freak嵌入式10 小时前
版本混乱 / 依赖缺失?uPyPi:MicroPython 版 PyPI,彻底解决库管理混乱
linux·服务器·数据库·单片机·嵌入式硬件·性能优化·依赖倒置原则
wuyk55510 小时前
77.嵌入式 C 语言中 enum 枚举的工程化实践:告别魔法数字,提升代码可维护性
c语言·开发语言·stm32·单片机·嵌入式硬件
义嘉泰11 小时前
XT25F128F-W Flash芯片全面解析
人工智能·嵌入式硬件·芯片
QH1392923188011 小时前
Keysight N9917B N9918B手持式综合微波分析仪
网络·科技·嵌入式硬件·集成测试·信息与通信
longxingiot11 小时前
轻量化单片机数传终端降低物联网开发门槛
单片机·嵌入式硬件·物联网
亿道电子Emdoor12 小时前
【Arm】MSP和PSP的区别简介
c语言·arm开发·单片机·mcu
国产HT1621B12 小时前
YL1650 LED驱动芯片详解:从原理到实战应用(附51单片机驱动代码)
stm32·单片机·嵌入式硬件·mcu·fpga开发·lcd驱动