因為工作項目需求,需要使用STM32與FPGA通信進行聯合開發,兩者通信,自然首選STM32自帶的FSMC通信接口。為了搞清楚FSMC的時序與尋址細節,特使用邏輯分析儀對FSMC的8位、16位、32位數據寫操作進行了抓取分析,從而得到了FSMC的時序與尋址細節。時間匆忙,少了很多廢話的部分,具體的后面再完善吧,具體意圖見本文標題。腰好痛啊,最近身體和大腦一直超負荷運轉,是該出去轉轉,出去運動運動了。 8位操作方式:對地址65534寫8位的數i代碼 *(vu8*)(Bank1_SRAM3_ADDR+65534)=i;
i++;
|
對地址65534寫8位的數i時序波形 對地址65535寫8位的數i代碼 *(vu8*)(Bank1_SRAM3_ADDR+65534)=i;
i++;
|
對地址65535寫8位的數i時序波形 STM32通過FSMC寫8位數據:C代碼中地址為實際要寫入的地址字節,若將FSMC 的數據位寬配置為16位,則每次尋址實際都尋址了兩個字節,例如,FSMC的地址總線值為0,則實際位于地址0有16位,兩個字節,因此需要通過高低字節控制信號來區分,即LB和UB信號(注意:所有控制信號都是低電平有效)。例如當希望對地址0上的高字節進行尋址時,則FSMC總線地址值任然為0,同時LB無效(高電平)UB有效(低電平),即可實現對地址0上的高字節單獨尋址。假設C代碼中的要寫入的地址為C_Addr,則實際FSMC總線上地址線的值與LB、UB值的狀態為: FSMC_ADDR = C_Addr/2 FSMC_LB = C_Addr%2 FSMC_UB =~ (C_Addr%2) 16位操作方式:對地址65534寫16位的數6555代碼 *(vu16*)(Bank1_SRAM3_ADDR+65534)=6555;
|
對地址65534寫16位的數6555時序波形 
對地址65535寫16位的數6555代碼 *(vu16*)(Bank1_SRAM3_ADDR+65535)=6555;
|
對地址65535寫16位的數6555時序波形 STM32通過FSMC寫16位數據:C代碼中地址為實際要寫入的地址字節,若將FSMC 的數據位寬配置為16位,則每次尋址實際都尋址了兩個字節,例如,FSMC的地址總線值為0,則實際位于地址0有16位,兩個字節,因此需要通過高低字節控制信號來區分,即LB和UB信號(注意:所有控制信號都是低電平有效)。例如當希望對地址0上的高字節進行尋址時,則FSMC總線地址值任然為0,同時LB無效(高電平)UB有效(低電平),即可實現對地址0上的高字節單獨尋址。假設C代碼中的要寫入的地址為C_Addr,則實際FSMC總線上地址線的值與LB、UB值的狀態為: 如果C_Addr為偶數,則 FSMC_ADDR = C_Addr/2 FSMC_LB = FSMC_UB = 0; FSMC一次性即可完成16位數據的寫入。 如果C_Addr為奇數,則實際FSMC會將數據分成兩個8位的數據來進行操作,因此效率會低很多。 先寫C_Addr,寫入數據字節為待寫入數據的高字節 FSMC_ADDR = C_Addr/2 FSMC_LB =1; FSMC_UB =0; 然后寫C_Addr + 1地址,寫入數據字節為待寫入數據的低字節 FSMC_ADDR = (C_Addr + 1) /2 FSMC_LB =0; FSMC_UB =1; 32位操作方式:對地址65534寫32位的數1265536(0x134F80)代碼 *(vu32*)(Bank1_SRAM3_ADDR+65534)= 1265536;
|
對地址65534寫32位的數0x134F80時序波形 對地址65535寫32位的數1265536(0x134F80)代碼 *(vu32*)(Bank1_SRAM3_ADDR+65535)= 1265536;
|
對地址65535寫32位的數0x134F80時序波形 對地址65536寫32位的數1265536(0x134F80)代碼 *(vu32*)(Bank1_SRAM3_ADDR+65536)= 1265536;
|
對地址65536寫32位的數0x134F80時序波形 對地址65537寫32位的數1265536(0x134F80)代碼 *(vu32*)(Bank1_SRAM3_ADDR+65537)= 1265536;
|
對地址65537寫32位的數0x134F80時序波形 STM32通過FSMC寫32位數據:C代碼中地址為實際要寫入的地址字節,若將FSMC 的數據位寬配置為16位,則每次尋址實際都尋址了兩個字節,例如,FSMC的地址總線值為0,則實際位于地址0有16位,兩個字節,因此需要通過高低字節控制信號來區分,即LB和UB信號(注意:所有控制信號都是低電平有效)。例如當希望對地址0上的高字節進行尋址時,則FSMC總線地址值任然為0,同時LB無效(高電平)UB有效(低電平),即可實現對地址0上的高字節單獨尋址。假設C代碼中的要寫入的起始地址為C_Addr,則實際FSMC總線上地址線的值與LB、UB值的狀態為: 如果C_Addr為4的倍數,則FSMC首先在起始地址處寫入待寫入數據的低字節和次低字節: FSMC_ADDR = C_Addr/2 FSMC_LB = FSMC_UB = 0; 然后FSMC再在起始地址+2處寫入待寫入數據的低字節和次低字節: FSMC_ADDR = (C_Addr+2)/2 FSMC_LB = FSMC_UB = 0; 只需要兩次16位數據寫入操作即可完成一個32位數據的寫入,因此效率較高。 如果C_Addr為奇數,則實際FSMC會將數據分成兩個8位的數據和一個16位的數據來進行操作,需要3次寫入操作才能完成32位數據的寫入(效率較低)。 FSMC首先在起始地址(C_Addr)位置以8位寫入方式寫入待寫入數據的低字節: FSMC_ADDR = C_Addr/2 FSMC_LB = 1; FSMC_UB = 0; 然后FSMC再在起始地址+2處(C_Addr + 2)以16位數據方式寫入帶寫入數據的次低字節和次高字節: FSMC_ADDR = (C_Addr+2)/2 FSMC_LB = FSMC_UB = 0; 最后FSMC再在起始地址+4處(C_Addr + 2)以8位寫入方式寫入待寫入數據的高字節: FSMC_ADDR = (C_Addr+4)/2 FSMC_LB = 0; FSMC_UB = 1; 小梅哥FPGA設計思想與驗證方法教程系列文檔
2015年07月10號于Snow Dream電子工作室
|