Hallo, habe bereits diversen Code mit meiner Hardware ausprobiert, unter anderem den Code von Uwe (Beitrag "Camera Modul (OV9655) am STM32F4 Discovery Board") und den zum Open407V-D mitgelieferten Code. Leider bekomme ich kein gescheites Kamerabild auf dem Display, was mich wundert, da der Code von Uwe funktionieren sollte. Habe natürlich die Hardwarepins im Code umgebogen. Die Displayinitialisierung funktioniert, ich kann GUIText darauf schreiben. Mit einigen wilden Einstellungen in den Registern HSTART HSTOP der OV9655 kann man ein Kamerabild auf dem Display erahnen. Mich wundert, dass ich dieses Problem (Streifenbild) bei verschiedenen Kameras mit Code habe, der eigentlich funkltionieren sollte bzw bei anderen funktioniert hat. Das STMDiscovery habe ich auch schon getauscht, gleiches Problem. Die Portpins kommen Hardwaremäßig alle dort an, wie sie in der Software eingetragen sind. Ein Hardwareproblem schließe ich also aus. Hat jemand gleiche Probleme gehabt oder eine Idee, was der Fehler sein könnte?
Das erste Bild sieht für mich ganz stark danach aus, als würde die horizontale Auflösung bzw. Breite vom Bild nicht mit der Auflösung des Displays übereinstimmen. D.h. Bild ist z.B. 260 Pixel breit, das Display 320 Pixel und du schreibst alles linear in den Display-Speicher ohne auf die Breite zu achten.
Das würde auch damit zusammenpassen, dass bei einigen Einstellungen in H(orizontal)Start und HStop das Bild einigermaßen zu erkennen ist. Mich wundert jedoch, dass ich Code probiert habe, der für die gleiche Cam und das gleiche Display geschrieben wurde und als funktionierend im Netz herumwandert. Meine HardwareIDs lauten LCDID = 0x8989 CamPID = 0x96 Ich suche weiter nach der Ursache.
Hi Marcel,
der Code von meiner Seite funktioniert...
natürlich nur mit absolut gleicher Hardware :-)
>Habe natürlich die Hardwarepins im Code umgebogen.
also hast du nicht die gleiche Hardware
(was für ein Display benutzt du bzw. welcher Display-Chip)
vermutlich stimmt der Anzeigemode von deinem Display nicht
es muss im Landscape-Mode initialisiert werden
die Start Adresse X=0, Y=0 ist eine Ecke vom Display
und durch das autoincrement beim zeichnen
muss zuerst die Längere Seite (die mit 320 Pixel) gezeichnet werden
das 321 Pixel ist dann in der nächsten Zeile
Prüf das mal ob dein Display so initialisiert ist :
stell das Display auf "Landscape-Mode"
setz den Cursor am Display auf X=0, Y=0
und lass 320 Pixel zeichnen (per autoincrement)
das muss eine einzelne Linie an der längeren Seite ergeben
640 Pixel ergeben dann zwei Zeilen usw
Gruss Uwe
Ich habe auch das ov9655 und das ssd8989 (id siehe oben), habe den ini-vektor von dir (display und cam) ausprobiert. Leider ohne Erfolg. Dann hab ich die Register unter die Lupe genommen und im Datenblatt gelesen, leider sind die Informationen zu den Registern sehr spärlich.
Ein paar Fragen hab ich: Was sollte passieren, wenn ich im DCMI einstelle: DCMI_CaptureMode_SnapShot? Bei mir zeichnet er eine kurze Linie Pixel, so ca 5 - 10 Pixel lang. Wie sage ich dem Programm, dass es genau eine Linie (320 Px) zeichnen und dann aufhören soll? Welche Auswirkung hat Änderung der DMA Buffer Size? Bei mir keine, außer wenn ich den Buffer auf Null setze. Mir ist noch nicht ganz klar, wie der Mechanismus "Daten vom DCMI holen - Daten auf FSMC schreiben" funktioniert und wie ich da reinschauen und überprüfen kann, ob das richtige passiert. Wie der DMA selbst funktioniert, weiß ich. Edit: ich stelle gerade fest, dass sich das angezeigte Bild ändert, wenn ich im DCMI address setup time, address hold time und data setup time ändere. Wie berechne ich die für mich richtigen Daten?
wie schon gesagt, vergiss erst mal die Camera und löse erst mal das Problem mit dem Display danach löst sich das Camera-Problem von selbst >Wie sage ich dem Programm, dass es genau eine Linie (320 Px) zeichnen >und dann aufhören soll? wie steuerst du den das Display an ? du brauchst eine Funktion um den Cursor auf eine X/Y-Koordinate zu setzen und eine Funktion um an der Stelle vom Cursor das Pixel einzufärben also z.B
1 | setCursor(10,20); // setzt den Cursor auf X=10, Y=20 |
2 | drawPixel(0x1234); // zeichnet ein Pixel mit der Farbe 0x1234 |
und für eine Linie würde ich eine For-Schleife empfehlen
1 | setCursor(0,0); |
2 | for(n=0;n<320;n++) { |
3 | drawPixel(0x1234); |
4 | } |
schreib wieder wenn das funktioniert
Die Displayansteuerung funktioniert. Dein Test-Code (rote Linie zeichnen) und andere Codes (GUI Text schreiben) laufen korrekt mit meinem Display.
Sorry, oben schrieb ich was über dcmi setup time, gemeint waren aber die fsmc-Zeiten. Das kuriose dabei ist: wenn ich diese Zeiten ändere, dann hat das zwar Auswirkungen auf das angezeigte Kamerabild, aber nicht auf andere Displayinhalte wie Text schreiben oder Linien zeichnen.
>Mir ist noch nicht ganz klar, wie der Mechanismus "Daten vom DCMI holen >- Daten auf FSMC schreiben" funktioniert und wie ich da reinschauen und >überprüfen kann, ob das richtige passiert. Wie der DMA selbst >funktioniert, weiß ich. die Kamera sendet (einmal angestupst) ständig das aktuelle Bild und zwar Pixel für Pixel Bild für Bild mann muss am Anfang am Display den Cursor auf x=0, y=0 setzen und weil die Auflösung vom Display und die von der Camera genau gleich ist, füllt ein Camera-Bild genau ein Display-Bild aus das "synronisiert" sich sozusagen selbst der DMA holt ein Pixelwert von der Camera und sendet ihn direkt ins RAM vom Display die Camera erhöht dann intern auf die nächste Pixel-Adresse und das Display macht das gleiche dann kommt das nächste Pixel usw. wenn du eine andere Auflösung willst (das geht auch) kannst du die Camera z.B. QQVGA auf 160x120 Pixel einstellen, dann muss am Display aber auch das Aktiv-Window genau auf diese Größe eingestellt werden >Sorry, oben schrieb ich was über dcmi setup time, gemeint waren aber die >fsmc-Zeiten. Das kuriose dabei ist: wenn ich diese Zeiten ändere, dann >hat das zwar Auswirkungen auf das angezeigte Kamerabild, aber nicht auf >andere Displayinhalte wie Text schreiben oder Linien zeichnen. das verstehe ich auch nicht ganz, was sein kann ist, das du den FSMC so langsam einstellst, das die Daten von der Camera schneller kommen als sie auf das Display geschrieben werden ich würde den FSMC so schnell wie möglich einstellen (gerade so das das Display noch funktioniert) kannst du leicht testen, wenn du die Zahlen verkleinerst wird irgendwann nichts mehr neues angezeigt >Was sollte passieren, wenn ich im DCMI einstelle: >DCMI_CaptureMode_SnapShot? Snapshot holt nur ein einzelnes Bild von der Camera und zeichnet es auf das Display (wie ein Foto) Nachtrag : mach mal ein Foto von dem Strich mit 320 Pixel und stell es hier rein >Die Displayansteuerung funktioniert. Dein Test-Code (rote Linie >zeichnen) und andere Codes (GUI Text schreiben) laufen korrekt mit >meinem Display. VORSICHT : diese Funktionen benutzen meist intern eine Funktion zum setzen vom Cursor, damit kannst du nicht erkennen ob der Landscape Mode aktiviert ist oder nicht im zweiten Bild das du gepostet hast, sieht man das er eben nicht im Landscape-Mode ist....und so wird das nie was Gruss Uwe
"von DEM strich mit 320 pixel" - welchen Strich meinst du? Ich habe hier keinen Strich mit 320 Pixel. Meinst du den Strich, der bei mir erscheint, wenn ich DCMI_CaptureMode_SnapShot einstelle? Da gibts nich viel zu sehen, das sind nur 20 Pixel. Woher weiß ich eigentlich den Adressoffset für das RAM des Display? In deinem Code steht was von Seite 1316 des refman, aber bei meinem hört der FSMC-Teil auf S.1277 auf. Mich verwirrt noch immer, dass sich das "Kamerabild" ändert, wenn ich an den Timings rumspiele. Muss ich FSMC und DCIM irgendwie aufeinander abstimmen? Und warum ist es egal, welchen Memorytype ich beim initialisieren wähle, es ändert sich dabei nichts an der Funktionalität.
Kein Problem, hab jetzt nochmal von vorn angefangen den Code umzuschreiben (hatte vorher einen Mischmasch aus deinem und nem anderen) und nun hab ich Bild. Zwar mit Falschfarben, aber das löse ich auch noch. Ich werd auch die Codes vergleichen, woran es nun lag. Dennoch: Woher hast du das Adressoffset für das RAM?
> Dennoch: Woher hast du das Adressoffset für das RAM? ich habe die Rev.3 vom Referenz Manual RM0090 vom Nov.2012 das PDF hat 1416 Seiten und auf der Seite 1316 wird der externe Adressraum vom FSMC beschrieben Kapitel 32.4 "External device address mapping" die eigentliche Adresse ist relativ egal (das Display hat sowieso keine Adressleitungen) sie muss nur irgendwo in BANK1/PSRAM1 liegen damit der richtige (weil einzige) ChipSelect-Pin aktiviert wird (NE1 an PD7) und fuer NE1 sind Adressen zwischen 0x60000000 und 0x63FFFFFF zuständig ich hab halt 0x60000000 benutzt du könntest aber genausogut 0x61234567 benutzen das macht keinen Unterschied das einzigste was noch eine Rolle spielt ist, wo der RS-Pin vom Display angeschlossen ist (bei mir an A19=PE3) und das du einmal eine Adresse hast mit RS-Pin = Lo und einmal eine mit RS-Pin = Hi die das obige Kriterium erfüllt aber das alles ist bei dir richtig eingestellt sonst würde gar nichts auf dem Display angezeigt werden >Zwar mit Falschfarben das klingt mir nach Display im Mode BGR statt RGB (oder andersrum) Gruss Uwe
So, hab die Tage noch etwas mit den Registern rumgespielt und nun endlich ein passendes Set gefunden. Dafür habe ich die serielle Schnittstelle eingebunden um online die Register ändern zu können und die direkte Wirkung auf dem Display zu sehen. Habe nun ein lauffähiges Projekt basierend auf dem Code von Uwe, welches das Kamerabild der OV9655 (Standardmodul von Waveshare) auf dem Display (HY32C) anzeigt. Motherboard ist das Open407V-D. Es wurden keine Hardwareveränderungen vorgenommen. Einfach alle Module anstecken, flashen und los. Einzig ein paar Pfade müssen in den Projekten angepasst werden.
Hi! I've got the same problem like you on the 1st picture. Could you please check on my code? https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F4Discovery%20%2b%20DCMI%20%2b%20OV7660%20%28OV7670%29&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FAllItems%2Easpx%3FPaged%3DTRUE%26p_StickyPost%3D%26p_DiscussionLastUpdated%3D20130725%252015%253a28%253a39%26p_ID%3D32572%26View%3D%257bF47A9ED8%252dE726%252d42BE%252dACED%252d732F13B66581%257d%26FolderCTID%3D0x012001%26PageFirstRow%3D41¤tviews=46 Thank you! Jeno
Please check all wirings and clocks first (where is your cams xclk? please compare with the code I posted). After that you can compare the registersettings and the order of the registersettings! the order is important! Very important are things like resolution, h and v polarity.
The XCLK is connected to the PA8 pin (RCC_MCO1Config(RCC_MCO1Source_HSI, RCC_MCO1Div_1); - 8 MHz) It seems to be working, because it can communicate over I2C. Did you managed to get working ov7670? I only saw ov9650 in your code. I'll try to compare the different registers.
I managed to get picture, but it's black on the left side, and the resolution seems to be wrong. Did you saw this type of problem before? Thanks!
It seems to be a problem with the resolution or/and the hstart/hstop vstart/vstop bits?
I found out, that if I didn't change the resolution from the default 640*480 there is no black line, and the resolution is also ok. When I change the resolution to cif I receive 2 picture in 640 pixel width side-by-syde with black line. Maybe the camera did not crop the image, and sends windowed picture? I'll try to crop it with DCMI.
if you change the resolution of the camimage, then you will receive less data per picture. but the display doesnt know this! you have to change the active window on the display also :)
I did not used a display, only a virtual one on the pc. The problem was with hstart hstop registers. I corrected them, and the image is fine now. Thank you for your help!
hello, can you please send me the complete code of your project
Jeno Kocsis schrieb: > I managed to get picture, but it's black on the left side, and the > resolution seems to be wrong. Did you saw this type of problem before? > Thanks! Could you please send me the code sir i want to develop this.
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.