stm32专题二十一:FSMC模拟8080时序

       ILI9341的8080通讯接口时序可以由STM32使用普通 I/O 接口进行模拟,但这样效率太低,STM32 提供了一种特别的控制方法,使用FSMC接口实现8080时序。

       由于 FSMC 外设可以用于控制扩展的外部存储器,而 MCU 对液晶屏的操作实际上就是把显示数据写入到显存中,与控制SRAM 存储器非常类似,且 8080 接口的通讯时序完全可以使用 FSMC 外设产生,因而非常适合使用 FSMC控制液晶屏。

FSMC结构框图:

LCD — 液晶显示:

NADV引脚是专门拥堵地址 / 数据线复用时做锁存信号,如下。当我们不需要地址 / 数据线复用时,NADV就不用管。

NADV由以下寄存器位来配置:

液晶屏使用模式B的写操作时序:

模式B读操作时序:

根据 STM32 对寻址空间的地址映射,地址 0x6000 0000 ~0x9FFF FFFF 是映射到外部存储器的,而其中的 0x6000 0000 ~0x6FFF FFFF 则是分配给 NOR FLASH、PSRAM这类可直接寻址的器件。
当 FSMC 外设被配置成正常工作,并且外部接了 NOR FLASH 时,若向 0x60000000地址写入数据如 0xABCD,FSMC 会自动在各信号线上产生相应的电平信号,写入数据。FSMC 会控制片选信号 NE1 选择相应的 NOR 芯片,然后使用地址线 A[25:0]输出0x60000000,在 NWE 写使能信号线上发出低电平的写使能信号,而要写入的数据信号0xABCD 则从数据线 D[15:0]输出,然后数据就被保存到 NOR FLASH 中了。

使用FSMC模拟8080时序:

一个非常重要的问题:就是地址对齐。

回想之前在SRAM中使用到的一个函数:

  /* 向整个SRAM写入数据  16位 */
  for (counter = 0; counter < IS62WV51216_SIZE/2; counter++)
  {
    *(__IO uint16_t*) (Bank1_SRAM3_ADDR + 2*counter) = (uint16_t)(uhWritedata_16b + counter);
  }

这个函数能够正常运行,没有问题。但是,值得注意的是,SRAM的数据线为16位,也就是说每个地址对应2个字节。这里在代码中直接写的是Bank1_SRAM3_ADDR + 2*counter,那么就会递增两个地址(4字节),是不是出了问题??应该只递增1地址才对啊?但是,无论是这个代码 or 下面的代码,都能够正确运行,非常奇怪。

/**
  * @brief  以“字”为单位向sdram写入数据 
  * @param  pBuffer: 指向数据的指针 
  * @param  uwWriteAddress: 要写入的SRAM内部地址
  * @param  uwBufferSize: 要写入数据大小
  * @retval None.
  */
void SRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize)
{
  __IO uint32_t write_pointer = (uint32_t)uwWriteAddress;
 

  /* 循环写入数据 */
  for (; uwBufferSize != 0; uwBufferSize--) 
  {
    /* 发送数据到SRAM */
    *(uint32_t *) (Bank1_SRAM3_ADDR + write_pointer) = *pBuffer++;

    /* 地址自增*/
    write_pointer += 4;
  }
}

这里竟然地址递增了4,应该会跳过8字节,但程序依然正常运行。问题出在这里:

这里感觉很不好理解,简单地分析如下:

对于16位SRAM,FSMC地址线要向右移一位(非常重要)。

以0x6800  0000这个地址为例,它分解成二进制是0110 1000 0000 0000 0000 0000 0000 0000,由于一个BANK是64M的地址空间,而2^25=64M,故0x6800 0000的位[25:0]是FSMC向外部SRAM传递的真实地址,对于0x6800 0000,FSMC向外部SRAM发的地址是位[25:0],即00 0000 0000 0000 0000 0000 0000。

