Forum: Mikrocontroller und Digitale Elektronik Probleme bei I2C und Display edip 240


von Sven W. (wache)


Lesenswert?

Hallo zusammen!

Ich sitze nun seit geschlagenenen 9 Stunden an meinem µC und meinem 
Display und bekomme es einfach nicht hin, dass auf meinem Display das 
steht, was da hin soll.
Ich möchte über I2C das Display ansteuern (AVR GCC). Das Display 
löschen, und eine Grade zeichnen funktioniert, zumindest teilweise.
Wenn ich nämlich erst das Display lösche, und dann die Grade zeichnen 
lassen will, dann wird nur das Display gelöscht.
Meine Routine zur Textausgabe funktioniert hingegen nie.
Als nächstes Problem stellt sich mit die Touchscreenabfrage. Da ich die 
Interrupuleitung SBUF nicht habe, muss ich irgendwie pollen. Jegliche 
Versuche, das zu tun sind gescheitert.

Als TWI Lib nutze ich die Lib von P. Fleury.
Der µC ist ein auf 16MHz getakteter AT90CAN128.

Kann mir jemand bei dem Problem behilflich sein?

Hier der Code für die Unterprogramme:


1
void Display_loeschen(void)
2
{
3
 int i = 0;
4
 i2c_start(0x10);
5
 i2c_write(DC1);
6
 i2c_write(0x03);
7
 i2c_write(ESC);
8
 i2c_write('D');
9
 i2c_write('L');
10
 i2c_write(DC1 + 0x03 + ESC + 'D' + 'L');
11
 i2c_start(0x10);
12
 do
13
   {
14
   i = i2c_readAck();
15
   }while (i!= ACK);
16
}
17
18
int text_send(int xpos, int ypos, char * text)
19
{
20
 int len, bcc, i;
21
 i = 0;
22
 len = strlen(text);
23
 bcc = 0;
24
 while (i <= len)
25
 {
26
   bcc+= text[i];
27
   i++;
28
 }
29
 bcc += DC1 + ESC + 'Z' + 'R'+ xpos + ypos + len;
30
 bcc = bcc % 0x100;
31
 i2c_start(0x10);
32
 i2c_write(DC1);
33
 i2c_write(0x06 + strlen(text));
34
 i2c_write(ESC);
35
 i2c_write('Z');
36
 i2c_write('R');
37
 i2c_write(xpos);
38
 i2c_write(ypos);
39
 i = 0;
40
 while (i <=strlen(text))
41
 {
42
    i2c_write(text[i]);
43
  i++;
44
 }
45
 i2c_write(bcc);
46
 i2c_stop();
47
 return (bcc);
48
}
49
50
int Linie_zeichnen(int x1, int y1, int x2, int y2)
51
{
52
 int bcc;
53
 bcc = DC1 + 0x07 + ESC + 'G' + 'D' + x1 + y1 + x2 + y2;
54
 bcc = bcc % 0x100;
55
 
56
 i2c_start_wait(0x10);
57
 i2c_write(DC1);
58
 i2c_write(0x07);
59
 i2c_write(ESC);
60
 i2c_write('G');
61
 i2c_write('D');
62
 i2c_write(x1);
63
 i2c_write(y1);
64
 i2c_write(x2);
65
 i2c_write(y2);
66
 i2c_write(bcc);
67
 i2c_stop();
68
 return (bcc);
69
}

von Sven W. (wache)


Lesenswert?

So, die Textroutine funktioniert nun ebenfalls mehr oder weniger.

Wenn ich im Debug-Modus ganz langsam durchgehe, dann klappen mehrere 
Sachen auch hintereinander. Ich habe das Gefühl, dass der Empfangsbuffer 
des Displays nicht hinterher kommt.

Kann mich da irgendjemand etwas aufschlauen?
Scheint ja ein I2C "Problem" zu sein...

