Forum: Mikrocontroller und Digitale Elektronik STM32F407 Black und No-Arduino


von grundschüler (Gast)


Angehängte Dateien:

Lesenswert?

Ich kämpfe mit dem oben angegebenen board. Eigentlich ohne Hal und ohne 
arduino. Ohne Hal hab ich bereits aufgegeben.

Problem mit dem ili9341: Irgendwie klappt die Initialisierung nicht. Es 
sieht so aus, als gäbe es zwei Speicherbereiche, die parallel 
beschrieben werden. In  früheren ilis konnte man Orientation einstellen: 
Bildaufbau von oben links bis von unten rechts. Das finde ich weder im 
Init-code noch im manual (240 Seiten). Das nit Anfangs- und Endwert 
klappt auch nicht. Der Bereich zwischen Anfangs- und Endwert wird  n i c 
h t  beschrieben (weißer Rahmen). Warum?

Hier der init-code:

1
void ili9341_init(void)
2
{
3
  LCD_REG = ILI9341_RESET;
4
  HAL_Delay(60);
5
    
6
  LCD_REG = ILI9341_DISPLAY_OFF;
7
8
  LCD_REG = ILI9341_POWERA;
9
  LCD_RAM = 0x39;
10
  LCD_RAM = 0x2C;
11
  LCD_RAM = 0x00;
12
  LCD_RAM = 0x34;
13
  LCD_RAM = 0x02;
14
15
  LCD_REG = ILI9341_POWERB;
16
  LCD_RAM = 0x00;
17
  LCD_RAM = 0xC1;
18
  LCD_RAM = 0x30;
19
20
  LCD_REG = ILI9341_DTCA;
21
  LCD_RAM = 0x85;
22
  LCD_RAM = 0x00;
23
  LCD_RAM = 0x78;
24
25
  LCD_REG = ILI9341_DTCB;
26
  LCD_RAM = 0x00;
27
  LCD_RAM = 0x00;
28
29
  LCD_REG = ILI9341_POWER_SEQ;
30
  LCD_RAM = 0x64;
31
  LCD_RAM = 0x03;
32
  LCD_RAM = 0x12;
33
  LCD_RAM = 0x81;
34
35
  LCD_REG = ILI9341_PRC;
36
  LCD_RAM = 0x20;
37
38
  LCD_REG = ILI9341_POWER1;
39
  LCD_RAM = 0x23;
40
41
  LCD_REG = ILI9341_POWER2;
42
  LCD_RAM = 0x10;
43
44
  LCD_REG = ILI9341_VCOM1;
45
  LCD_RAM = 0x3E;
46
  LCD_RAM = 0x28;
47
48
  LCD_REG = ILI9341_VCOM2;
49
  LCD_RAM = 0x86;
50
51
  LCD_REG = ILI9341_MAC;
52
  LCD_RAM = 0x48;
53
54
  LCD_REG = ILI9341_PIXEL_FORMAT;
55
  LCD_RAM = 0x55;
56
57
  LCD_REG = ILI9341_FRC;
58
  LCD_RAM = 0x00;
59
  LCD_RAM = 0x18;
60
61
  LCD_REG = ILI9341_DFC;
62
  LCD_RAM = 0x08;
63
  LCD_RAM = 0x82;
64
  LCD_RAM = 0x27;
65
66
  LCD_REG = ILI9341_3GAMMA_EN;
67
  LCD_RAM = 0x00;
68
69
  LCD_REG = ILI9341_COLUMN_ADDR;
70
  LCD_RAM = 0x00;
71
  LCD_RAM = 0x00;
72
  LCD_RAM = 0x00;
73
  LCD_RAM = 0xEF;
74
75
  LCD_REG = ILI9341_PAGE_ADDR;
76
  LCD_RAM = 0x00;
77
  LCD_RAM = 0x00;
78
  LCD_RAM = 0x01;
79
  LCD_RAM = 0x3F;
80
81
  LCD_REG = ILI9341_GAMMA;
82
  LCD_RAM = 0x01;
83
84
  LCD_REG = ILI9341_PGAMMA;
85
  LCD_RAM = 0x0F;
86
  LCD_RAM = 0x31;
87
  LCD_RAM = 0x2B;
88
  LCD_RAM = 0x0C;
89
  LCD_RAM = 0x0E;
90
  LCD_RAM = 0x08;
91
  LCD_RAM = 0x4E;
92
  LCD_RAM = 0xF1;
93
  LCD_RAM = 0x37;
94
  LCD_RAM = 0x07;
95
  LCD_RAM = 0x10;
96
  LCD_RAM = 0x03;
97
  LCD_RAM = 0x0E;
98
  LCD_RAM = 0x09;
99
  LCD_RAM = 0x00;
100
101
  LCD_REG = ILI9341_NGAMMA;
102
  LCD_RAM = 0x00;
103
  LCD_RAM = 0x0E;
104
  LCD_RAM = 0x14;
105
  LCD_RAM = 0x03;
106
  LCD_RAM = 0x11;
107
  LCD_RAM = 0x07;
108
  LCD_RAM = 0x31;
109
  LCD_RAM = 0xC1;
110
  LCD_RAM = 0x48;
111
  LCD_RAM = 0x08;
112
  LCD_RAM = 0x0F;
113
  LCD_RAM = 0x0C;
114
  LCD_RAM = 0x31;
115
  LCD_RAM = 0x36;
116
  LCD_RAM = 0x0F;
117
118
  LCD_REG = ILI9341_SLEEP_OUT;
119
  HAL_Delay(100);
120
121
  LCD_REG = ILI9341_DISPLAY_ON;
122
  LCD_RAM = ILI9341_GRAM;
123
124
125
}

