合伙人合作方式:关于STM32 FSMC 是否支持6800时序的深入讨论

来源:百度文库 编辑:中财网 时间:2024/04/28 20:28:40

关于STM32 FSMC 是否支持6800时序的深入讨论

发布: 2009-12-31 01:16 | 作者: stm | 来源: STM32技术社区

[i=s] 本帖最后由 stm 于 2010-1-1 09:24 编辑

在我的“学习使用32位微控制器STM32的汇报bbs_page_no=1&bbs_id=3020),我指出STM3210E-LK中LCD的硬件设计问题:LCD控制器按6800方式连接的,我读了STM32的器件手册后,认为STM32的FSMC不支持6800,所以认定设计电路是错误的。

   尽管ST的工程师也电话与我勾通过,但到目前没有任何确定的答复,到底是正确还是错误。昨天在准备课程时,看到了这样的介绍:
  
(原文件名:未标题-2 拷贝.jpg)


    我出了身冷汗,人家STM32支持6800呀,我犯了错误了。

    今天在网上找了半天STM32的FSMC如何支持6800的资料,没有找到。到是在21IC的STM32专栏中也发现有人问这样的问题:

    “[STM32] 用STM32的FSMC驱动摩托罗拉6800液晶总线遇到难题”(http://bbs.21ic.com/icview-111668-1-1.html),而那里的ST斑竹的回答是:实际上,我没有研究过这个LCD的驱动问题,等有时间我再看看AN2790附带的程序,你也可以先看看这个程序。

     根据该帖子的线索,我到ST官方站上下载了AN2790,结果看到的东西把我弄晕了。

     在这个应用文档中有6800的连接参考图:


    两个图中都不是完整的FSMC的功能:一个是使用一个GPIO口线辅助;而另外使用一个非门做转换,实际是把8080的时序转成了与6800兼容!

    那么到底STM32的FSMC支持不支持6800呢?该如何回答和定义?

    不过使我感到稍微定心的是,STM3210E-LK板上的LCD选择6800接口,但与STM32的连接与AN2790中2个图是不同的,还是应该有问题的,这一点我没有说错。

    可能的结果是:
    1。STM32的FSMC不能完全支持6800时序。
    2。如果完全支持6800时序,那么ST官方的应用文档中的参考电路为何要使用额外的GPIO或非门转换?并且在数据手册中根本也找不到6800的时序?

stm (2009-12-31 01:16:29)把STM32的FSMC支持6800的出处也找到了:
stm (2009-12-31 01:17:55)列位看官,咱上一回说到的“FSMC是否支持,以及如何支持6800”的问题还只是在查找资料(注意:所有资料均来自于ST官方!)过程中发现的,不过这仅是让老朽刚开始晕,还不至于晕倒。

本回讲述的是实际测试结果,这个结果却让老朽更加晕,晕倒了。

列位看官(包括ST的工程师)可能会有疑问,因为如果在STM3210E-LK上运行其所带的DEMO程序的话,LCD是能显示ST的LOGO、包括其它的相应的提示字符。如果是硬件问题,那么这个DEMO是如何正常驱动LCD的?

我也一直存在着疑问,想了解清楚,ST的DEMO软件是怎样饶过这个硬件错误的?还是FSMC的确是支持6800?STM3210E-LK上的LCD连接方式并没有采用AN2790的电路,那它如何却能够工作?

由于我手上原来STM3210E-LK板上的LCD电路已经被我改成了8080方式,所以测试、比对、验证无法开展。昨天拿到ST公司新的STM3210E-LK板后,我进行了一系列的测试、验证工作。

============================================================
一、测试条件、代码介绍

2块STM3210E-LK学习板:一块是没有改动过,LCD采用6800模式(下面称A板);一块是改动过的,LCD采用8080方式(下面称B板)。

测试代码是根据ST的DEMO简化的,只使用LCD,开始显示一个画面,然后使用一个按键,控制4个LED二极管循环点亮(走马灯)。相同的代码,分别在A和B板上运行,看结果。然后改变某些设置,再分别在A和B板上运行,看结果。stm (2009-12-31 01:18:18)二、FSMC的配置
先把STM3210E-LK附带DEMO中LCD部分的FSMC配置代码贴上:
void LCD_FSMCConfig(void)
{
#ifndef NO_LCD   
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;

/*-- FSMC Configuration ------------------------------------------------------*/
/*----------------------- SRAM Bank 4 ----------------------------------------*/
  /* FSMC_Bank1_NORSRAM4 configuration */
  p.FSMC_AddressSetupTime = 1;
  p.FSMC_AddressHoldTime = 1;
  p.FSMC_DataSetupTime = 20;
  p.FSMC_BusTurnAroundDuration = 0;
  p.FSMC_CLKDivision = 0;
  p.FSMC_DataLatency = 1;
  p.FSMC_AccessMode = FSMC_AccessMode_A;

  /* Color LCD configuration ------------------------------------
     LCD configured as follow:
        - Data/Address MUX = Disable
        - Memory Type = SRAM
        - Data Width = 16bit
        - Write Operation = Enable
        - Extended Mode = Enable
        - Asynchronous Wait = Disable */
  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);   

  /* BANK 4 (of NOR/SRAM Bank 1~4) is enabled */
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
#endif
}

