FMC总线应用控制32路高速IO扩展

FMC总线应用控制32路高速IO扩展

  • FMC的块区分配
  • 举例扩展IO驱动LED应用
  • FMC驱动
    • 配置MPU
    • 配置扩展IO
    • 配置FMC并口访问时序
    • 应用

仅供个人学习,来源于armfly。

为什么要做 IO 扩展,不是已经用了 240 脚的 H743XIH6 吗?因为开发板使用了 32 位 SDRAM 和RGB888 硬件接口,消耗 IO 巨大,所以必须得扩展了。扩展的 32 路高速 IO 非常实用,且使用简单,只需初始下 FMC,32 路 IO 就可以随意使用了。当前的扩展方式只支持高速输出。
FMC 总线扩展 32 路高速 IO 理解成 GPIO 的 ODR 寄存器就很简单了,其实就是一个东西。
FMC 扩展 IO 是对地址 0x60001000 的 32bit 数据空间的 0 和 1 的操作。GPIOA 的 ODR 寄存器是对地址 0x40000000 + 0x18020000 + 0x14 空间的操作。但只能操作 16 个引脚。
使用总线的优势就在这里了,相当于在 GPIOA 到 GPIOK 的基础上,又扩展出 GPIOL 和 GPIOM。

FMC的块区分配

FMC 总线可操作的地址范围 0x60000000 到 0xDFFFFFFF,具体的框图如下:
在这里插入图片描述

举例扩展IO驱动LED应用

操作LED的亮灭,就是操作FMC数据引脚D8、D9、D10和D11
在这里插入图片描述

FMC驱动

配置MPU

实际测试发现,使能 FMC_NE1 所管理的存储区的 Cache 功能后,会出现扩展 IO 的 NE 片选和 NWE信号输出 2 次的问题。经过各种 Cache 方式配置、FMC 带宽配置、操作 FMC 时的数据位宽设置,发现禁止了 Cache 功能就正常了,也就是说,设置 FMC_NE1 所管理的存储区 MPU 属性为 Device 或者Strongly Ordered 即可。

/* 配置 FMC 扩展 IO 的 MPU 属性为 Device 或者 Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);

配置扩展IO

static void HC574_ConfigGPIO(void)
{
	/*
	安富莱 STM32-H7 开发板接线方法:4 片 74HC574 挂在 FMC 32 位总线上。1 个地址端口可以扩展出 32 个 IO
	PD0/FMC_D2
	PD1/FMC_D3
	PD4/FMC_NOE ---- 读控制信号,OE = Output Enable , N 表示低有效
	PD5/FMC_NWE -XX- 写控制信号,AD7606 只有读,无写信号
	PD8/FMC_D13
	PD9/FMC_D14
	PD10/FMC_D15
	PD14/FMC_D0
	PD15/FMC_D1
	PE7/FMC_D4
	PE8/FMC_D5
	PE9/FMC_D6
	PE10/FMC_D7
	PE11/FMC_D8
	PE12/FMC_D9
	PE13/FMC_D10
	PE14/FMC_D11
	PE15/FMC_D12
	PG0/FMC_A10 --- 和主片选 FMC_NE2 一起译码
	PG1/FMC_A11 --- 和主片选 FMC_NE2 一起译码
	XX --- PG9/FMC_NE2 --- 主片选(OLED, 74HC574, DM9000, AD7606)
	--- PD7/FMC_NE1 --- 主片选(OLED, 74HC574, DM9000, AD7606)
	+-------------------+------------------+
	+ 32-bits Mode: D31-D16 +
	+-------------------+------------------+
	| PH8 <-> FMC_D16 | PI0 <-> FMC_D24 |
	| PH9 <-> FMC_D17 | PI1 <-> FMC_D25 |
	| PH10 <-> FMC_D18 | PI2 <-> FMC_D26 |
	| PH11 <-> FMC_D19 | PI3 <-> FMC_D27 |
	| PH12 <-> FMC_D20 | PI6 <-> FMC_D28 |
	| PH13 <-> FMC_D21 | PI7 <-> FMC_D29 |
	| PH14 <-> FMC_D22 | PI9 <-> FMC_D30 |
	| PH15 <-> FMC_D23 | PI10 <-> FMC_D31 |
	+------------------+-------------------+
	*/
	GPIO_InitTypeDef gpio_init_structure;
	/* 使能 GPIO 时钟 */
	__HAL_RCC_GPIOD_CLK_ENABLE();
	__HAL_RCC_GPIOE_CLK_ENABLE();
	__HAL_RCC_GPIOG_CLK_ENABLE();
	__HAL_RCC_GPIOH_CLK_ENABLE();
	__HAL_RCC_GPIOI_CLK_ENABLE();
	/* 使能 FMC 时钟 */
	__HAL_RCC_FMC_CLK_ENABLE();
	/* 设置 GPIOD 相关的 IO 为复用推挽输出 */
	gpio_init_structure.Mode = GPIO_MODE_AF_PP;
	gpio_init_structure.Pull = GPIO_PULLUP;
	gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	gpio_init_structure.Alternate = GPIO_AF12_FMC;
	/* 配置 GPIOD */
	gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7 |
	 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
	 GPIO_PIN_15;
	HAL_GPIO_Init(GPIOD, &gpio_init_structure);
	/* 配置 GPIOE */
	gpio_init_structure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
	 GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |
	 GPIO_PIN_15;
	HAL_GPIO_Init(GPIOE, &gpio_init_structure);
	/* 配置 GPIOG */
	gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
	HAL_GPIO_Init(GPIOG, &gpio_init_structure);
	/* 配置 GPIOH */
	gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12
	| GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
	HAL_GPIO_Init(GPIOH, &gpio_init_structure);
	/* 配置 GPIOI */
	gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_6
	| GPIO_PIN_7 | GPIO_PIN_9 | GPIO_PIN_10;
	HAL_GPIO_Init(GPIOI, &gpio_init_structure);
}