von Arduinoquäler (Gast)


Lesenswert?

Wenn du Pixels auf das Display bringst dann ist die Initialisierung
schon mal nicht sooo schlecht.

Konzentriere dich darauf dass du bei jeder Operation wo du
Pixel malen willst, immer die Beriche/Grenzen setzen musst.

Also damit
1
  LCD_REG = ILI9341_COLUMN_ADDR;
2
  LCD_RAM = 0x00;
3
  LCD_RAM = 0x00;
4
  LCD_RAM = 0x00;
5
  LCD_RAM = 0xEF;
6
7
  LCD_REG = ILI9341_PAGE_ADDR;
8
  LCD_RAM = 0x00;
9
  LCD_RAM = 0x00;
10
  LCD_RAM = 0x01;
11
  LCD_RAM = 0x3F;

Dann ist die Abfolge des Setzens mehrerer Pixel davon abhängig
wie die Orientungsbits gesetzt sind. Das zuständige Register
dass du dabei selbst in der Hand haben musst ist

ILI9341_MADCTL      0x36

Ich habe die Erfahrung gemacht dass dieses Register bzw seine
Bit-Definitionen bei jedem Hersteller bzw Display-Typ anders
zu interpretieren ist bzw seine Richtungen unterschiedlich sind.

Nachdem ich keine Treiber öffentlich gefunden habe die die
Display-Orientierung für alle vier Möglichkeiten korrekt
behandeln blieb mir auch nur der steinige Weg dies selbst
durch trial-and-error herauszufinden da die Angaben im Manual
nicht sehr klar sind.

Durch ungeeignetes Setzen der Orientierungs-Bits bekommt man
oft seltsame Effekte die deiner Darstellung ähneln. Oft kommt
es bei mehrfachen Schreiben dann zu Über-/Unterläufen bei den
Parametern (die ja automatisch inkrementiert werden) von
ILI9341_COLUMN_ADDR und/oder ILI9341_PAGE_ADDR.

Dass man die Parameter-Liste der Kommandos immer 8-bittig
schreibt hast du ja erfreulicherweise bereits herausgefunden
(was ich dir gestern nicht so deutlich mitgeteilt habe).

von grundschüler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> ILI9341_MADCTL      0x36

danke für den Hinweis. Habe das manual jetzt ausgedruckt. 9.3 /S.201 
enthält eine Übersicht über die Einstellung von MV/MX/MY - MADCTl.

von Arduinoquäler (Gast)


Lesenswert?

Also gut, hier noch eine Funktion zum "Herausfinden" der
Zeichenrichtung.
1
/* FUNCTION ************************************/
2
void Drawbar_Test (uint16_t colour)
3
/*
4
 * SPECIFICATION: Eine Linie ziehen
5
 *                zum Erkennen der Update-Richtung
6
 * PARAMETERS:
7
 * SIDE_EFFECTS:
8
 * RETURN VALUES:
9
 ***********************************************/
10
{
11
  uint16_t  ii, fillcount;
12
  uint16_t  x1, x2, y1, y2;
13
14
  x1 =   0;
15
  x2 = 200;
16
  y1 =   3;    // wegen erster Linie sehr am Rand
17
  y2 =   4;    // zwei Linien damit es deutlicher wird
18
19
  fillcount = (x2 - x1) + 1;
20
  fillcount = fillcount * (y2 - y1 + 1);
21
22
  TFT_SetWindow (x1, y1, x2, y2);
23
  TFT_WriteCmd (ILI9341_RAMWR);
24
25
  for (ii=0; ii<fillcount; ii++)
26
  {
27
    LCD_RAM = colour;
28
    delay (paar_Millisekunden); // das Schreiben ohne wäre ja zu schnell
29
    // damit kann man beobachten in welcher Richtung die Pixels
30
    // geschrieben werden und seine Schlussfolgerungen für
31
    // MAD_CTRL ziehen.
32
  }
33
}

