• 话说stm32f10x-FSMC的配置与频率


    1.存储器,从例子说起
      存储器读写,cpu与芯片同步等等都需要参考设备的读写时序,并通过参考cpu系统时钟,给出合理的读写周期。
      这里以stm32f103zeT6读写外部CSRAM为例子加以说明。
    选用用的CSRAM芯片的读写模式为同步非复用,频率为36MHz,芯片挂在cpu的FSMC的BANK1 SRAM4区,其同步非复用
    模式就不多讲,具体参考《STM32F103ZET6》p51~p52。至于这个36MHz则需要进行对FSMC的读写时序进行控制。如何
    控制呢?网上很多资料在这里都没有详细的说明,估计是很多网友觉得这个比较容易吧。但是当时我真是被这个问题
    给搞的半死不活。后来沉下心来悉心研究了一段时间,终于知道是怎么配置这个36MHz了。
     首先需要明确的是,stm32f10x固件库提供了简便的FSMC配置过程,我们可以利用一个结构体就进行配置,而不用
    对具体的寄存器进行一位一位的填写。具体的配置如下:
      FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
     FSMC_NORSRAMTimingInitTypeDef  FSMC_NORSRAMTimingInitStructure;
     //
     FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 1; 
     FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;  
     FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 2;
     FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0;   //总线恢复时间-19:16

     /*系统选用PLL作为时钟输出源,而PLL频率为72MHz,CRAM读写频率为36MHz,所以采用2分频*/
     FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 1; //bit-23:20,分频比为1,则存储器读写周期为 1/2 SYSCLK

     FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0;    //bit27:24,(数据保持时间)对于CRAM这个参数必须为0
     FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A;  //访问模式-只对FSMC_BCR1中EXTMOD位为1时起作用
     
       //以下是配置FSMC_BCR1寄存器的各个位
     FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4; 
     FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //非复用MUXEN:bit1
     FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; //MTYP-bit3:2存储器类型 
     FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;  //存储器数据总线宽度-bit5:4
     FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;//BURSTEN-bit8 成组模式使能
     FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; //bit15这一位手册里面保留...
     FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;  //WAITPOL-bit9-等待信号极性
     FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //WRAPMOD-bit10是否支持费对其成组模式
     FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; //WAITCFG-bit11
     FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //WREN-bit12
     FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;  //WAITEN-bit13-等待使能
     FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;  //EXTMOD-bit14 读写时序不一致时设置
     FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Enable;     //同步写-CBURSTRW(bit19)
     FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure; 
     FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;

     FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
     /* Enable FSMC Bank1_SRAM4 Bank */
     //根据PCB原理图 CSRAM的片选信号ARM_325T_CS与PG12连接,而PG12则是FSMC_NE4
     FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
     
     上面的配置大部分都给出了明确的解释,有些解释比较书面化,如不能理解透彻还是参照《STM32F10XXX参考手册》18章具体的
    寄存器说明进行查阅。
       这里只重点讲下,时钟配置,FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 1;这条语句,为什么配置为1?首先知
    道这条命令的含义。FSMC_CLKDivision表示分频比,而这个分频的参考是SYSCLK,而我的初始化程序中将系统时钟设置为72MHZ。
    而这里CRAM读写频率是36MHZ,所以要进行二分频,根据手册,二分频则需要将FSMC_BTRx寄存器的CLKDIV(bit23~bit20)位配置为
    1,即FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 1;这样就ok了~

    2.时钟,从启动程序说起
     另外要说的是,我的开发工具是keil-uVersion4+rt-thread,这个非常好用,boot程序都已经写好了的。查看其启动程序,发现中
    断向量表的第二个向量放的是复位中断,片段如下:
    __Vectors       DCD     __initial_sp                    ; Top of Stack
                    DCD     Reset_Handler                   ; Reset Handler //复位中断
    系统一旦复位便进入复位中断,并调用复位中断处理程序,处理如下:
    Reset_Handler    PROC
                     EXPORT  Reset_Handler             [WEAK]
         IMPORT  __main
         IMPORT  SystemInit
                     LDR     R0, =SystemInit
                     BLX     R0
                     LDR     R0, =__main
                     BX      R0
                     ENDP
                    
     我们可以看到,复位中断处理首先调用的是SystemIint程序,再调用c库函数_main,SystemInit也就是初始化我们的板子的运行环境,
    包括时钟,SRAM,FLASH等等,主要是时钟这一块。这个函数对HSE,HSI,PLL,以及系统时钟进行配置。
     这里只列出关于PLL和系统时钟的配置
     /* 
       硬件电路中HSE给的是12MHz(其实默认是8MHz,在stm32f10x中其取值范围为4~16MHz,具体参考《STM32F103ZET6中文》p42)

     */
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                            RCC_CFGR_PLLMULL));
     
      //PLL 时钟配置: PLLCLK = HSE * 6 = 72 MHz
     RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);
     
     系统复位后,HSI被选为系统时钟(HSI),而我们这里要选择PLL作为SYSCLK的时钟源,代码如下:
      /* Select PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  
     这样系统时钟就是72MHz。  

     
     
     
     

  • 相关阅读:
    获取农历日期
    图片上传代码(C#)
    ASP.net使用技术总结(1)GridView控件的单击处理
    JavaScript使用小技巧:IE8的关闭处理
    FrameSet左右收缩编码
    哈哈,开心!今天注册开通了 弟弟Kernel 的网志
    设计模式简介
    Delphi字符串、PChar与字符数组之间的转换
    C++中数组参数详解
    1、简单工厂模式
  • 原文地址:https://www.cnblogs.com/ju-an/p/3286712.html
Copyright © 2020-2023  润新知