同理,对于0x6800 0002,FSMC向外部SRAM发送的地址是00 00000000 0000 0000 0000 0010。若FSMC不自动右移一位,这个地址明显发错了,因为期望读取的SRAM地址为0x0000 0001中的数据。

为了解决这一问题,当在初始化FSMC时,若选择外部SRAM为16位,则FSMC在向外部SRAM发地址时,会自动右移一位,例如刚才的0x6800 0002,FSMC在向外部发SRAM地址时,00 0000 0000 0000 0000 0000 0010会自动右移一位,变成00 0000 00000000 0000 0000 0001,即0x0000 0001,该地址正好是期望的外部SRAM地址。接着,外部SRAM从地址为0x0000 0001中取出16位数据传送给FSMC,由FSMC将这个16位数据保存在以映射地址0x6800 0002起始的两个8位存储单元中。

地址映射如下:

这样的话,当16位数据宽度时,地址的问题解决了,还有一个问题,是往高字节写入还是低字节写入呢?

这也就是NBL0和NBL1的作用了,如果你要进行字节操作 :
如stm32发送地址0x0001读取一个字节。右移一位对应的是sram地址0x0000处的16位数据, FSMC会根据A0(最后一根地址线)来控制NBL0和NBL1。当A0 = 1时,读取高字节数据(仅NBL1有效);A0 = 0时,读取低字节数据仅NBL0有效),当进行16位读写时,NBL0和NBL1都有效。

**********************************************************************************************************************************************

经过了上面的分析,再来重新观察数据的写入过程:

当地址为0x6800  0000,会访问到SRAM的第0个16位地址,而此时A0 = 0(低字节有效),实际会访问的是16位 0地址的低字节;当地址为0x6800  0001时,A0 = 1,访问16位 0地址的高字节。依次。

因此,想让地址线的最后一位产生0或1,应该在前一位做出改变(stm32会自动右移):

结论:

本工程中使用 FSMC_A16 地址线作为命令/数据选择线 RS 信号,所以在地址范围内,再选择出使得 FSMC_A16 输出高电平的地址,即可控制表示数据,选择出使得FSMC_A16输出低电平的地址,即可控制表示命令。

要使 FSMC_A16 地址线为高电平,实质是访问内部 HADDR 地址的第(16+1)位为1 即可:

使用 0X6000 0000~0X63FF FFFF内的任意地址,作如下运算:
       使 FSMC_A16地址线为高电平:0X6000 0000 |= (1<<(16+1)) = 0x6002 0000
要使 FSMC_A16 地址线为低电平,实质是访问内部 HADDR 地址的第(16+1)位为0 即可:

使用 0X6000 0000~0X63FF FFFF内的任意地址,作如下运算:
       使 FSMC_A16地址线为低电平: 0X6000 0000 &= ~ (1<<(16+1)) = 0x6000 0000

*************************************************************************************************************************************************

根据最终的计算结果,总结如下:当 STM32 访问内部的 0x6002 0000 地址时,FSMC自动输出时序,且使得与液晶屏的数据/命令选择线 RS(即 D/CX)相连的 FSMC_A16 输出高电平,使得液晶屏会把传输过程理解为数据传输;     类似地,当 STM32 访问内部的 0X6000 0000 地址时,FSMC 自动输出时序,且使得与液晶屏的数据/命令选择线 RS(即 D/CX)相连的 FSMC_A16输出低电平,使得液晶屏会把传输过程理解为命令传输。