配置FMC并口访问时序

static void HC574_ConfigFMC(void)
{
	SRAM_HandleTypeDef hsram = {0};
	FMC_NORSRAM_TimingTypeDef SRAM_Timing = {0};
		
	hsram.Instance  = FMC_NORSRAM_DEVICE;
	hsram.Extended  = FMC_NORSRAM_EXTENDED_DEVICE;

    /* FMC使用的HCLK3,主频200MHz,1个FMC时钟周期就是5ns */
	/* SRAM 总线时序配置 4-1-2-1-2-2 不稳定,5-2-2-1-2-2 稳定 */  
	SRAM_Timing.AddressSetupTime       = 5;  /* 5*5ns=25ns,地址建立时间,范围0 -15个FMC时钟周期个数 */
	SRAM_Timing.AddressHoldTime        = 2;  /* 地址保持时间,配置为模式A时,用不到此参数 范围1 -15个时钟周期个数 */
	SRAM_Timing.DataSetupTime          = 2;  /* 2*5ns=10ns,数据保持时间,范围1 -255个时钟周期个数 */
	SRAM_Timing.BusTurnAroundDuration  = 1;  /* 此配置用不到这个参数 */
	SRAM_Timing.CLKDivision            = 2;  /* 此配置用不到这个参数 */
	SRAM_Timing.DataLatency            = 2;  /* 此配置用不到这个参数 */
	SRAM_Timing.AccessMode             = FMC_ACCESS_MODE_A; /* 配置为模式A */

	hsram.Init.NSBank             = FMC_NORSRAM_BANK1;              /* 使用的BANK1,即使用的片选FMC_NE1 */
	hsram.Init.DataAddressMux     = FMC_DATA_ADDRESS_MUX_DISABLE;   /* 禁止地址数据复用 */
	hsram.Init.MemoryType         = FMC_MEMORY_TYPE_SRAM;           /* 存储器类型SRAM */
	hsram.Init.MemoryDataWidth    = FMC_NORSRAM_MEM_BUS_WIDTH_32;	/* 32位总线宽度 */
	hsram.Init.BurstAccessMode    = FMC_BURST_ACCESS_MODE_DISABLE;  /* 关闭突发模式 */
	hsram.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;   /* 用于设置等待信号的极性,关闭突发模式,此参数无效 */
	hsram.Init.WaitSignalActive   = FMC_WAIT_TIMING_BEFORE_WS;      /* 关闭突发模式,此参数无效 */
	hsram.Init.WriteOperation     = FMC_WRITE_OPERATION_ENABLE;     /* 用于使能或者禁止写保护 */
	hsram.Init.WaitSignal         = FMC_WAIT_SIGNAL_DISABLE;        /* 关闭突发模式,此参数无效 */
	hsram.Init.ExtendedMode       = FMC_EXTENDED_MODE_DISABLE;      /* 禁止扩展模式 */
	hsram.Init.AsynchronousWait   = FMC_ASYNCHRONOUS_WAIT_DISABLE;  /* 用于异步传输期间,使能或者禁止等待信号,这里选择关闭 */
	hsram.Init.WriteBurst         = FMC_WRITE_BURST_DISABLE;        /* 禁止写突发 */
	hsram.Init.ContinuousClock    = FMC_CONTINUOUS_CLOCK_SYNC_ONLY; /* 仅同步模式才做时钟输出 */
    hsram.Init.WriteFifo          = FMC_WRITE_FIFO_ENABLE;          /* 使能写FIFO */

	/* 初始化SRAM控制器 */
	if (HAL_SRAM_Init(&hsram, &SRAM_Timing, &SRAM_Timing) != HAL_OK)
	{
		/* 初始化错误 */
		Error_Handler(__FILE__, __LINE__);
	}
}