von grundschüler (Gast)


Angehängte Dateien:

Lesenswert?

Ich kann jetzt 240x240 px sinnvoll Beschreiben(Bild). Schön wäre esw 
natürlich, wenn die gesamte Bildschirmbreite mit 320 px genutzt werden 
könnte. Wo wird eingestellt, ob nach 240 oder 320px umgebrochen wirde?

von Arduinoquäler (Gast)


Lesenswert?

Gut!

Es wird dann umgebrochen wenn das X-Ende oder Y-Ende deines
aktuell gesetzten Fensters erreicht ist. Abhängig davon wie du
die Schreibrichtung des MAD_CTRL Registers gesetzt hast.

Also entweder wird zuerst von x1 bis x2 geschrieben, dann der
y-Wert inkrementiert, oder es wird von y1 bis y2 geschrieben und
dann x inkrementiert.

Das Inkrementieren kann aber auch Dekrementieren sein.

Schreibe dir doch erst mal die Fillscreen-Funktion die dir
einen ganzen schwarzen bzw einfarbigen Screen liefert.

von Arduinoquäler (Gast)


Lesenswert?

grundschüler schrieb:
> Wo wird eingestellt, ob nach 240 oder 320px umgebrochen wirde?

Wenn du so fragst habe ich den Eindruck dass du noch nicht
verstanden hast was ich dir schon vorher beschrieben habe:

Arduinoquäler schrieb:
> Konzentriere dich darauf dass du bei jeder Operation wo du
> Pixel malen willst, immer die Beriche/Grenzen setzen musst.
>
> Also damit
>   LCD_REG = ILI9341_COLUMN_ADDR;
>   LCD_RAM = 0x00;  // start
>   LCD_RAM = 0x00;
>   LCD_RAM = 0x00;  // ende
>   LCD_RAM = 0xEF;
>
>   LCD_REG = ILI9341_PAGE_ADDR;
>   LCD_RAM = 0x00;  // start
>   LCD_RAM = 0x00;
>   LCD_RAM = 0x01;  // ende
>   LCD_RAM = 0x3F;

von grundschüler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Wenn du so fragst habe ich den Eindruck dass du noch nicht
> verstanden hast was ich dir schon vorher beschrieben habe:

Ich habe das schon verstanden und auch ausprobiert. Nur war das 
Ergebnis, dass bei 0,0,240,320 gar nichts angezeigt wurde und bei 
0,0,10,20 ein unbeschriebener weißer Rand von 10 bzw. 20 blieb -auf dem 
Foto gut sichtbar.

Vielleicht habe ich es dann doch nicht richtig verstanden - jedenfalls 
der Bereich zwischen Start- und Endwert wird nicht beschrieben, erst der 
Bereich nach dem Endwert...

Warum?

von Arduinoquäler (Gast)


Lesenswert?

Poste doch mal deine Setwindow Funktion.

Vermutlich verwechselst du irgedwas in Richtung:

xxxfunction (x1, y1, x2, y2)

und

xxxfunction (x1, x2, y1, y2)

Erkennst du den Unterschied?

von grundschüler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Poste doch mal deine Setwindow Funktion.

mach ich nach feierabend. Meine aber genau mein Problem ab Seite 127 des 
manuals gefunden zu haben. Probiere es heute abend aus.

von grundschüler (Gast)


Lesenswert?

hier der Code:
1
void lcd_clear(uint16_t Color){
2
  uint32_t index;
3
    LCD_REG = 0x002A;  // column address set
4
    LCD_RAM = 0;       // x Startwert 16 Bit
5
    LCD_RAM = 10;       // x Endwert 16 Bit
6
    LCD_REG = 0x002B;  // row address set
7
    LCD_RAM = 0;       // y Startwert 16 Bit
8
    LCD_RAM = 10;       // y Endwert 16 Bit
9
  LcdWriteReg(0x002c);
10
  for( index = 0; index < (MAX_X) * MAX_Y; index++ )
11
  {
12
    LcdWriteData(Color);
13
    //delay_ms(1);
14
  }
15
}

Damit bekomme ich den auf den Fotos ersichtlichen weißen Rand zwischen 
Start- und Endwert. Der Cursor wird auf den Endwert gesetzt und ab da 
dann die angegebene Anzahl pixel gesetzt. Umgebrochen wird nicht.

