OV7670 Testbild mit manchmal verschobenen Streifen

OP #5762022
Lesenswert?
• ▲
▼
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
Angehängte Dateien:
Gast #5763097
Lesenswert?
• ▲
▼
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?
OP #5764371
Lesenswert?
• ▲
▼
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
}
Gast #5764503
Lesenswert?
• ▲
▼
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.
OP #5837549
Lesenswert?
• ▲
▼
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
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.