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

ops/2024/11/20 17:39:51/

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 个 IOPD0/FMC_D2PD1/FMC_D3PD4/FMC_NOE ---- 读控制信号,OE = Output Enable , N 表示低有效PD5/FMC_NWE -XX- 写控制信号,AD7606 只有读,无写信号PD8/FMC_D13PD9/FMC_D14PD10/FMC_D15PD14/FMC_D0PD15/FMC_D1PE7/FMC_D4PE8/FMC_D5PE9/FMC_D6PE10/FMC_D7PE11/FMC_D8PE12/FMC_D9PE13/FMC_D10PE14/FMC_D11PE15/FMC_D12PG0/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;}
}

http://www.ppmy.cn/ops/4341.html

相关文章

基于单片机的船舶柴油机冷却水温控制研究

摘 要: 在利用原有方法进行船舶柴油机冷却水温控制时,由于受到负荷过大的影响而无法计算循环水量,在转速工况为1 500~2 300 r/min 的范围内存在发动机NO 排放量过大的问题,因此提出一种基于单片机的船舶柴油机冷却水温控制方法,通过船舶柴油机冷却热量对冷却水的实际循环量…

设计企业需求图纸加密软件,如何更好实现加密功能

随着计算机的普及设计行业也进入了数字化时代&#xff0c;平面设计、机械设计、建筑设计、动画设计每一种设计都得到了突飞猛进的发展&#xff0c;怎样保护企业的设计图纸不被泄露&#xff0c;在很多加密的防泄密方案中&#xff0c;文件透明加密因使用方便性价比高得到了很多企…

[Spring Cloud] (3)gateway令牌token拦截器

文章目录 集成redisNacos配置增加 redis配置配置pomredis配置RedisConfigredis序列化工具FastJson2JsonRedisSerializer测试 令牌校验拦截器nacos配置拦截器代码微服务登录接口实现 最终效果-登录接口与数据接口 本文gateway与微服务已开源到gitee 杉极简/gateway网关阶段学习 …

各自时间轴上

时间轴线交通阡陌上&#xff0c;相交相离间&#xff0c;成就时间流里的一份子&#xff0c;或大或小&#xff0c;皆在其内。哪有无缘无故&#xff0c;更没有突如其来&#xff0c;都是因缘际会&#xff0c;关键还是珍惜和把握。 ​顺水寻源&#xff0c;逐末求本&#xff0c;自然而…

C语言---贪吃蛇(二)---逻辑和代码的实现

文章目录 前言1.准备工作2.蛇的相关属性3.游戏流程设计3.1.游戏开始(GameStart)3.1.1.设置光标位置3.1.2.隐藏光标3.1.3.打印欢迎界面3.1.4.创建地图3.1.5.初始化蛇身3.1.6.创建食物 3.2.游戏运行(GameRun)3.2.1.打印信息栏3.2.2.蛇身的移动3.2.2.1.判断下一个结点是否为食物3.…

meta-llama/Meta-Llama-3-8B

https://huggingface.co/meta-llama/Meta-Llama-3-8B 型号细节 Meta开发并发布了Meta Llama 3家族大型语言模型(LLM),这是一组预训练和指令微调的生成性文本模型,大小为8B和70B参数。Llama 3指令微调模型针对对话用例进行了优化,在常见的行业基准测试中表现优于许多可用的开源…

centos7安装mysql5.7笔记

1 配置yum仓库 1.1更新密钥 #更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 1.2 下载使用wget命令下载MySQL的repo文件 #下载使用wget命令下载MySQL的repo文件 wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 2 使用…

洛谷 P4779 [模板] 单源最短路径 题解 dijkstra算法

【模板】单源最短路径&#xff08;标准版&#xff09; 题目描述 给定一个 n n n 个点&#xff0c; m m m 条有向边的带非负权图&#xff0c;请你计算从 s s s 出发&#xff0c;到每个点的距离。 数据保证你能从 s s s 出发到任意点。 输入格式 第一行为三个正整数 n ,…