使用这两个地址发送命令和数据:

 

  • 20
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: STM32F407的FSMC(Flexible Static Memory Controller)总线应用是指将FSMC用于连接外部存储器或外设的数据交换。FSMC是一个灵活的高性能静态存储器控制器,可以与各种存储器类型和外设相连接。 STM32F407的FSMC总线应用有以下几个方面: 1. 外部存储器扩展:通过FSMC总线,可以将外部存储器,如SRAM(静态随机存储器)或 NOR Flash(并行闪存),连接到STM32F407微控制器。这样可以扩展STM32F407的存储容量,适用于需要大容量内存的应用,如图像处理、音频处理等。 2. 外设连接:FSMC还可以用于连接外部设备,如LCD液晶显示屏。通过FSMC总线,可以将STM32F407与LCD控制器相连接,实现彩色图像的实时显示。此外,FSMC还可以连接其他外设,如触摸屏控制器、摄像头模块等。 3. 并行接口:FSMC总线是一个高速的并行接口,支持多种总线协议。除了SRAM和NOR Flash之外,FSMC还可以连接其他外部存储器,如PSRAM(伪静态随机存储器)、NAND Flash(并行闪存)等。通过FSMC的并行接口,可以实现高速数据传输和存取。 4. DMA支持:FSMCSTM32F407的DMA(直接存储器访问)控制器相结合,可实现高效的数据传输。DMA可以直接从外部存储器读取数据或向外部存储器写入数据,减轻了CPU的负担,提高了数据传输的效率。 总之,STM32F407的FSMC总线应用广泛,可以连接各种外部存储器和外设,具有灵活性和高性能。它在大容量存储、图像处理、音频处理等应用中发挥着重要作用,同时通过DMA支持提供了高效的数据传输解决方案。 ### 回答2: STM32F407的FSMC(Flexible Static Memory Controller)总线可以用于处理与外部静态存储器的通信。它提供了多种接口和功能,方便与不同类型的存储器进行连接,包括SRAM、NOR Flash和PSRAM等。 在SRAM应用中,FSMC总线可以为外部SRAM提供直接访问功能。通过配置FSMC控制寄存器和时序寄存器,可以实现读取和写入SRAM中的数据。这种方式可以扩展MCU的内存空间,提高数据处理能力。 在NOR Flash应用中,FSMC总线可以实现对外部闪存的读取和写入。通过配置FSMC的控制寄存器和时序寄存器,可以设置访问闪存的时序和模式。这种方式可以用于存储嵌入式应用程序代码和数据,提高系统的运行速度和效率。 在PSRAM应用中,FSMC总线可以连接并访问外部并行存储器。通过配置FSMC的控制寄存器和时序寄存器,可以实现对PSRAM的读取和写入。这种方式可以提供高速存储器的访问能力,适用于对存储速度要求较高的应用场景。 总之,STM32F407的FSMC总线应用广泛,能够满足不同类型的外部存储器的连接和通信需求。它提供了灵活的接口和丰富的功能,可以大幅拓展内存空间,提高系统性能和效率。 ### 回答3: STM32F407的FSMC(Flexible Static Memory Controller)总线是一种用于连接外部存储器设备的接口。它提供了与静态存储器(SRAM和NOR闪存)、NAND闪存、SDRAM等设备进行高速数据传输的功能。FSMC总线的应用范围广泛,包括但不限于以下几个方面: 首先,FSMC总线可以连接静态存储器设备,例如SRAM和NOR闪存。SRAM是一种快速且易于访问的存储器,适用于对读写速度要求较高的应用场景。NOR闪存则在数据存储方面提供了非常大的存储容量,适用于嵌入式系统中的代码存储需求。 其次,FSMC总线还可以连接NAND闪存,这是一种使用较多的闪存存储设备,适用于对存储容量要求较高的应用场景。NAND闪存不仅具备较大的存储容量,还具备良好的擦除和写入性能。 另外,FSMC总线还支持连接SDRAM,这是一种用于动态存储的存储器设备。SDRAM具备较大的存储容量和高速的数据传输速度,适用于对存储容量和数据读写性能要求较高的应用场景,如图像处理、音频处理等。 总之,STM32F407的FSMC总线广泛应用于嵌入式系统中需要连接外部存储器设备的场景。通过高速、稳定的数据传输,实现了对静态存储器(SRAM和NOR闪存)、NAND闪存和SDRAM等存储设备的有效控制和访问,为嵌入式系统的数据存储和处理提供了良好的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值