STM32 OV2640將數據緩存至SRAM
流程設計
流程如下:
-
初始化OV2640后,初始化DCMI和DMA,DCMI的初始化代碼與原子開發板的代碼一致,這里主要是區分在DMA的初始化上:
ram_campic = (u16 *)my_malloc(SRAMEX, (lcddev.width * lcddev.height * 4)); DCMI2LCD_DMA_Init((u32)ram_campic, (lcddev.width * lcddev.height) * 4, DMA_MemoryDataSize_HalfWord, DMA_MemoryInc_Enable);
RGB565是16個比特,2個字節,因此采用半字傳輸,總量為
(lcddev.width * lcddev.height) * 2
,存儲器地址遞增,初始化代碼內部定義外設寬度為32bit,即一次4個字節,半字傳輸需要傳2次,所以總數是4倍。 -
循環查詢幀接收flag,如果查到則停止DCMI(這一步冗余,因為在DCMI中斷和DMA中斷中已經停止了DCMI,而中斷的到達時刻要遠快於查詢),則將該幀打印至LCD或后續通過UDP發送出去
-
重新啟動DMA后等待穩定后啟動DCMI
-
中斷處理:
- 當DMA循環完一次之后,立即停止DMA,之后停止DCMI,清除中斷標記並將flag置位,如果順序相反,則DCMI停止的過程中DMA依然在工作,因此新的一幀圖像會將上一幀圖像的起始部分覆蓋,所以DMA收齊一幀后立即停止。
- 當一幀傳輸結束后觸發DCMI中斷,此時部分幀圖像數據依然在DMA的FIFO中,此時停止DCMI,等待DMA傳輸完成后將flag置位,這樣可以確保DMA將一幀圖像完整的傳輸結束。
- 由於一幀傳完后DCMI和DMA均停止,中斷標記清除,因此主程序while循環將檢測到flag並進行處理,結束后重新啟動DMA和DCMI
問題匯總
SRAM數據緩存不完整
這個問題表現在外部即LCD打印SRAM的數據時會有大片的黑屏或錯位,產生原因是DMA的訪問速度過快,部分數據沒有及時存儲而被拋棄。解決方法是減小FSMC的寫地址和數據的時間:
FSMC_ReadWriteTimingStructure.FSMC_AddressSetupTime = 1; //地址建立時間,修改前為15
FSMC_ReadWriteTimingStructure.FSMC_AddressHoldTime = 0x00; //地址保持時間,模式A未用到
FSMC_ReadWriteTimingStructure.FSMC_DataSetupTime = 3; //數據保持時間,0x18個HCLK,6* 24 ns,改之前0x18
FSMC_ReadWriteTimingStructure.FSMC_BusTurnAroundDuration = 0x00;
FSMC_ReadWriteTimingStructure.FSMC_CLKDivision = 0x00;
FSMC_ReadWriteTimingStructure.FSMC_DataLatency = 0x00;
FSMC_ReadWriteTimingStructure.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
LCD打點過程中部分屏幕黑屏
如果SRAM的時序沒有問題,則這個問題的原因是DMA的數據傳輸的數據量不足,因此調整傳輸量即可。
邊緣圖像小范圍錯位
這個問題的原因是由於DMA和DCMI的停止順序沒有控制好造成的,即上面提到的DCMI停止的過程中DMA依然在傳輸數據,因此將下一幀的部分數據替到了上一幀的開始位置,調整開關DMA和DCMI的順序即可解決
屏幕花屏
大范圍斜紋花屏的原因是打點函數的x、y和攝像頭的掃描順序不一致造成的,即攝像頭行掃描的數據被按列打點,而列坐標范圍無法覆蓋到行坐標,因此出現斜紋,調整打點的掃描方向或打點順序即可。