应用


#define  HC574_PORT	 *(uint32_t *)0x60001000

__IO uint32_t g_HC574;	/* 保存74HC574端口状态 */

static void HC574_ConfigGPIO(void);
static void HC574_ConfigFMC(void);

/*
*********************************************************************************************************
*	函 数 名: bsp_InitExtIO
*	功能说明: 配置扩展IO相关的GPIO. 上电只能执行一次。
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitExtIO(void)
{
	HC574_ConfigGPIO();
	HC574_ConfigFMC();
	
	/* 将开发板一些片选,LED口设置为高 */
	g_HC574 = (NRF24L01_CE | VS1053_XDCS | LED1 | LED2 | LED3 | LED4);
	HC574_PORT = g_HC574;	/* 写硬件端口,更改IO状态 */
}

/*
*********************************************************************************************************
*	函 数 名: HC574_SetPin
*	功能说明: 设置74HC574端口值
*	形    参: _pin : 管脚号, 0-31; 只能选1个,不能多选
*			  _value : 设定的值,0或1
*	返 回 值: 无
*********************************************************************************************************
*/
void HC574_SetPin(uint32_t _pin, uint8_t _value)
{
	if (_value == 0)
	{
		g_HC574 &= (~_pin);
	}
	else
	{
		g_HC574 |= _pin;
	}
	HC574_PORT = g_HC574;
}

/*
*********************************************************************************************************
*	函 数 名: HC574_TogglePin
*	功能说明: 饭庄74HC574端口值
*	形    参: _pin : 管脚号, 0-31; 只能选1个,不能多选
*	返 回 值: 无
*********************************************************************************************************
*/
void HC574_TogglePin(uint32_t _pin)
{
	if (g_HC574 & _pin)
	{
		g_HC574 &= (~_pin);
	}
	else
	{
		g_HC574 |= _pin;
	}
	HC574_PORT = g_HC574;
}