Hier die Routine zum Text senden:
1
int text_send(int xpos, int ypos, char * text)
2
{
3
 int bcc, i;
4
 i = 0;
5
 bcc += DC1 + ESC + 'Z' + 'R'+ xpos + ypos + 0x06 + strlen(text);
6
 for (i = 0; i <= strlen(text); i++)
7
   bcc += text[i];
8
 bcc = bcc % 0x100;
9
 i2c_start(0x10);
10
 i2c_write(DC1);
11
 i2c_write(0x06 + strlen(text));
12
 i2c_write(ESC);
13
 i2c_write('Z');
14
 i2c_write('R');
15
 i2c_write(xpos);
16
 i2c_write(ypos);
17
 for (i = 0; i <= strlen(text); i++)
18
   i2c_write(text[i]);
19
 i2c_write(bcc);
20
 i2c_stop();
21
 return (0);
22
}


Gruß,

Sven

von Sven W. (wache)


Lesenswert?

Hier nocheinmal der Vollständigkeit halber der Aufruf aus dem 
Hauptprogramm:
1
int main(void)
2
{ 
3
Adress_Datenbus_initialisieren();
4
// SPI initialisieren
5
  SPCR=0x5c;  
6
  SPSR=0x00;
7
// SPI Init fertig
8
sprintf(Text, "Beispieltext");
9
Zaehler_initialisieren();
10
at90can_init(BITRATE_500_KBPS);
11
sja1000_init(BITRATE_500_KBPS);
12
SPI_MasterInit();
13
i2c_init();
14
Display_loeschen();  
15
_delay_ms(2100);
16
text_send(10, 20, Text);

und hier die aktuelle Programmversion:
1
void Display_loeschen(void)
2
{
3
 int i = 0;
4
 i2c_start(0x10);
5
 i2c_write(DC1);
6
 i2c_write(0x03);
7
 i2c_write(ESC);
8
 i2c_write('D');
9
 i2c_write('L');
10
 i2c_write(DC1 + 0x03 + ESC + 'D' + 'L');
11
 i2c_stop();
12
}
13
14
int text_send(int xpos, int ypos, char * text)
15
{
16
 int bcc,i;
17
 bcc = DC1 + ESC + 'Z' + 'R' + xpos + ypos + 0x06 + strlen(text);
18
 for (i=0; i<=strlen(text); i++)
19
   bcc += text[i];
20
 bcc = bcc % 0x100;
21
 i2c_start(0x10);
22
 i2c_write(DC1);
23
 i2c_write(0x06 + strlen(text));
24
 i2c_write(ESC);
25
 i2c_write('Z');
26
 i2c_write('R');
27
 i2c_write(xpos);
28
 i2c_write(ypos);
29
30
31
 for (i=0; i<=strlen(text); i++)
32
   i2c_write(text[i]);
33
 i2c_write(bcc);
34
 i2c_stop();
35
 return (0);
36
}

von Stefan H. (abudun)


Lesenswert?

Weiß nicht ob du schon selbst drauf gekommen bist, aber meiner Meinung 
nach müsste an diversen Stellen da "Abholen" des ACK des Display fehlen!
Deswegen geht es manchmal und manchmal nicht

Grüsse

von Stefan H. (abudun)


Lesenswert?

Hier noch als Nachtrag eine Funktionierende Routine zum Lesen der 
Version des Diplays. Zu beachten ist das Lesen des ACK das bei Erfolg 
0x06 und bei Misserfolg 0x15 ist (wenn ACK = 0x15 wird das paket 
verworfen)
Die SlaveAddr ist übrings immer 0xDE / 0xDF wenn man sowohl BA[2:0] also 
auch SA[2:0] offen lässt (interne Pull-Up Widerstände auf dem Display)

Der Code ist im übrigen nur für einen schnellen 5min Test des Displays 
geschrieben, es werden also weder ACK noch irgendwelche anderen Daten 
überprüft ;-)

void getVersion_RapidTesting(U8 data)
{
   U16 bcc;

   bcc = 0x11 + 0x03 + 0x1B + 'T' + 'V';

   i2c_start(0xDE); // START with Addr
   i2c_write(0x11); // <DC1>
   i2c_write(0x03); // len
   i2c_write(0x1B); // ESC
   i2c_write('T');  // cmd Zeichenkette ausgeben
   i2c_write('V');  // cmd Versions-Nr. ausgeben
   i2c_write((U8)bcc); // Cecksum
   // Get ACK of Disp
   i2c_rep_start(0xDF);
   data = i2c_readNak();
   i2c_stop();
   // hier könnte ACK des Display ausgewertet werden
}

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.