Hi, ich arbeite mit dem ov7670 kamera modul und kann mittlerweile ein "gutes" testbild darstellen. Leider habe ich mit dem generierten Testbilder der Kamera ein Problem, manchmal sind die Farbspalten verschoben (1/2 Pixel manchmal mehr), mir ist nicht klar wie dieses Bild zu stande kommen kann. Vielleicht hat jemand von euch eine Idee? Danke
Hi Uli, ich muss gestehen, dieses Fehlerbild habe ich noch nie gesehen ... Sieht fast so aus, als ob Dein Programm irgendwo zwischendurch den Einsatz verpasst bzw. aufgehalten wird. Evtl. durch eine ISP-Routine? Viele Grüße Igel1
Sieht nach versauten Synchronisations-Signalen oder nicht ganz abrissfreiem Datenstrom aus. Ohne zu wissen, mit welchem System (DMA ist fast ein Muss) du die Daten einziehst, kann man aber nicht viel weiter sinnvoll spekulieren. Das Pattern sieht sonst korrekt aus (vom etwas flachen Rot abgesehen). Gibst du die Daten auf einen TFT im 565 Mode aus?
Hallo Andreas und Fitzebutze, erstmal ganz herzlichen Danke für eure Antworten! Zu meinem Programm, ich verwende einen STM32F4 MCU: - Bilder werden über die DCMI-Schnittstelle eingelesen - Verwende DMA und der Modus ist zirkular (im Normal Mode bekomme ich keine Daten in den DMA) - Die Farben werden im RGB565 Modus von der Kamera an den MCU gegeben und als RGB565 auf dem Display dargestellt. - Mein Programm hat nur eine ISR Routine, und das habe ich mir auch gedacht, in Verbindung mit dem zyklischen DMA schreiben könnte das sein... nur ist das eine richtige Vermuting? Hier meine mein IRQHandler, die Variable frame_read wird in der main aufgegriffen und mit if, ein Bild auf das Display geschrieben. Danach wird dma_frame_read zurückgesetzt. Die meisten "guten" Bilder bekomme ich bei jedem zweiten Durchgang.
1 | void DMA2_Stream1_IRQHandler(void) |
2 | {
|
3 | if ((DMA2->LISR & DMA_LISR_TCIF1) && (DMA2_Stream1->CR & DMA_SxCR_TCIE)) |
4 | {
|
5 | DMA2->LIFCR = DMA_LIFCR_CTCIF1; |
6 | frame_read = 1; |
7 | } |
8 | |
9 | } |
Uli S. schrieb: > Hier meine mein IRQHandler, die Variable frame_read wird in der main > aufgegriffen und mit if, ein Bild auf das Display geschrieben. Danach > wird dma_frame_read zurückgesetzt. Die meisten "guten" Bilder bekomme > ich bei jedem zweiten Durchgang. Das ist ein Klassiker, der schief geht, leider eben typischerweise genau so sporadisch wie in deinem Fall. Stichwörter "Race condition" und "non-atomic access". Zur Behebung: Stichwort "Buffer queue". Die meisten Implementierungen dieser Art nutzen zwei Pointer "head" und "tail", head darf nur die ISR verändern, tail nur die Polling-Routine (aus der Hauptschleife aufgerufen). Im Prinzip musst du dein Programm im Disassembly scharf anschauen, und dir klar sein, dass die ISR irgendwann dazwischen zuschlagen kann. Manche Architekturen haben natürlich atomare Zugriffe präsent, aber am besten portabel ist es nach dem Buffer-Queue-Konzept.
Fitzebutze, danke für deine Antwort! Leider bin ich mir nicht sicher wie ich die Buffer Queue umstetzen kann (da Daten unterschiedlich Geschrieben und gelesen werden). Mein Problem die durch den DMA werden die ein Buffer Array, dma_frame_buffer, in einem Durchgang geschreiben. Nicht jedes einzelne Element. Und die Daten werden gelesen, Pixel für Pixel. Wie kann ich die Buffer Queue umsetzen so wie meine Codestruktur gerade ist? Ich hoffe das ist verständlich, hier ein Überblick meines Codes: IRQ Handler:
1 | void DMA_IRQ(void) |
2 | {
|
3 | if (DMA_Full && DMA_Enabled) |
4 | {
|
5 | DMA->CLEARFLAG = CLEAR; //Clear Interrupt Flag |
6 | |
7 | //Im Hintergrund werden die über DCMI übertragenen daten in folgendes Array geladen: dma_frame_buffer
|
8 | |
9 | //DMA Indicator
|
10 | dma_frame_read = 1; |
11 | }
|
12 | }
|
Meine Main:
1 | int main (void) |
2 | {
|
3 | if(dma_frame_read == 1) |
4 | {
|
5 | for(int pixel_counter=0; pixel_counter<253; pixel_counter++) |
6 | {
|
7 | Display_Pixel(dma_frame_buffer[pixel_counter]); |
8 | dma_frame_read = 0; |
9 | }
|
10 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.