/*
*********************************************************************************************************
*	函 数 名: HC574_GetPin
*	功能说明: 判断指定的管脚输出是1还是0
*	形    参: _pin : 管脚号, 0-31; 只能选1个,不能多选
*	返 回 值: 0或1
*********************************************************************************************************
*/
uint8_t HC574_GetPin(uint32_t _pin)
{
	if (g_HC574 & _pin)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/561961.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 编译器中对 use after free 的检查示例

意图&#xff1a;检查源代码中是否存在某些地址&#xff0c;在free掉之后还对其进行了访问。 1, 示例远代码 cat hello_sani.cpp #include <iostream>using namespace std;int main(int argc, char **argv) {int i 1;int *A new int[12];cout <<"newed …

TCP/IP协议—HTTP

TCP/IP协议—HTTP HTTP协议HTTP通讯特点HTTP通讯流程 HTTP请求报文请求方法 HTTP应答报文状态码 HTTP协议 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09;是一种请求-响应的协议&#xff0c;用户可以通过HTTP向服务器上传、下载数据。HT…

ESP32嵌入式物联网开发实战笔记-C编程基础知识点【doc.yotill.com】

乐鑫ESP32入门到精通项目开发参考百例下载&#xff1a; 链接&#xff1a;百度网盘 请输入提取码 5.1 C 语言基础知识复习 本节我们给大家介绍一下 C 语言基础知识&#xff0c;对于 C 语言比较熟练的开发者&#xff0c;可以跳过此节&#xff0c;对于基础比较薄弱的开发者&…

JVM概述

JVM概述 1、一些性能上的问题 我好好运行的线上系统突然间卡死了&#xff0c;系统无法访问&#xff0c;当然这个原因非常多&#xff1b;想解决线上的JVM GC问题却无从下手&#xff1b;新的项目上线了&#xff0c;对于各种JVM参数的设置一脸茫然&#xff0c;全部直接默认&…

从头开始构建自己的 GPT 大型语言模型

图片来源&#xff1a; Tatev Aslanyan 一、说明 我们将使用 PyTorch 从头开始构建生成式 AI、大型语言模型——包括嵌入、位置编码、多头自注意、残差连接、层归一化&#xff0c;Baby GPT 是一个探索性项目&#xff0c;旨在逐步构建类似 GPT 的语言模型。在这个项目中&#xff…

Unity HDRP Water Surface 水系统 基础教程

Unity HDRP Water Surface 水系统 基础教程 Unity Water SurfaceUnity 项目创建Unity Water Surface&#xff1a;Ocean&#xff08;海洋&#xff09;简介Ocean&#xff1a;Transform、GeneralOcean&#xff1a;Simulation&#xff08;仿真模拟&#xff09;Ocean&#xff1a;Sim…

pnpm - Failed to resolve loader: cache-loader. You may need to install it.

起因 工作原因需要研究 vue-grid-layout 的源码&#xff0c;于是下载到本地。因为我习惯使用 pnpm&#xff0c;所以直接用 pnpm i 安装依赖&#xff0c;npm run serve 启动失败。折腾了一番没成功。 看到源码里有 yarn.lock&#xff0c;于是重新用 yarn install 安装依赖&…

多模态大语言模型综述

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

车控操作系统

车控操作系统 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看…

贪吃蛇游戏实现(VS编译环境)

贪吃蛇游戏 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C语言&#x1f353; &#x1f33c;文章目录&#x1f33c; 0. 前言 1. 游戏背景 2. 实现后游戏画面展示 3. 技术要求 4. Win32 API介绍 4.1 Win32 API 4.2 控制台程序 4.…

使用脚本启动和关闭微服务

使用脚本启动和关闭微服务 一、前言二、启动1、处理每个服务2、编写启动脚本3、其他启动脚本&#xff08;无效&#xff0c;有兴趣可以看看&#xff09;4、启动 三、关闭1、测试拿服务进程id的命令是否正确2、编写关闭脚本3、关闭 一、前言 假如在服务器中部署微服务不使用 doc…

【C++类和对象】const成员函数及流插入提取

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

地图图源#ESRI ArcGIS XYZ Tiles系列(TMS)

目录 1、前言 2、地图图源网址 2.1、Satellite 卫星图源 2.2、Terrain 地形图源 2.3、Street 路网/标注图源 2.4、Specifity 特色设计图源 3、专业推荐”穿搭“ 4、图源配置下载及使用 图源名称图层类别特别注意谷歌 Google①地形 ②影像 ③矢量及标注 ④特色图源国内大…

Nessus【部署 03】Docker部署漏洞扫描工具Nessus详细过程分享(下载+安装+注册+激活)文末福利

Docker部署漏洞扫描工具Nessus 1.安装2.配置2.1 添加用户2.2 获取Challenge code2.3 获取插件和许可证2.4 注册 3.使用4.进阶 整体流程&#xff1a; 1.安装 # 1.查询镜像 docker search nessus# 2.拉取镜像 docker pull tenableofficial/nessus# 3.启动镜像【挂载目录用于放置…

【Java框架】Spring框架(一)——Spring基本核心(IOC/DI)

目录 Java企业级框架企业级系统EJB概念解析EJB与Spring的恩怨情仇 Spring系统架构1. Data Access/Integration&#xff08;数据访问&#xff0f;集成&#xff09;2. Web 模块3. Core Container&#xff08;Spring 的核心容器&#xff09;4. AOP、Aspects、Instrumentation 和 M…

冰达ROS机器人快速使用指南

欢迎来到《冰达ROS机器人极简使用指南》 Q&#xff1a;这份教程适合谁&#xff1f; A&#xff1a;适合完全0基础新手&#xff0c;需要快速跑起来机器人的基本功能。也适合技术大佬需要快速的了解冰达ROS机器人的使用方法。 Q&#xff1a;这份教程内容很少&#xff0c;是不是…

迅雷下载不了的资源怎么下载?

我想下载Boost库&#xff0c;但是下载不下来 用迅雷下载是一直卡在0k 后来尝试在centos上用wget进行下载&#xff0c;竟然可以 wget https://boostorg.jfrog.io/artifactory/main/release/1.85.0/source/boost_1_85_0.tar.gz

信息打点--语言框架

指纹识别 后端 CMS:一般php开发居多源码程序&#xff0c;其他语言也存在&#xff0c;但不易识别&#xff08;利用源码程序名去搜漏洞情况&#xff0c;源码下载进行后期的代码审计&#xff09; 前端 js框架&#xff08;爬取更多的js从里面筛选URL或敏感泄露key&#xff09;等…

docker-compose 安装MongoDB续:创建用户及赋权

文章目录 1. 问题描述2. 分析2.1 admin2.2 config2.3 local 3. 如何连接3.解决 1. 问题描述 在这一篇使用docker-compose创建MongoDB环境的笔记里&#xff0c;我们创建了数据库&#xff0c;但是似乎没有办法使用如Robo 3T这样的工具去连接数据库。连接的时候会返回这样的错误&…

C++参考手册使用说明

C参考手册使用说明 文章目录 C参考手册使用说明1 为什么要使用C参考手册2 网站3 C参考手册离线格式4 C参考手册使用说明1.1 离线C参考手册下载1.2 html离线C参考手册1.3 chm离线C参考手册1.4 linux安装包C参考手册&#xff08;只有英文版本&#xff09;1.5 qch离线C参考手册 更…