注意:该代码前面对FSMC_NORSRAMTimingInitTypeDef的定义部分(FSMC_WriteTimingStruct)实际是不起作用的,因为在后面语句中的: FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; 一句是将FSMC的ExtendedMode方式禁止了,所以前面对FSMC_WriteTimingStruct是多余的,浪费代码。

ST的DEMO中使用的是ST的库函数,而我的测试代码使用了STM32_init.c,FSMC的设置同上面相同:
  
(原文件名:未标题-2 拷贝.jpg)

我的测试代码中使用STM32_Init.c进行初始化配置,FSMC部分是我添加到STM32_Init.c中的。

三、测试比对一

FSMC的配置不变(实际就是8080的时序),只是改变系统运行时钟的频率:72M、64M、56M、48M....或直接使用内部RC 8M,禁止PLL。
结果如下:
    A板(6800方式),只是在72M时,LCD能正常显示。其它频率LCD根本就不显示了,但LED走马灯正常工作,按键功能正常,说明程序在正常运行。

    B板(8080方式),任何频率下,LCD都正常显示工作。(这个应该是当然的)

第一次晕倒!A板为什么在72M时,LCD能工作?(不知道为什么,就是晕倒了)。

四、测试比对二
这个测试是我“凑”出来的,因为既然在72M下,LCD能工作,那么FSMC中的某些模式是否就是6800方式?

(原文件名:未标题-4 拷贝.jpg)
改变FSMC的配置,允许Write burst enable!

结果如下:

    A板(6800方式),任何频率下,LCD都正常显示工作。
    B板(8080方式),任何频率下,LCD都正常显示工作。

神奇呀,并再一次重重的晕倒!!

为什么神奇?因为我已经看过STM32手册FSMC部分N遍了,里面根本没有允许Write burst enable后FSMC的读写时序图,而当我允许“Write burst”后,FSMC的时序完全兼容,并且自动识别8080和6800了?

================================================================
到次老朽是彻底晕倒了,因为实在不知道为什么,也找不到根据。反正这样设置,LCD(至少是STM3210E-LK上的LCD),不管是6800方式,还是8080方式,都能正常工作显示了。

ST公司的资深工程师们,是否能稍微去掉一点浮华的外表,踏踏实实的给出一个解释,说明原因?


stm (2009-12-31 01:19:19)我看过它的资料,应该与STM3210E-LK一样。你可以直接改动DEMO,看LCD工作是否正常:

1。只是改变系统的工作频率(DEMO工作在72M下),如32M等。

2。在FSMC配置中,允许Write burst:
   
   既将:FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
   改成:FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Enable;

   其它不变,然后在使用不同的系统时钟频率试一下。stm (2009-12-31 01:19:50)用8080模式的RD接E, WR接R/W 这样的接法本身就有问题

这样接去讨论在72M下可以显示,或是在write burst enable下能用,都已经不重要了

因为这种接法会可以正常显示,算是一个特例,一个巧合

只因为是在8080的写入模式时,WR为低电平,RD为高电平 => 刚好满足6800写入模式R/W为低电平,E要为高电平的要求

在读出模式时,是绝对不能用的,只是这个LCD模块只需要写入模式,刚好可以不需要用到读出模式,就可以正常显示

如果用这种方式去接其他6800器件或需要读出模式的LCD模块,是必死无疑的stm (2009-12-31 01:19:59)谢马老师认真仔细的分析与测试,经搭电路上机验证,改了一条语句 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Enable; 确实可行,完全支持 STM32 规格书上所描述的 支持Intel的8080和Motorola的6800时序 ,只是 STM32 的规格书写的实在太牛了,有人说,STM32 的规格书是写给本科学历以上的高手看的,现在连马老师这等顶级教授都彻底晕倒了,我等连初中文凭都没有的P民,看来只能把握这唯一的机会,紧紧跟着马老师学习的步伐搞懂搞清STM32先进的设计原理和思想, 才有可能活学活用,用好用精STM32这等专门为本科学历以上的高手设计的先进芯片。stm (2009-12-31 01:20:11)关于STM32的FSMC是否支持6800时序的问题,我的观点是:

