STM32 的并口总线的所有接口类型解决方法

发布者:骄阳少年最新更新时间:2018-06-07 来源: eefocus关键字:STM32  并口总线  接口类型 手机看文章 扫描二维码
随时随地手机看文章

       STM32的并口总线支持NOR, SRAM, PSRAM,NAND接口,本文以PSRAM为例实现并口的同步非复用, 异步复用和异步非复用操作!以STM32F207IG(176脚)系列为例,步骤如下:

      1.  初始化并口的各个引脚

//Add[0-25] : F0-F5(6); F12-F15(4); G0-G5(6); D11-D13(3); E3-E6(4); E2(1); G13-G14(2)              
//Data[0-15]: D14-D15(2);D0-1(2);E7-15(9);D8-10(3)                                                 
//FSMC_NIORD: F6   NC           for PC CARD                                                        
//FSMC_NREG : F7   NC           for PC CARD                                                        
//FSMC_NIOWR: F8   NC           for PC CARD                                                        
//FSMC_CD   : F9   NC           for PC CARD                                                        
//FSMC_INTR : F10  NC           for PC CARD                                                        
//FSMC_INT2 : G6   NC           for COMMON                                                         
//FSMC_INT3 : G7   NC           for COMMON                                                         
//FSMC_CLK  : D3                for NOR/PSRAM                                                      
//FSMC_NOE  : D4                for COMMON                                                         
//FSMC_NWE  : D5                for COMMON                                                         
//FSMC_NWAIT: D6                for COMMON                                                         
//FSMC_NE1  : D7   FSMC_NCE2    for NOR/PSRAM  for NAND                                            
//FSMC_NE2  : G9   FSMC_NCE3    for NOR/PSRAM  for NAND                                            
//FSMC_NE3  : G10  NC           for NOR/PSRAM                                                      
//FSMC_NCE4 : G11  NC           for NOR/PSRAM                                                      
//FSMC_NE4  : G12  NC           for NOR/PSRAM                                                      
//FSMC_NL   : B7                for NOR/PSRAM                                                      
//FSMC_NBL0 : E0                for NOR/PSRAM                                                      
//FSMC_NBL1 : E1                for NOR/PSRAM

   

