Ich ärger mich nun schon die ganze Nacht durch an einem STM32 rum - um
die I2C unter der ST HAL zum laufen zu bekommen, das klappt nun
mittlerweile auch tadellos.
Aaaaalerdings habe ich da nun ein kleines Programmierproblem mit einem
Zeiger auf ein Array:
1
constuint8_tssd1306_font6x8[]={
2
0x00,0x00,0x00,0x00,0x00,0x00,// sp
3
0x00,0x00,0x00,0x2f,0x00,0x00,// !
4
0x00,0x00,0x07,0x00,0x07,0x00,// "
5
//..... Eingekürzt
6
0x00,0x00,0x41,0x77,0x08,0x00,// }
7
0x00,0x08,0x04,0x08,0x08,0x04,// ~
8
};
Und zwar gebe ich die Font über meine PUTS an den I2C raus... in der
Reihenfolge:
1
//von hier: (Font ist 8x6px - das Disp schiebt Zeilenweise)
Quasi von const char nacht *atxBuffer zu *pData.... und wenn ich bei der
PUTC nicht mit dem & Zeiger arbeite kommt dies nicht an. Hab ich
allerdings in der PUTC:
1
WriteLongBuffer(0x40,&ssd1306_font6x8[ch*6],6);
funktioniert es zwar Augenscheinlich, aber mein Compiler wirft mir eine
Warnung an den Kopf:
1
passing argument 2 of 'WriteLongBuffer' makes pointer from integer without a cast
2
3
und:
4
5
expected 'uint8_t * {aka unsigned char *}' but argument is of type 'const uint8_t * {aka const unsigned char *}'
Er kompiliert es zwar und es funktioniert, aber irgendwo muss doch da
der Wurm drinn sein.
Wo wir gerade dabei sind: Gibt es bei dem STM32 auch eine Möglichkeit
soetwas ins Flash zu legen (PROGMEM) wie bei den AVR? PROGMEM geht
leider nicht.
DraconiX schrieb:> Wo wir gerade dabei sind: Gibt es bei dem STM32 auch eine Möglichkeit> soetwas ins Flash zu legen (PROGMEM) wie bei den AVR? PROGMEM geht> leider nicht.
Was denkst du denn, wo es aktuell liegt???
Die zweite Meldung sagt es schon: WriteLongBuffer erwartet ein uint8_t*,
Du übergibst aber ein const uint8_t*, d.h. aTxBuffer kann in
WriteLongBuffer verändert werden, was Du übergibst kann es aber nicht!
Darauf weist Dich der Compiler hin.
Daher mußt Du entweder die Parameter const machen, oder per cast das
const entfernen, was man aber nur machen sollte, wenn man garantieren
kann, das die Parameter nicht verändert werden können.
Zu Deinem Flash Problem: globale const Variablen sollten hier
automatisch im Flash angelegt werden. Schaue mal in Dein Map File nach.
PROGMEM ist hier daher nicht notwendig.
Darum auch mit dem const-wegcasten vorsichtig. Ändert Deine Funktion
doch die Parameter und diese liegen im Flash...
DraconiX schrieb:> Und zwar gebe ich die Font über meine PUTS an den I2C raus... in der> Reihenfolge:> //von hier: (Font ist 8x6px - das Disp schiebt Zeilenweise)>> void ssd1306_putc(char c){> uint8_t ch = c - 32;> WriteLongBuffer(0x40,ssd1306_font6x8[ch * 6],6);> }>> //über da:>
warum und wie das (angeblich) funktionieren soll, entzieht sich meiner
Kenntnis. Ich jedenfalls würde da als Compiler nix Vernünftiges draus
machen.
Du übergibst das auszugebende Zeichen c und rechnest dann den Index (ch)
in das Pixelarray aus. WriteLongBuffer() will offensichtlich eine
Adresse sehen, Du übergibst aber den Wert, der dort steht. Das muß
1
WriteLongBuffer(0x40,&ssd1306_font6x8[ch*6],...
heißen. Dann meckert auch der Compiler nicht mehr. Mit const oder nicht
const hat das nix zu tun.
Andreas E. schrieb:> Die zweite Meldung sagt es schon: WriteLongBuffer erwartet ein> uint8_t*,> Du übergibst aber ein const uint8_t*, d.h. aTxBuffer kann in> WriteLongBuffer verändert werden, was Du übergibst kann es aber nicht!> Darauf weist Dich der Compiler hin.> Daher mußt Du entweder die Parameter const machen, oder per cast das> const entfernen, was man aber nur machen sollte, wenn man garantieren> kann, das die Parameter nicht verändert werden können.> Zu Deinem Flash Problem: globale const Variablen sollten hier> automatisch im Flash angelegt werden. Schaue mal in Dein Map File nach.> PROGMEM ist hier daher nicht notwendig.> Darum auch mit dem const-wegcasten vorsichtig. Ändert Deine Funktion> doch die Parameter und diese liegen im Flash...
Dankeschön :-D Das wars! WriteLongBuffer übernimmt nun den const.
Markus F. schrieb:> warum und wie das (angeblich) funktionieren soll, entzieht sich meiner> Kenntnis. Ich jedenfalls würde da als Compiler nix Vernünftiges draus> machen.> Du übergibst das auszugebende Zeichen c und rechnest dann den Index (ch)> in das Pixelarray aus. WriteLongBuffer() will offensichtlich eine> Adresse sehen, Du übergibst aber den Wert, der dort steht. Das muß> WriteLongBuffer(0x40, &ssd1306_font6x8[ch * 6], ...> heißen. Dann meckert auch der Compiler nicht mehr. Mit const oder nicht> const hat das nix zu tun.
Hatte ich ja beide Versionen, mit Zeiger auf die Position und ohne - Mit
Zeiger hat er ebenfalls mit Warnung compiliert, aber auf die Falsche
Position gezeigt, nämlich auf die Adressen welche im Array standen,
logisch.
Es handelt sich ja auch nur um das eine Array was ich "zerpflückt"
übergeben muss, bei den anderen übergebe ich ja eh nur den Arrayzeiger.
DraconiX schrieb:> Hatte ich ja beide Versionen, mit Zeiger auf die Position und ohne - Mit> Zeiger hat er ebenfalls mit Warnung compiliert, aber auf die Falsche> Position gezeigt, nämlich auf die Adressen welche im Array standen,> logisch.
wenn in deinem Array Adressen stehen, warum deklarierst Du das dann als
char Array?
Markus F. schrieb:> DraconiX schrieb:>> Hatte ich ja beide Versionen, mit Zeiger auf die Position und ohne - Mit>> Zeiger hat er ebenfalls mit Warnung compiliert, aber auf die Falsche>> Position gezeigt, nämlich auf die Adressen welche im Array standen,>> logisch.>> wenn in deinem Array Adressen stehen, warum deklarierst Du das dann als> char Array?
Nein... Der Pointer hat den Inhalt des Arrays als Adresse übernommen,
das war so nicht gewollt. Quasi nicht die Adresse, sondern den Inhalt
als Adresse... weißt du was ich meine?!
DraconiX schrieb:> weißt du was ich meine?!
Um ehrlich zu sein ..., nein.
Und ich fürchte, nicht ich bin derjenige, der hier ein wenig verwirrt
ist ;).
DraconiX schrieb:> Der Pointer hat den Inhalt des Arrays als Adresse übernommen, das war so> nicht gewollt.
Das ist in Deinem ersten Beispiel der Fall:
1
WriteLongBuffer(0x40,ssd1306_font6x8[ch*6],6);
Da übergibst Du genau ein Byte aus Deinem Array, und das wird von
WriteLongBuffer als Adresse interpretiert.
Wenn Du aber
1
WriteLongBuffer(0x40,&ssd1306_font6x8[ch*6],6);
verwendest, wird eine Adresse eines Elements auf Dein Array berechnet
und Deiner Funktion übergeben, was vollkommen korrekt ist.
In der übrigens
wandert die Warnung an eine andere Stelle.
Und die kannst Du genauso anpassen; Deine Funktion HAL_I2C_SSD_Transmit
verändert schließlich die übergebenen Daten nicht, also kann sie auch so
geändert werden:
@ DraconiX oder auch jemand mit Idee,
mich würde interessieren wie die Funktion
HAL_I2C_SSD_Transmit
ausssieht. Speziell geht es um das Kombinieren des Command mit dem
aTxBuffer.
Man könnte einfach den Buffer ab Index 1 beschreiben und nachher Command
auf Index 0 schreiben und der HAL_I2C_Master_Transmit übergeben.
Da ich auch lesen möchte, würden dann die Daten ab Index 0 beginnen und
für Command ist dann kein Platz mehr.
Jetzt könnte ich eine Tx und einen Rx Puffer anlegen, die Daten
umkopieren oder einen neuen Typ anlegen, aber welche ist die einfachste
Lösung die wenig Zeit und wenig Speicher braucht um nur einen Puffer zu
verwenden?
Kann sein das ich mich verlaufen habe und die simple Lösung nicht sehe.
Jemand eine Idee?