Allerdings wird jetzt der gesamte Bildschirm beschrieben. Fehler lag an 
MV.

Ich versuche mich jetzt mal an einem fonts.






Ich bekomme

von Arduinoquäler (Gast)


Lesenswert?

grundschüler schrieb:
> hier der Code:

Der ist nicht korrekt.

column address set und row address set verlangen
nach 4 (in Worten: vier) Parameter à 8 Bit.

Du kannst Kommando-Parameter nicht 16 Bit breit schreiben.
Das Datenblatt schreibt dir das vor. Schau es dir nochmals an!

Arduinoquäler schrieb:
> Dass man die Parameter-Liste der Kommandos immer 8-bittig
> schreibt hast du ja erfreulicherweise bereits herausgefunden

Aber offensichtlich nicht konsequent weitergeführt.

von Arduinoquäler (Gast)


Lesenswert?

grundschüler schrieb:
> LcdWriteData(Color);

Warum schreibst du an dieser Stelle nicht

LCD_RAM = Color;


grundschüler schrieb:
> LcdWriteReg(0x002c);

Warum schreibst du an dieser Stelle nicht

LCD_REG = 0x002c;

Es ist doch erbärmlich umständlich für einen einfachen
Write-Vorgang extra eine Funktion aufzurufen.

von grundschüler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> nach 4 (in Worten: vier) Parameter à 8 Bit.

du hast recht. Deswegen klappt der ganze code nicht richtig, danke, 
hätte ich selbst nicht gefunden.

Arduinoquäler schrieb:
> Es ist doch erbärmlich umständlich für einen einfachen
> Write-Vorgang extra eine Funktion aufzurufen.

Das ist überbleibsel von dem Versuch, meinen eigenen Standard-code 
abzuändern. Wird geändert.

von grundschüler (Gast)


Lesenswert?

Display geht. Nächstes Problem RTC:
1
HAL_RTC_GetTime(&hrtc, &sTime, FORMAT_BIN);
2
lcd_goto(1,1);
3
lcd_int2(sTime.Hours);
4
lcd_write(":");
5
lcd_int2(sTime.Minutes);
6
lcd_write(":");
7
lcd_int2(sTime.Seconds);

Die RTC läuft. Nach dem rst ändert sich die Zeit. Allerdings im 
laufenden Programm wird die Zeit mit "HAL_RTC_GetTime" nicht 
aktualisiert. Was mach ich falsch?

von grundschüler (Gast)


Lesenswert?

grundschüler schrieb:
> Was mach ich falsch?

mit
  HAL_RTC_GetTime(&hrtc, &sTime, FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &sDate, FORMAT_BIN);
läuft es...

von Harry L. (mysth)


Lesenswert?

hast du dir HAL_RTC_GetTime mal genauer angesehen?
Kann man doch wunderbar im Debugger durchgehen.
Ich glaube nicht, daß der doppelte Aufruf der Weisheit letzter Schluß 
ist.

von grundschüler (Gast)


Lesenswert?

Harry L. schrieb:
> der Weisheit letzter Schluss

Das sehe ich genauso. Aber:
 * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to 
unlock the values
  *        in the higher-order calendar shadow registers to ensure 
consistency between the time and date values.
  *        Reading RTC current time locks the values in calendar shadow 
registers until current date is read.

Eine endlose hal-Funktion für einen einfachen Registeraufruf. Ich 
benutze diese nur zum Abgleich und ansonsten einen systick-timer. Hal 
ist gut für ein lauffähiges Grundgerüst.

von grundschüler (Gast)


Lesenswert?

habe jetzt ein ir-Einstellmenu für die rtc.
1
void set_smh(void){
2
  sTime.Seconds=sec;
3
  sTime.Minutes =min;
4
  sTime.Hours =hou;
5
  sDate.Date= DAY;
6
  sDate.Month =MON;
7
  sDate.Year= YEA;
8
  sDate.WeekDay= WDY;
9
10
  HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BIN);
11
  HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BIN);
12
}
Problem: die rtc läuft nicht auf Batterie weiter. Hat jemand die 
richtige Einstellung parat?

von grundschüler (Gast)


Lesenswert?

Hänge immer noch an der rtc bzw. die rtc hängt immer noch.

Es gibt doch sicher Jemanden, der beim black-board die rtc korrekt zum 
laufen gebracht hat. Muss man etwa etwas umlöten, damit die rtc nach 
Power_down über Batterie weiterläuft???

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
Noch kein Account? Hier anmelden.