您的位置:首页 > 其它

关于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电源或驱动器电源关闭。

如果你出现问题了,可以参考以上几种解决办法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stm32 emwin