1。STM32的FSMC接口本身是不支持6800时序的。因为在STM32的手册中给出的FSMC接口引脚定义和操作时序图中,根本没有任何与6800相关的的东西。

2。ST公司的宣传资料中的说法,是不负责任的,偷梁换柱的说法,尽管它在前边加上了一个LCD驱动器的限定。另外从ST公司的AN2790中给出的2个参考电路看,也证明还需要在硬件上做变化。但这两个参考的兼容6800的电路实际也是不可靠的。

3。所以我的结论是:如果在实际产品设计中,千万不要使用什么6800的接口,否则会犯原则上的错误。例如驱动LCD,就应该使用LCD的8080接口。

4。至于上面我谈到的改了一条语句,LCD工作正常的情况,只是一个特例。它只是在STM3210E-LK上驱动LCD,以及特定的软件下。我是因为需要上课,而改动15块版的硬件很难做到,只能尝试改动软件,但我都不知道为什么可以。所以发到这里,想讨教这里的STM32高手。stm (2009-12-31 01:20:38)我认真看了ST的AN2790应用文档和所带的参考代码,发现以下问题:

1。尽管在AN2790中,给出了FSMC转6800的两个参考电路(见楼主位图),但参考代码中是使用的8080时序,而且该参考代码所对应连接的LCD也是8080的接口,不是6800。因此不能确定该代码是否能正确配合2个6800电路的使用。

2。ST的AN2790中第一个6800转换参考,使用一个GPIO模拟6800的E信号,电路上是可行的,但这个GPIO需要单独写代码控制,与FSMC的配合变成了不伦不类的组合,我都不知道控制这个GPIO的代码如何写。当FSMC读写操作一个数据时,总线上的操作是自动完成的,你怎样在这其中插上这条将GPIO(E)置高清另的指令?如果象23楼说的全部直接用GPIO方式驱动是可以的,但那已经不是FSMC功能了,而且效率也差的多了。

3。ST的AN2790中第二个6800转换参考,使用一个非门将CS取反作为6800的E信号,这在时序上非常不严格。在6800中,E信号的高电平表示数据有效,它的下降沿通常是数据写(读)的打入信号。而CS是片选信号,通常CS为低,片子工作,CS为高,片子不工作,数据线高阻态。因此当CS从低变高时,E从高变低(下降沿),而且E是CS取反,比CS的变化要慢(经过硬件非门延时了)。想一想,CS变高了,芯片已经不工作了,此时的E信号的下降沿还有用处吗?

4。AN2790中的2个参考电路都是把8080的WR作为6800的R/W,这样做只能说还能过的去。注意到6800的R/W在一个数据读写过程中,完整的保持高或低电平(与地址信号基本同步)。因此,当8080读的时候WR始终为高,这个还与6800相同;但当8080写的时候,与6800的R/W就产生差别了:8080的WR通常在地址和数据都出现后才发出“低”的WR,不是与地址同步的,这与6800的R/W就有差别:留给外部6800器件的操作的时间至少减少了1/4~1/3。stm (2009-12-31 01:21:02)现在已经不是讨论FSMC本身是否能实现6800了,而是看如何转换能实现与6800的兼容更好些。

按26楼描述:“RD和WR用与非门(如HC00)产生 E 信号,R/W 则接到 A1 ,RS 接 A0”

我画个对照:

    8080                          6800
     RD      ==》 硬件HC00 ==》    E
     WR      ==》 硬件HC00
     A1      ==》                  R/W
     A0      ==》                  RS(其它LCD驱动,可能标为C/D)
     数据    ==》                  数据
     CS      ==》                  CS
==================================================
比ST的AN2790的2个参考电路要好的多,但软件上需要调整,而且多用掉一根地址线。

原来地址为2个:读写控制寄存器,A0 = 0;读写RAM A0 = 1
现在地址为4个:读控制寄存器 A1=1;A0=0
               写控制寄存器 A1=0;A0=0
               读RAM        A1=1;A0=1
               写RAM        A1=0;A0=1      
总算兼容6800了吧。


可是注意,这个只是lcd特例。如果是其它6800的器件。需要同一个地址进行读写操作,麻烦就更多了。

怪不得ST说,“连接LCD控制器”,兼容8080/6800。前面这个定语条件有学问,而且在AN2790中的两个电路也太不“兼容”了。