調(diào)試了幾天STM32的FSMC驅(qū)動液晶的程序,原先在MDK上編譯下載后可以運(yùn)行的程序,移植到IAR上后就出現(xiàn)了問題,(以下描述的是在從新上電復(fù)位后運(yùn)行的現(xiàn)象,但在jlink調(diào)試過程中運(yùn)行都是正常的)問題是這樣的:程序運(yùn)行完 *(__IO uint16_t *) (Bank1_LCD_C)= index; 后就不在往下運(yùn)行了,反復(fù)實(shí)驗(yàn)了N次,只有一次進(jìn)入了Hardfault, 而剩下的情況都是mcu不運(yùn)行了。查了很多資料終于在一片《STM32F103FSMC同步模式學(xué)習(xí)筆記2》文章中找到了答案,原因是在FSMC初始化過程中出現(xiàn)的,我們初學(xué)者編程序都有以個缺點(diǎn),就是定義申請的變量后都不進(jìn)行變量初始化操作(特別是定義了一些較為復(fù)雜的結(jié)構(gòu)體之后),而在我們使用的過程中又忽視一些未使用的變量,這些都會導(dǎo)致一系列我們不想初相的問題,而編譯器有時候也不可能智能到按照我們默認(rèn)地想法為我們做好各種細(xì)節(jié)的操作。
FSMC_NORSRAMInitTypeDef結(jié)構(gòu)體的定義是這樣的:
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結(jié)構(gòu)體的初始化過程中是這樣的:
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; //Bank1基址0x60000000
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //關(guān)閉地址、數(shù)據(jù)線混合模式
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR; //選擇存儲器模式,選擇與液晶控制器類似的模式
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //數(shù)據(jù)寬度16位
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; //關(guān)閉連續(xù)地址模式,自動增地址
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; //連續(xù)模式中地址線等狀態(tài)電平
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //關(guān)閉連續(xù)模式中的包傳輸
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_DuringWaitState;//FSMC_WaitSignalActive_BeforeWaitState;//連續(xù)傳輸模式中在等待狀態(tài)前發(fā)等待信號
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //使能FSMC寫操作
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //關(guān)閉連續(xù)模式中的等待信號
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; //關(guān)閉時序擴(kuò)展模式
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //關(guān)閉并發(fā)寫入模式
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_Timing; //用FSMC_Timing結(jié)構(gòu)體設(shè)定讀寫時序
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //以上參數(shù)初始化FSMC
這個結(jié)構(gòu)體初始化過程只對結(jié)構(gòu)體里面的13項(xiàng)進(jìn)行了初始化,而結(jié)構(gòu)體定義了15項(xiàng),也就是說我們默認(rèn)為進(jìn)行初始化操作的另外兩項(xiàng)內(nèi)存值應(yīng)該都0x00,而事實(shí)并非我們所想想的那樣,問題就出在這里。解決的方法也很簡單,那就是加一句將FSMC_NORSRAMInitTypeDef初始化為0x00的語句接可以了。
FSMC_NORSRAMInitTypeDef 結(jié)構(gòu)體未進(jìn)行初始化可能會出現(xiàn)一下幾種糾結(jié)的情況:
1、像我上面遇到的一樣,用jlink調(diào)試是可以運(yùn)行,但是系統(tǒng)從新上電后就會出現(xiàn)運(yùn)行完一個FSMC的讀寫操作后就會出現(xiàn)Hardfault或則程序直接死在了這里(應(yīng)該說單片機(jī)進(jìn)入了某種等待狀態(tài),這種狀態(tài)如果是處在jlink調(diào)試模式下,就可能導(dǎo)致仿真不能停止的情況,而只能關(guān)閉jlink調(diào)試,從新復(fù)位開發(fā)板,然后從新開始jlink調(diào)試運(yùn)行)
2、程序可以脫機(jī)運(yùn)行,但是運(yùn)行得很慢
評論