关于STM32F103使用外部SRAM运行EMWIN时死机的问题
2015-08-23 00:13
330 查看
关于STM32F103使用外部SRAM运行EMWIN时死机的问题
使用stm32f103平台使用外部SRAM运行EMWIN出现死机的问题,困扰了我一晚上,后来查找了一些资料,最终解决了问题。下面将解决办法列出来:0.确保硬件无误,已经可以使用内部SRAM跑起来
1.检查LCD驱动
由于STM32使用FSMC驱动LCD,我的问题就出在了LCD的FSMC时序配置上:
###代码stm3210e_eval_fsmc_lcd.c
/** * @brief LCD FSMC 模式配置 * @param 无 * @retval 无 */ static void LCD_FSMCConfig(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef readWriteTiming; FSMC_NORSRAMTimingInitTypeDef writeTiming; /* 使能FSMC时钟*/ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); readWriteTiming.FSMC_AddressSetupTime = 0x01; //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到 readWriteTiming.FSMC_DataSetupTime = 0x04; // 数据保存时间为16个HCLK,因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。 readWriteTiming.FSMC_BusTurnAroundDuration = 0x00; readWriteTiming.FSMC_CLKDivision = 0x00; readWriteTiming.FSMC_DataLatency = 0x00; readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A 4000 writeTiming.FSMC_AddressSetupTime = 0x00; //地址建立时间(ADDSET)为1个HCLK writeTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(A writeTiming.FSMC_DataSetupTime = 0x03; //数据保存时间为4个HCLK writeTiming.FSMC_BusTurnAroundDuration = 0x00; writeTiming.FSMC_CLKDivision = 0x00; writeTiming.FSMC_DataLatency = 0x00; writeTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A //在地址数\据线不复用的情况下,ABCD模式的区别不大 //本成员配置只有使用扩展模式才有效 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_BANK1_NORSRAM; //NOR FLASH的BANK FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //数据线与地址线不复用 // FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR; //存储器类型NOR FLASH FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //数据宽度为16位 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; //使用异步写模式,禁止突发模式 FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; //本成员的配置只在突发模式下有效,等待信号极性为低 FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //禁止非对齐突发模式 FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; //本成员配置仅在突发模式下有效。NWAIT信号在什么时期产生 FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //写使能 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //本成员的配置只在突发模式下有效,禁用NWAIT信号 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; //禁止扩展模式,扩展模式可以使用独立的读、写模式 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //禁止突发写操作 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming; //写时序 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); /* 使能 FSMC Bank1_SRAM Bank */ FSMC_NORSRAMCmd(FSMC_BANK1_NORSRAM, ENABLE); }
一定要注意readWriteTiming、writeTiming两个结构体的时序设置,需要根据你LCD驱动器手册上的时序进行相应的修改,以上配置为ILI9341驱动的LCD。
2.检查SRAM驱动
SRAM驱动按照例程上的移植过来,但是要根据SRAM芯片的时序设置FSMC。
###代码stm3210e_eval_fsmc_lcd.c
/** * @brief Configures the FSMC and GPIOs to interface with the SRAM memory. * This function must be called before any write/read operation * on the SRAM. * @param None * @retval None */ void SRAM_Init(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef p; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF, ENABLE); /*-- GPIO Configuration ------------------------------------------------------*/ /*!< SRAM Data lines configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOE, &GPIO_InitStructure); /*!< SRAM Address lines configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_Init(GPIOD, &GPIO_InitStructure); /*!< NOE and NWE configuration 无需改变*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5; GPIO_Init(GPIOD, &GPIO_InitStructure); /*!< NE3 configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOG, &GPIO_InitStructure); /*!< NBL0, NBL1 configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOE, &GPIO_InitStructure); // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO_Init(GPIOG, &GPIO_InitStructure); // GPIO_SetBits(GPIOG,GPIO_Pin_9); /*-- FSMC Configuration ------------------------------------------------------*/ p.FSMC_AddressSetupTime = 0; p.FSMC_AddressHoldTime = 0; // p.FSMC_DataSetupTime = 1; p.FSMC_DataSetupTime = 3; //数据保持时间(DATAST)为3个HCLK 4/72M=55ns(对EM的SRAM芯片) p.FSMC_BusTurnAroundDuration = 0; p.FSMC_CLKDivision = 0; p.FSMC_DataLatency = 0; p.FSMC_AccessMode = FSMC_AccessMode_A; FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_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); /*!< Enable FSMC Bank1_SRAM Bank */ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
要注意此处p.FSMC_DataSetupTime = 3; 这个时间是跟你的系统时钟和你得SRAM手册设置的,死机问题主要出现在这里。
3.检查EMWIN配置
/********************************************************************* * * LCD_X_DisplayDriver * * Function description: * This function is called by the display driver for several purposes. * To support the according task the routine needs to be adapted to * the display controller. Please note that the commands marked with * 'optional' are not cogently required and should only be adapted if * the display controller supports these features. * * Parameter: * LayerIndex - Index of layer to be configured * Cmd - Please refer to the details in the switch statement below * pData - Pointer to a LCD_X_DATA structure * * Return Value: * < -1 - Error * -1 - Command not handled * 0 - Ok */ int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) { int r; (void) LayerIndex; (void) pData; switch (Cmd) { case LCD_X_INITCONTROLLER: { // // Called during the initialization process in order to set up the // display controller and put it into operation. If the display // controller is not initialized by any external routine this needs // to be adapted by the customer... // // ... //LCD_Init(); //此处不放LCD_Init函数,在MAIN函数中放在SRAM函数初始化前面。 return 0; } default: r = -1; } return r; }
注意LCD初始化函数位置。
4.检查MAIN函数
将LCD初始化函数放在SRAM函数之前。
4.看到网上说还有一种方法是在SRAM初始化前要将LCD电源或驱动器电源关闭。
如果你出现问题了,可以参考以上几种解决办法。
相关文章推荐
- Keil STM32工程环境搭建
- stm32之RTC
- STM32串口操作相关事项
- STM32 SPI工作在主模式时用DMA方式接收数据
- STM32 配置定时器让引脚输出PWM波形
- [嵌入式裸机课程]Cortex-M3开发实训班
- stm32的1602操作显示
- STM32 UART DMA实现未知数据长度接收(转自amoBBs)
- STM32F429 LTDC学习笔记1
- stm32学习笔记---入门环境搭建及开发板的选用
- stm32中断服务函数的机制
- pc寄存器与可寻址空间
- 关于STM32 库函数3.5版的各种坑
- STM32 Printf函数实现方法 (转载)
- STM32 IAP
- 红龙103开发板CAN IAP
- STM32的时钟基础知识
- STM32使用16M外部晶振时出现异常
- STM32开发板点灯
- [学习笔记]使用GNU Toolchain在STM32上跑起一个最小OS