你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

FSMC模拟8080刷OLED从F1移植到F4后无法使用

[复制链接]
Freesoul 提问时间:2023-3-29 14:15 / 未解决

1、STM32F103ZET6上配置的FSMC模拟8080用于刷新OLED(256*64),使用正常; 2、移植至STM32F412RET6后无法使用,时钟、复用、FSMC均已配置,使用NE4、A0,配置写入命令地址为0x6C00000,写入数据地址为0x6C000001;错误现象为:①屏幕显示现象为雪花屏②用逻辑分析仪测得D0-D3数据线无信号输出,仅有高电平。 配置已检查过多遍,麻烦各位给一些思路解决一下这个问题,感谢!

代码如下:


/*
*                        RS(DC)——A0——PC3                RD——FSMC_NOE——PC5
*                        WR——FSMC_NWE——PC2        D0——FSMC_D0——PB14
*                        D1——FSMC_D1——PC6         D2——FSMC_D2——PC11
*                        D3——FSMC_D3——PC12        D4——FSMC_D4——PA2
*                        D5——FSMC_D5——PA3                D6——FSMC_D6——PA4
*                        D7——FSMC_D7——PA5         CS——FSMC_NE4——PC4
*                        RESET——PB13
*/
/*******************************************************************************
@name    :InitOLED
@brief   :按键初始化
@param   :None
@return  :None
*******************************************************************************/
void InitOLED (void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        /*GPIOA、B、C时钟使能*/
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC, ENABLE);
       
        /*WR、RS、CS、RD、D1、D2、D3推挽复用输出*/
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_11|GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
       
        /*D0推挽复用输出*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        /*D4、D5、D6、D7推挽复用输出*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_FSMC);
       
        /*RESET推挽输出*/
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);       
       
        InitFSMC();
}

void InitFSMC(void)
{
        FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
        FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;
        FSMC_NORSRAMTimingInitTypeDef  writeTiming;
       
        /*FSMC时钟使能*/
        RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);
       
        /*读时序设置*/
        readWriteTiming.FSMC_AddressSetupTime = 0x01;
        readWriteTiming.FSMC_AddressHoldTime = 0x00;
        readWriteTiming.FSMC_DataSetupTime = 0x02;
        readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
        readWriteTiming.FSMC_CLKDivision = 0x00;
        readWriteTiming.FSMC_DataLatency = 0x00;
        readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;

        /*写时序设置*/
        writeTiming.FSMC_AddressSetupTime = 0x01;
        writeTiming.FSMC_AddressHoldTime = 0x00;               
        writeTiming.FSMC_DataSetupTime = 0x02;
        writeTiming.FSMC_BusTurnAroundDuration = 0x00;
        writeTiming.FSMC_CLKDivision = 0x00;
        writeTiming.FSMC_DataLatency = 0x00;
        writeTiming.FSMC_AccessMode = FSMC_AccessMode_A;

        FSMC_NORSRAMInitStructure.FSMC_Bank                  = FSMC_Bank1_NORSRAM4;                 //使用NE4
        FSMC_NORSRAMInitStructure.FSMC_DataAddressMux        = FSMC_DataAddressMux_Disable;         //不复用数据地址
        FSMC_NORSRAMInitStructure.FSMC_MemoryType            = FSMC_MemoryType_SRAM;                // FSMC_MemoryType_SRAM;  
        FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth       = FSMC_MemoryDataWidth_8b;             //存储器数据宽度为8bit   
        FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode       = FSMC_BurstAccessMode_Disable;        // FSMC_BurstAccessMode_Disable;
        FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity    = FSMC_WaitSignalPolarity_Low;
        FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait      = FSMC_AsynchronousWait_Disable;
        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_Enable;             //读写使用不同的时序
        FSMC_NORSRAMInitStructure.FSMC_WriteBurst            = FSMC_WriteBurst_Disable;
        FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;                     //读写时序
        FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct     = &writeTiming;                         //写时序

        FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);                                                //初始化FSMC配置

        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);                                                //使能BANK1
}

/*******************************************************************************
@name    :Write_cmd
@brief   :SPI写入命令函数
@param   :None
@return  :None
*******************************************************************************/
void Write_cmd(u8 data)
{
        data=data;
        * (__IO u8 *)(FSMC_ADDR_CMD) = data;
}

/*******************************************************************************
@name    :Write_Data
@brief   :SPI写入数据函数
@param   :None
@return  :None
*******************************************************************************/
void Write_Data(u8 data)
{
        data=data;
        * (__IO u8 *)(FSMC_ADDR_DATA) = data;
}

#define FSMC_ADDR_DATA            ((u32) 0x6C000000 | (1<<0))
#define FSMC_ADDR_CMD                 ((u32) 0x6C000000)
收藏 评论3 发布时间:2023-3-29 14:15

举报

3个回答
xmshao 回答时间:2023-3-29 15:17:37
相信你把配置检查多篇了,其实 我刚才也仔细检查核对了2遍,包括你的地址什么的。


到目前为止 没有发现配置上的问题。


会不会是硬件上哪里弄错了呢?或者你把主频放低点测试下 看看如何?比方设置到80MHz.


另外,初始化代码里是否有加上这句 __HAL_RCC_SYSCFG_CLK_ENABLE();
Freesoul 回答时间:2023-4-3 18:44:32

void InitOLED (void) { GPIO_InitTypeDef GPIO_InitStructure;

/*GPIOA、B、C时钟使能*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC, ENABLE);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_OTG_FS);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_OTG_FS);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_OTG_FS);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_OTG_FS);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_FSMC);

/*WR、RS、CS、RD、D1、D2、D3推挽复用输出*/
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

/*D0推挽复用输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/*D4、D5、D6、D7推挽复用输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/*RESET推挽输出*/
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

InitFSMC();

} 问题已解决,具体原因还在分析,根据CUBE配置的端口来进行修改后能够输出对应的信号。需要将D0-D3复用为GPIO_AF_OTG_FS,如果有人遇到此类问题的话,可以参考一下。

butterflyspring 回答时间:2023-4-6 11:30:33
再次查询了一下参考手册,楼主的验证是符合手册的,应该是AF10。
同时看了一下标准库,可能是时间原因,库中是没有明显STM32F412文件选项,412是后出来的产品。
而早期的407等FSMC在库中用的是AF12。 所以楼主用AF10是正确的。
STM32F412 FSMC AF10 1.png
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版