void FsmcInit(void)

    u8 i=0;

    // 1. 
    GPIO_InitTypeDef GPIO_InitStructure; 
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB  | RCC_AHB1Periph_GPIOD  |        RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);
  
    for(i=0; i    {        
        GPIO_PinAFConfig((GPIO_TypeDef *)GPIOx,  GPIO_PinSourceX, GPIO_AF_FSMC);
    }
    
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 ;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
    GPIO_Init(GPIOD, &GPIO_InitStructure); 
    
    for(i=0; i    {        
        GPIO_InitStructure.GPIO_Pin   = (1<        GPIO_Init((GPIO_TypeDef *)GPIOx,   &GPIO_InitStructure);
    }

// FSMC_NWAIT: D6  

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 ;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
    GPIO_Init(GPIOD, &GPIO_InitStructure); 

    FsmcBank1BusTypeInit(FSMC_TYPE_NOMUX_SYN, FSMC_Bank1_NORSRAM1, FSMC_MemoryType_PSRAM, FSMC_MemoryDataWidth_16b);
  //  FsmcBank1BusTypeInit(FSMC_TYPE_MUX_ASYN, FSMC_Bank1_NORSRAM1, FSMC_MemoryType_PSRAM, FSMC_MemoryDataWidth_16b);
   // FsmcBank1BusTypeInit(FSMC_TYPE_NOMUX_ASYN, FSMC_Bank1_NORSRAM1, FSMC_MemoryType_PSRAM, FSMC_MemoryDataWidth_16b);
}


2. 初始化FSMC

  u8 FsmcBank1BusTypeInit(u8 uchBusType, u32 uiBank1Numb, u32 uiMemType, u32 uiDataWide)

{
    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
    FSMC_NORSRAMTimingInitTypeDef  FSMC_NORSRAMTimingRead;
    FSMC_NORSRAMTimingInitTypeDef  FSMC_NORSRAMTimingWrite;
   

    if(((FSMC_TYPE_NOMUX_SYN == uchBusType)||(FSMC_TYPE_MUX_SYN == uchBusType)) &&(uiMemType == FSMC_MemoryType_NOR))
    {//同步访问Nor 只支持读操作
        return FSMC_OPT_FAIL;
    }


    // 0.默认初始化结构体,读写的时序
    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingRead;  
    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct     = &FSMC_NORSRAMTimingWrite;
    FSMC_NORSRAMStructInit(&FSMC_NORSRAMInitStructure);


    // 1. 总线类型初始化
    FSMC_NORSRAMInitStructure.FSMC_Bank                  = uiBank1Numb;  
    FSMC_NORSRAMInitStructure.FSMC_MemoryType            = uiMemType;
    FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth       = uiDataWide;


    // 2.根据芯片类型初始化
    if((FSMC_TYPE_NOMUX_SYN == uchBusType)||(FSMC_TYPE_MUX_SYN == uchBusType))
    {//同PSRAM, 同步非复用
        //同步模式设置:      
        // 2.1 总线类型         
        if(FSMC_TYPE_MUX_SYN == uchBusType)
        {
            FSMC_NORSRAMInitStructure.FSMC_DataAddressMux    = FSMC_DataAddressMux_Enable; 
        }
        else
        {
            FSMC_NORSRAMInitStructure.FSMC_DataAddressMux    = FSMC_DataAddressMux_Disable;
        }
        FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode       = FSMC_BurstAccessMode_Enable;   //同步模式下使用,for NOR Flash(PSRAM)
                     
        // 2.2. 其他设置,burst模式禁用,burst mode disable: Paras. valid only when accessing Flash memories in burst mode      
        FSMC_NORSRAMInitStructure.FSMC_WriteBurst            = FSMC_WriteBurst_Enable;          //在同步模式下支持Write burst,但读时无效; 异步模式下设0,禁用,表示在异步模式下写操作总是容许的
        FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait      = FSMC_AsynchronousWait_Disable;   //异步操作时是否采用NWAIT信号来进行数据准备的延时
        FSMC_NORSRAMInitStructure.FSMC_ExtendedMode          = FSMC_ExtendedMode_Disable;       //是否支持扩展模式A,B,C,D,根据需要来设定
        FSMC_NORSRAMInitStructure.FSMC_WaitSignal            = FSMC_WaitSignal_Enable;          //在burst模式下,是否插入NWAIT等待延时信号 ,同步必须插
        FSMC_NORSRAMInitStructure.FSMC_WriteOperation        = FSMC_WriteOperation_Enable;      //是否支持写操作
        FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive      = FSMC_WaitSignalActive_DuringWaitState; // 延时等待信号在FSMC_WaitSignalPolarity时表示正在等待,不是之前一个时钟周期类在等待
        FSMC_NORSRAMInitStructure.FSMC_WrapMode              = FSMC_WrapMode_Disable;           //对总线宽度不一致时使用
        FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity    = FSMC_WaitSignalPolarity_Low;    //异步操作若开启延时,此表示延迟等待的电平,非此电平表示延时结束,for NOR Flash(PSRAM) WAITEN、WAITCFG、WAITPOL 


        // 2.3 延时时间设置,根据芯片来设计,同步模式,下列前三个不用设置
        FSMC_NORSRAMTimingRead.FSMC_AddressSetupTime         = 10;  //地址建立时间的持续时间, 异步使用
        FSMC_NORSRAMTimingRead.FSMC_AddressHoldTime          = 5;   //地址的建立后的保持时间, 异步使用
        FSMC_NORSRAMTimingRead.FSMC_DataSetupTime            = 10;  //数据建立时间的持续时间,异步复用中使用
        FSMC_NORSRAMTimingRead.FSMC_BusTurnAroundDuration    = 2;   //总线周转时间?!,         复用模式使用
        FSMC_NORSRAMTimingRead.FSMC_CLKDivision              = 3;   //定义输出时钟分频,      同步使用, 0x0 to get CLK = HCLK(个别芯片不支持),0x1 to get CLK = 2 × HCLK,... , 0x0f;    ==2,clk == 40M,==3,clk == 30M 
        FSMC_NORSRAMTimingRead.FSMC_DataLatency              = 0;   //内存时钟周期数,        同步使用,  DataLatency = 1 for NOR Flash; DataLatency = 0 for PSRAM
        FSMC_NORSRAMTimingRead.FSMC_AccessMode               = FSMC_AccessMode_A;//Specifies the asynchronous access mode  


        memcpy((u8 *)&FSMC_NORSRAMTimingWrite, (u8 *)&FSMC_NORSRAMTimingRead, sizeof(FSMC_NORSRAMTimingInitTypeDef));
    }
    else if((FSMC_TYPE_MUX_ASYN == uchBusType) || (FSMC_TYPE_NOMUX_ASYN == uchBusType))
    { //异步复用模式,   异步非复用   
        // 2.1 总线类型        
        if(FSMC_TYPE_MUX_ASYN == uchBusType)
        {
            FSMC_NORSRAMInitStructure.FSMC_DataAddressMux    = FSMC_DataAddressMux_Enable; 
        }
        else
        {
            FSMC_NORSRAMInitStructure.FSMC_DataAddressMux    = FSMC_DataAddressMux_Disable; 
        }
        FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode       = FSMC_BurstAccessMode_Disable;   //同步模式下使用,for NOR Flash(PSRAM)
                     
        // 2.2. 其他设置,burst模式禁用,burst mode disable: Paras. valid only when accessing Flash memories in burst mode      
        FSMC_NORSRAMInitStructure.FSMC_WriteBurst            = FSMC_WriteBurst_Disable;         //在同步模式下支持Write burst ; 异步模式下设0,禁用,表示在异步模式下写操作总是容许的
        FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait      = FSMC_AsynchronousWait_Disable;    //异步操作时是否采用NWAIT信号来进行数据准备的延时
        FSMC_NORSRAMInitStructure.FSMC_ExtendedMode          = FSMC_ExtendedMode_Disable;       //是否支持扩展模式A,B,C,D,根据需要来设定
        FSMC_NORSRAMInitStructure.FSMC_WaitSignal            = FSMC_WaitSignal_Disable;         //在burst模式下,是否插入NWAIT等待延时信号 
        FSMC_NORSRAMInitStructure.FSMC_WriteOperation        = FSMC_WriteOperation_Enable;      //是否支持写操作
        FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive      = FSMC_WaitSignalActive_BeforeWaitState; // 延时等待信号在FSMC_WaitSignalPolarity时表示正在等待,不是之前一个时钟周期类在等待
        FSMC_NORSRAMInitStructure.FSMC_WrapMode              = FSMC_WrapMode_Disable;           //对总线宽度不一致时使用
        FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity    = FSMC_WaitSignalPolarity_High;    //异步操作若开启延时,此表示延迟等待的电平,非此电平表示延时结束,for NOR Flash(PSRAM) WAITEN、WAITCFG、WAITPOL 


        // 2.3 延时时间设置,根据芯片来设计
        FSMC_NORSRAMTimingRead.FSMC_AddressSetupTime         = 20;  //地址建立时间的持续时间, 异步使用
        FSMC_NORSRAMTimingRead.FSMC_AddressHoldTime          = 5;  //地址的建立后的保持时间, 异步使用
        FSMC_NORSRAMTimingRead.FSMC_DataSetupTime            = 30;  //数据建立时间的持续时间,异步复用中使用
        FSMC_NORSRAMTimingRead.FSMC_BusTurnAroundDuration    = 5;  //总线周转时间?!,         复用模式使用


        FSMC_NORSRAMTimingRead.FSMC_CLKDivision              = 1;  //定义输出时钟分频,      同步使用, 0x0 to get CLK = HCLK(个别芯片不支持),0x1 to get CLK = 2 × HCLK,... , 0x0f;   
        FSMC_NORSRAMTimingRead.FSMC_DataLatency              = 0;  //内存时钟周期数,        同步使用,  DataLatency = 1 for NOR Flash; DataLatency = 0 for PSRAM
        FSMC_NORSRAMTimingRead.FSMC_AccessMode               = FSMC_AccessMode_D;//Specifies the asynchronous access mode  


        memcpy((u8 *)&FSMC_NORSRAMTimingWrite, (u8 *)&FSMC_NORSRAMTimingRead, sizeof(FSMC_NORSRAMTimingInitTypeDef));
    }    
    else//FSMC_TYPE_MUX_SYN: 同步复用
    {      
        return FSMC_OPT_FAIL;
    }
    
    // 5.写配置到REG
    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);    
    FSMC_NORSRAMCmd(uiBank1Numb, ENABLE);   

    
    return FSMC_OPT_OK;
}

      

3. 函数的调用

void PsramWrite(u32 uiRegAddr, u16 ushValue)
{
    // Transfer data to the memory 
    *(__IO u16 *) (cuistBank1BaseAddr[FSMC_FEC_BANK_NUMB] + (uiRegAddr<<1)) = ushValue;                
}

u16 PsramRead(u32 uiRegAddr)
{    
      u16 ushVal = 0;
    // Read data from the memory 
    ushVal = *(__IO u16*) (cuistBank1BaseAddr[FSMC_FEC_BANK_NUMB] + (uiRegAddr<<1));
    
    return ushVal;
}


    总结:一般异步模式下,需要调试建立时间,同步模式下则不用!

    特别说明,对于非STM32标准的接口,如motorola和intel总线的并口,需要在调用PsramWrite和PsramRead时,手动进行片选FSMC_NEx的上拉和下拉!


关键字:STM32  并口总线  接口类型 引用地址:STM32 的并口总线的所有接口类型解决方法

上一篇:STM32 I2C 总线占用问题解析
下一篇:STM32驱动LCD12864显示屏

推荐阅读最新更新时间:2024-03-16 16:05

STM32--程序睡眠唤醒下载的方法
stm32开发:用j-link或ST-link下载, 如果遇到: Internal command error 一种情况是:程序休眠了 解决办法: 按下复位按钮,点击下载。再松开复位按键,就可以重新下载
[单片机]
STM32通用定时器TIMx
STM32计数器时钟可由下列四种时钟源提供: (1)内部时钟(CK_INT) (2)外部时钟模式1:外部输入脚(TIx) (3)外部时钟模式2:外部触发输入(ETR) (4)内部触发输入(ITRx) 时钟源(CK_INT)经预分频(PSC)后得到定时时钟(CK_CNT),每个定时时钟计数寄存器计数(可设向上/向下/中央对齐模式),计数寄存器计数至捕获比较寄存器(CCR),则产生CC中断;计数寄存器计数至预装载值(ARR),则产生UPDATE中断,并重装预载值。 举个例子:(以向上计数为例,每40us中断一次)   例程: (省略RCC设置部分) void TIM2_Configuration(void) {
[单片机]
<font color='red'>STM32</font>通用定时器TIMx
再造STM32---第十部分:GPIO输入—按键检测
本章参考资料:《STM32F4xx 参考手册》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。 按键检测使用到 GPIO 外设的基本输入功能,本章中不再赘述 GPIO 外设的概念,如您忘记了,可重读前面“GPIO 框图剖析”小节, STM32 标准库中 GPIO 初始化结构体GPIO_TypeDef 的定义与“定义引脚模式的枚举类型”小节中讲解的相同。 10.1 硬件设计: 按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,使用按键时会产生图 10-1 中的带波纹信号,需要用软件消抖处理滤波,不方便输入检测。本实验板连接的按键带硬件消
[单片机]
再造STM32---第十部分:GPIO输入—按键检测
STM32 自定义频率与占空比PWM输出的方法
图一 图二 PWM应用非常广泛,但是不同的项目对输出的PWM又有特殊要求,为满足这些要求我们需要更多的实验来验证。接下来讲述图一显示波形的输出方法步骤(图二为异常波形)。 一、本实例所使用资源: 1、TIM4_CH3(对应管脚PB8)用于输出PWM波形 2、TIM3用于产生中断 3、MDK 软件仿真方法 二、执行过程: 1、初始化配置TIM4_CH3对应管脚的PWM输出功能(频率与占空比可变)。 2、初始化配置使用TIM3定时器中断功能,中断时间的配置需要根据PWM输出波形配置(定时器中断时间可变)。 3、在main()函数中调用TIM4与TIM3的初始化函数。 三、具体代码: int main(void) //主函数
[单片机]
<font color='red'>STM32</font> 自定义频率与占空比PWM输出的方法
STM32 构建库函数
由于自己的粗心大意 导致构建库函数 这一个简单的事 弄了好几个小时 所以我决定把这个配置的过程记录下来 我们按照这个逻辑来 就没有啥问题 前面构建工程过程 就不多赘述 新建文件夹 点击鼠标右键 选择add grup 长按 可以修改文件夹的名字 然后就是从已经有的固件库中导入文件 STRATUP 只需要选择 那个stm32f10x_ hd.s 结尾的 配置成这样就可以了 然后我们选择编译会发现出现error 但是千万不要慌 为什么呢 原因就是 就是我们锤子还没完成配置 点击锤子 选择c/c++ 点击这里 添加一下路径 这里的路径不能带中文 选择这三个就可 然后我们点开user 的main.c 文件 点击头文件
[单片机]
<font color='red'>STM32</font> 构建库函数
STM32定时器产生PWM彻底应用
这次学习STM32花了很长时间,一个礼拜多,也有颇多收获,学习过程也有颇多曲折。这次的任务是:用STM32的一个定时器在四个通道上产生四路频率可调占空比可调的PWM波。 看到这个题,我先看STM32的数据手册,把STM32的定时器手册看完就花了一天,但是看了一遍任然不知道所云,就看库函数,略有点理解,就想一哈把这个程序调出来,于是就花了一天多时间仿照网上别人的程序来写,花了一天多写出来调试,结果行不通,做了无用功,于是静下心来想想,还是一步一步的来。 我先用STM32的通用定时器用PWM模式产生四路相同占空比,不同频率的PWM波,配置如下: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM
[单片机]
stm32 0.96寸OLED时钟程序,万年历,大字体
下午闲着没事,在我们的51hei论坛找了一个小玩意儿(具体谁的我找不着了,抱歉哈),修改了一下。但是他的程序之前写的时候可能太古老了,所以我就稍微修改完善了一下。用的是stm32自带的RTC时钟。硬件连接很简单,当然程序也是比较简单的,只写了温度(DS18B20),stm32自带RTC和OLED显示,大家可自行删改功能。 硬件连接: SDA --》PB13 SCL --》PB12 DS18B20----》PA15 OLED和DS18B20直接5V供电就成,代码和工具都在最后,需要的小伙伴自行下载吧。 效果如下: 单片机源程序如下: #include sys.h #include usart.h
[单片机]
<font color='red'>stm32</font> 0.96寸OLED时钟程序,万年历,大字体
STM32开发者社区:从这里开启你的STM32之旅!小白和PRO都友好
当面对STM32Cube生态系统这样一个庞大而丰富的开发世界时,工程师难免会产生疑问,从哪里开始才好? ST的许多合作伙伴和客户都希望有更多的产品能够利用STM32Cube开发环境。开发人员很享受开发环境的图形用户界面和工具的易用性,如STM32CubeMX、免费的STM32CubeIDE以及许多软件包、驱动程序和中间件,这些都有助于更快地将产品推向市场。随着越来越多的企业选择ST的产品,越来越多的工程师在ST的生态系统中迈出了第一步。为了降低开发人员的进入门槛,ST推出了STM32开发者社区。开发者社区如何为开发团队提供帮助,ST如何将STM32生态系统整合在一起?让我们详细聊聊。 STM32开发者社区 为开
[单片机]
<font color='red'>STM32</font>开发者社区:从这里开启你的<font color='red'>STM32</font>之旅!小白和PRO都友好
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved