Forum: Mikrocontroller und Digitale Elektronik EA EDIPTFT32 und ATXMEGA: ASCII-Datentyp macht Probleme


von ruud86 (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei ein ediptft32 mit einem XMEGA256A3 über SPI 
kommunizieren zu lassen.
Um die Befehle zu Implementieren habe ich mir den Beispielcode von EA 
für das SmallProtocoll zu eigen gemacht.
(siehe 
http://www.lcd-module.de/fileadmin/downloads/development%20service/eDIP240/SmallProtocoll_R8_RS232.zip)

Da sind dann im Modul Display die ganzen Befehle schon vordefiniert, 
feine Sache eigentlich.

Nun mein Problem:

Die Befehle, z.B.
1
#define eDIP_TA() eDIP_command("TA")
übergeben ein Array von ASCII-Zeichen, deren Datentyp wohl char ist.

Letzendlich werden die Parameter an die se Funktion übergeben:
1
bool eDIP_command6(uint8_t * data, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4, uint8_t data5, uint8_t data6, uint8_t parameter)
2
{
3
...
4
  return ...
5
}

Diese Funktion erwartet unsigned char Parameter und beim compilieren 
bekomme ich dann jeweils folgende 2 Warnungen:
1
Warning  1  pointer targets in passing argument 1 of 'eDIP_command6' differ in signedness [-Wpointer-sign]
2
3
Warning  2  expected 'uint8_t *' but argument is of type 'char *'

Ich möchte das alles nicht eingfach mit Typecasts glatt bügeln, da 
dadürch wahrscheinlich nur neue Probleme entstehen. Also darum die 
Frage, wie ich das elegant lösen könnte?
Kann ich irgendwie ASCII-Zeichen global als unsigned char definieren?

Gruß Adrian

von Peter D. (peda)


Lesenswert?

Eine Funktion mit 8 Parametern ist extrem unüblich.
Man legt eine struct an und übergibt den Pointer auf die struct.

von ruud86 (Gast)


Lesenswert?

Das ist dem Aufbau des Display Treibers geschuldet:
1
#define eDIP_command(ins)          eDIP_command6(ins,0,0,0,0,0,0,0)
2
#define eDIP_command1(ins,n1)        eDIP_command6(ins,n1,0,0,0,0,0,1)
3
#define eDIP_command2(ins,n1,n2)      eDIP_command6(ins,n1,n2,0,0,0,0,2)
4
#define eDIP_command3(ins,n1,n2,n3)      eDIP_command6(ins,n1,n2,n3,0,0,0,3)
5
#define eDIP_command4(ins,n1,n2,n3,n4)    eDIP_command6(ins,n1,n2,n3,n4,0,0,4)
6
#define eDIP_command5(ins,n1,n2,n3,n4,n5)  eDIP_command6(ins,n1,n2,n3,n4,n5,0,5)
1
bool eDIP_command6(uint8_t * data, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4, uint8_t data5, uint8_t data6, uint8_t parameter)
2
{
3
  uint8_t buf[9]={0};
4
5
  buf[0]=ESC;
6
  buf[1]=*data++;
7
  buf[2]=*data;
8
  buf[3]=data1;
9
  buf[4]=data2;
10
  buf[5]=data3;
11
  buf[6]=data4;
12
  buf[7]=data5;
13
  buf[8]=data6;
14
  
15
  return send_Command(buf, parameter+3);  //3 is aggredated, because 3 bytes added additionally
16
}

es werden also auch nicht immer alle Parameter genutzt. Aber das ist ja 
eher eine Stil-Frage oder? Das Problem mit den Warnungen würde es auch 
nicht lösen oder ?

von Karl H. (kbuchegg)


Lesenswert?

ruud86 schrieb:


> Ich möchte das alles nicht eingfach mit Typecasts glatt bügeln,

An dieser Stelle ist das ok.

deine eDIP_command Funktion übernimmt offenbar das Kommando als String. 
Die darunterliegende Funktion eDIP_command6 arbeitet aber auf Bytes. 
D.h. an irgendeiner Stelle geschieht ein Übergang in der 
Betrachtungsweise des Speicherinhaltes. An genau dort (ich schätze mal 
in der Funktion eDIP_command) muss dann der Pointer umgecastet werden.

> da
> dadürch wahrscheinlich nur neue Probleme entstehen.

Nö. Da gibt es keine Probleme. Alles was du tust, ist das 
'Spezialwissen' "String" über Bord zu werfen und auf den primtiveren 
Datentyp "Byte" überzugehen.

> Also darum die
> Frage, wie ich das elegant lösen könnte?
> Kann ich irgendwie ASCII-Zeichen global als unsigned char definieren?

Das willst du eigentlich nicht tun. Denn das ist noch schlimmer als ein 
einmaliger Cast eines Pointers in einer Funktion, von dem wir wissen, 
dass er nur logische Konsequenzen hat, aber an den Bitmustern nichts 
ändert.

von Karl H. (kbuchegg)


Lesenswert?

Wenn das erste Argument in die Funktion
1
bool eDIP_command6(uint8_t * data, ...

sowieso IMMER ein Kommando-String ist, warum machst du dann nicht von 
vorne herein daraus einen char* ?
Einen const char*, um genau zu sein?
1
bool eDIP_command6(const char* data, ....

in der Funktion castest du den Character nach der Dereferenzierung auf 
einen uint8_t und hast damit die Stelle, an der der Übergang von Text 
auf Bytes erfolgt an einer Position zusammengefasst.

von Gobi (Gast)


Lesenswert?

Hat man keine Probleme, macht man sie sich- in C. Was ist das alles nur 
für ein überflüssiger Krampf mit der ganzen Herumcasterei und 
-referenziererei.  Leute, nehmt Assembler: Da wird niedergeschrieben was 
nötig und wirklich Sache ist. Aber warum einfach wenns auch kompliziert 
geht... Kopfschüttel

von Karl H. (kbuchegg)


Lesenswert?

Gobi schrieb:
> Hat man keine Probleme, macht man sie sich- in C. Was ist das alles nur
> für ein überflüssiger Krampf mit der ganzen Herumcasterei und
> -referenziererei.  Leute, nehmt Assembler: Da wird niedergeschrieben was
> nötig und wirklich Sache ist. Aber warum einfach wenns auch kompliziert
> geht... Kopfschüttel


Wenn alles was man hat Bytes sind und man die nach belieben 
verwurschteln kann, wie man lustig, ist ... ja, dann ist die Welt 
einfach. Ist ja auch viel einfacher einfach überall mit dem Hammer 
draufzuhauen, weil das das einzige Werkzeug ist, das man kennt.

In C, wie in den meisten Hochsprachen, gibt es nun mal Datentypen. Und 
das aus gutem Grund. Eben weil sich die Sichtweise "Alles ist ein Byte 
und wie ich das verwurschtle entscheide ich als Programmierer" nun mal 
nicht bewährt hat.
Und mit diesen Datentypen kommen Regeln ins System. Spielt man nach 
diesen Regeln, dann helfen einem die Datentypen, viele Fehler zu 
vermeiden bzw. durch den Compiler einer Überprüfung zuzuführen. Der 
Preis dafür ist akzeptabel - man muss sich nur an die Spielregeln 
halten.

von Peter D. (peda)


Lesenswert?

Hier mal ein Beispiel, wie ich das mache:
1
#define TFT_FKT(x)         tft_wr( sizeof(x) - 1, x, 1 )
2
3
uint8_t tft_wr( uint8_t len, uint8_t *dat, uint8_t flash );
4
          // write to GLCD from SRAM (0) or Flash (1)
5
6
prog_uint8_t INIT[] =   "\x1bTC\0"    // text cursor off
7
                        "\x1b""DO\2"    // rotate 180ø
8
                        "\x1b""FD\x8\x1"  // display color
9
                        "\x1b""FZ\x8\x1"  // text color
10
                        "\x1b""DL"    // display clear
11
                        "\x1b""YZ\x0"    // no delay
12
                        "\x1b""YH\x64"    // light on
13
                        ;
14
15
void tft_init( void )
16
{
17
  TFT_FKT( INIT );
18
}

von ruud86 (Gast)


Lesenswert?

Hi,

danke erst mal für die Antworten, hat geholfen, habe an zentraler Stelle 
jetzt einen Typecast eingebaut.

Wenn das ganze erst mal komplett läuft, werde ich mich um 
Optimierungsmöglichkeiten bemühen.

Gobi dein missionarischer Eifer stellt ja fast die Katholiken in den 
Schatten :)

Vielen Dank auf jeden Fall.

Gruß

Adrian

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.