调试了几天STM32的FSMC驱动液晶的程序,原先在MDK上编译下载后可以运行的程序,移植到IAR上后就出现了问题,(以下描述的是在从新上电复位后运行的现象,但在jlink调试过程中运行都是正常的)
问题是这样的:程序运行完 *(__IO uint16_t *) (Bank1_LCD_C)= index; 后就不在往下运行了,反复实验了N次,只有一次进入了Hardfault, 而剩下的情况都是mcu不运行了。查了很多资料终于在一片《STM32F103 FSMC 同步模式 学习笔记2》文章中找到了答案,原因是在FSMC初始化过程中出现的,我们初学者编程序都有以个缺点,就是定义申请的变量后都不进行变量初始化操作(特别是定义了一些较为复杂的结构体之后),而在我们使用的过程中又忽视一些未使用的变量,这些都会导致一系列我们不想初相的问题,而编译器有时候也不可能智能到按照我们默认地想法为我们做好各种细节的操作。
FSMC_NORSRAMInitTypeDef结构体的定义是这样的:
typedef struct
{
uint32_t FSMC_Bank;
uint32_t FSMC_DataAddressMux;
uint32_t FSMC_MemoryType;
uint32_t FSMC_MemoryDataWidth;
uint32_t FSMC_BurstAccessMode;
uint32_t FSMC_AsynchronousWait;
uint32_t FSMC_WaitSignalPolarity;
uint32_t FSMC_WrapMode;
uint32_t FSMC_WaitSignalActive;
uint32_t FSMC_WriteOperation;
uint32_t FSMC_WaitSignal;
uint32_t FSMC_ExtendedMode;
uint32_t FSMC_WriteBurst;
FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct;
FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;
}FSMC_NORSRAMInitTypeDef;
我的参看的程序在对FSMC_NORSRAMInitTypeDef结构体的初始化过程中是这样的:
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; //Bank1基址0x60000000
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //关闭地址、数据线混合模式
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR; //选择存储器模式,选择与液晶控制器类似的模式
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //数据宽度16位
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; //关闭连续地址模式,自动增地址
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; //连续模式中地址线等状态电平
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //关闭连续模式中的包传输
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_DuringWaitState;//FSMC_WaitSignalActive_BeforeWaitState;//连续传输模式中在等待状态前发等待信号
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //使能FSMC写操作
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 = &FSMC_Timing; //用FSMC_Timing结构体设定读写时序
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //以上参数初始化FSMC
这个结构体初始化过程只对结构体里面的13项进行了初始化,而结构体定义了15项,也就是说我们默认为进行初始化操作的另外两项内存值应该都0x00,而事实并非我们所想想的那样,问题就出在这里。解决的方法也很简单,那就是加一句将FSMC_NORSRAMInitTypeDef初始化为0x00的语句接可以了。
FSMC_NORSRAMInitTypeDef 结构体未进行初始化可能会出现一下几种纠结的情况:
1、像我上面遇到的一样,用jlink调试是可以运行,但是系统从新上电后就会出现运行完一个FSMC的读写操作后就会出现Hardfault或则程序直接死在了这里(应该说单片机进入了某种等待状态,这种状态如果是处在jlink调试模式下,就可能导致仿真不能停止的情况,而只能关闭jlink调试,从新复位开发板,然后从新开始jlink调试运行)
2、程序可以脱机运行,但是运行得很慢