Forum: Mikrocontroller und Digitale Elektronik U8glib HW-SPI LCD 128x64 ST7920 verpixelt


von D. M. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

da bei meinem Atmega328p die sw_spi der u8glib Variante viel zu langsam 
ist (1-2 Updates pro Sek.) habe ich die hw_spi Version ausprobiert.

Es handelt sich um folgendes LCD:
http://www.ebay.de/itm/12864-128x64-LCD-SPI-serial-Graphic-Display-Module-For-Arduino-r3-Raspberry-Pi-y-/201159581980?hash=item2ed60ba11c:g:xioAAOSwnDZUAMd7

Diese ist deutlich schneller, nur leider ist bei mir das obere Viertel 
voll verpixelt. Der Rest des Displays funktioniert ohne Probleme (siehe 
Bild).

Hier der Code:
1
#include "u8g.h"
2
#include <avr/interrupt.h>
3
#include <avr/io.h>
4
5
u8g_t u8g;
6
uint16_t adc_value = 0;
7
8
// ADC initialisieren
9
void ADC_init (void)
10
{
11
  // AREF = AVcc
12
  ADMUX = (1<<REFS0);
13
  
14
  // ADC Enable and prescaler of 128
15
  // 16000000/128 = 125000
16
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
17
}
18
19
// ADC 16-Bit Einzelmessung
20
uint16_t ADC_Read(uint8_t ch)
21
{
22
  // select the corresponding channel 0~7
23
  // ANDing with ’7' will always keep the value
24
  // of ‘ch’ between 0 and 7
25
  ch &= 0b00000111;  // AND operation with 7
26
  ADMUX = (ADMUX & 0xF8)|ch; // clears the bottom 3 bits before ORing
27
  
28
  // start single convertion
29
  // write ’1' to ADSC
30
  ADCSRA |= (1<<ADSC);
31
  
32
  // wait for conversion to complete
33
  // ADSC becomes ’0' again
34
  // till then, run loop continuously
35
  while(ADCSRA & (1<<ADSC));
36
  
37
  return (ADC);
38
}
39
40
void LCD_init(void)
41
{
42
  //SW SPI Init:
43
  //u8g_InitSPI(&u8g, &u8g_dev_st7920_128x64_4x_sw_spi, PN(3, 3), PN(1, 1), PN(1, 0), U8G_PIN_NONE, U8G_PIN_NONE); //SCK, MOSI, CS 
44
  
45
  //HW SPI Init:
46
  u8g_InitSPI(&u8g, &u8g_dev_st7920_128x64_4x_hw_spi, PN(1, 5), PN(1, 3), PN(3, 5), U8G_PIN_NONE, U8G_PIN_NONE); //SCK, MOSI, CS 
47
}
48
49
void draw(void)
50
{
51
  u8g_SetFont(&u8g, u8g_font_helvB12);
52
  u8g_SetFontPosTop(&u8g);
53
  u8g_DrawStr(&u8g, 10, 0, "ADC-Wert");
54
  u8g_DrawStr(&u8g, 40, 25, u8g_u16toa(adc_value,4));
55
  u8g_DrawStr(&u8g, 45, 45, "Test");
56
}
57
58
59
int main(void)
60
{
61
  ADC_init();
62
  LCD_init();
63
64
  while(1)
65
  {
66
    adc_value = ADC_Read(0);
67
    u8g_FirstPage(&u8g);
68
    do
69
    {
70
      draw();
71
    } while ( u8g_NextPage(&u8g) );
72
  }
73
}

Hat jemand ne Ahnung warum das so ist?
Außerdem die Frage, wieso die sw_spi Lösung soooo viel langsamer ist? 
Der einzige Unterschied im Code ist in der LCD_init zu sehen.


Vielen Dank im Voraus für eure Hilfe.

Gruß electricar

Edit:
Übrigens wird der obere Teil mit der SW-SPI ganz normal dargestellt!

von D. M. (Gast)


Lesenswert?

Irgendjemand ne Ahnung?

von hp-freund (Gast)


Lesenswert?

Vielleicht kommen deine Daten einfach zu schnell.
Halbiere z.B. die Taktfrequenz und beobachte...

von Philipp K. (philipp_k59)


Lesenswert?

Naja das HW SPI läuft mit seiner Maxgeschwindigkeit von alleine, das SW 
SPI kostet somit Rechenzeit.. wieviel nun wirklich habe ich auch keinen 
Plan.

Ich benutze auch das HW SPI via U8g an Arduino und habe das Problem 
nicht.

von hp-freund (Gast)


Lesenswert?

Ach ja,

SPI + schnell = Leitungslänge beachten.

von Julian B. (julinho)


Lesenswert?

Passt die Spannung vom Controller zur Spannung vom Display?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

D. M. schrieb:
> Hat jemand ne Ahnung warum das so ist?

 Zwischen uC und Display (CLOCK Leitung) einen Widerstand  56-120 Ohm.

 CLOCK ist empfindlich bei hohen Frequenzen, DATA dagegen ist
 weitgehend unkritisch.

von D. M. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

vielen Dank für eure Antworten.
Leitungslänge ist ca. 15cm. Kürzer kann ich aktuell nicht testen, denke 
aber nicht, dass das ein Problem ist. Kenne viele PCBs auf denen der SPI 
Bus über das komplette Board mit einer längeren Leitung geht.

Mit dem Serienwiderstand hat sich leider nichts geändert.

Hab mal paar Bilder aufgenommen. Meiner Meinung nach sieht das ganz ok 
aus. Was sagt ihr? Masse ist über ein kleines Kabel angebunden.

Die Spannung vom Controller uns Display ist die gleiche. Oder meinst du 
etwas anderes?

Was aufgefallen ist:
Durch kurzes Lösen und Zusammenschließen der Verbindungen (SDA und SCL) 
vom Board zum LCD wandert der verpixelte Kasten manchmal an eine andere 
Stelle, was jedoch noch weitere Verpixelungen mit sich zieht...

Grüße

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

D. M. schrieb:
> Durch kurzes Lösen und Zusammenschließen der Verbindungen (SDA und SCL)
> vom Board zum LCD wandert der verpixelte Kasten manchmal an eine andere
> Stelle, was jedoch noch weitere Verpixelungen mit sich zieht...

 Bilder sehen gar nicht mal so schlecht aus, sollte so funktionieren.
 Da es aber nicht funktioniert, ist der SPI wahrscheinlich zu schnell.
 Wie ich sehe, wird LCD uber SPI-Modul angesteuert ?
 Wenn ja, vergiss alles uber 800KHz.

von Philipp_K59 (Gast)


Lesenswert?

&u8g_dev_st7920_128x64_4x_hw_spi

Schonmal &u8g_dev_st7920_128x64_1x_hw_spi probiert?

Muss man überhaupt die ganzen Pins angeben, kenne das nur mit CS und 
Reset?

von D. M. (Gast)


Lesenswert?

Ich hatte
1
u8g_InitSPI(&u8g, &u8g_dev_st7920_128x64_hw_spi, PN(1, 5), PN(1, 3), PN(3, 5), U8G_PIN_NONE, U8G_PIN_NONE);

ausprobiert, jedoch keine Besserung.
Ich glaube ohne Arduino muss man alle Pins angeben. Zumindest gibt es 
mir eine Fehlermeldung aus (too few arguments).

Ja, das LCD wird über SPI angesteuert. Wie bekomme ich es langsamer?
Habe es über SPR0 und SPR1 probiert, jedoch auch hier keine Änderung...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

D. M. schrieb:
> Ja, das LCD wird über SPI angesteuert. Wie bekomme ich es langsamer?
> Habe es über SPR0 und SPR1 probiert, jedoch auch hier keine Änderung...

 Also, erst mal LCD Init, danach SPI2x auf 0, SPR0 und SPR1 auf 1.
 Irgendetwas auf LCD schreiben.
 Wenn nach der LCD-Ausgabe SPR0, SPR1, SPI2x wieder verstellt werden,
 Library wegschmeissen.

 Wenn die bits aber unverandert bleiben, langsam SPI Frequenz erhohen,
 bis es wieder anfangt, Pixel durcheinander zu bringen.

von D. M. (Gast)


Lesenswert?

Ich verstehe es langsam nicht mehr...
Wenn ich es als Arduino flashe, funktioniert alles.
Normal in C ohne Arduino Bootloader gibt es diesen komischen Balken 
oben.

Habe mit SPI2x, SPR0 und SPR1 rumgespielt, aber in den meisten 
Kombinationen kam gar nichts auf dem Display. Wenn was kam, dann wieder 
nur verpixelt.

Ist hier nicht auch ab und zu der Autor der Library unterwegs? :D

Evtl. sieht er das ja und kann weiterhelfen. Aktuell bin ich echt 
überfragt...

Trotzdem vielen Dank natürlich an alle die weitergeholfen haben!
Evtl. fällt ja jemandem noch was ein :)

Gruß

von Philipp_K59 (Gast)


Lesenswert?

Die Installationsanleitung mit allem drum und dran befolgt?
AVR Studio 4: Set additional options (Project - Configuration - Custom 
Options)

    [All Files]
        -ffunction-sections
        -fdata-sections
    [Linker Options]
        -Wl,--gc-sections



Wie im Example hinter draw() vielleicht noch nen 100ms delay rein um zu 
Gewährleisten das alles übertragen wurde bevor ein neues Bild erzeugt 
wird.

von Klaus (Gast)


Lesenswert?

D. M. schrieb:
> Ich verstehe es langsam nicht mehr...
> Wenn ich es als Arduino flashe, funktioniert alles.
> Normal in C ohne Arduino Bootloader gibt es diesen komischen Balken
> oben.

Dann ist doch alles klar. In der Arduino Umgebung wird etwas 
initialisiert, was du nicht initialisierst.

MfG Klaus

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

D. M. schrieb:
> Ich verstehe es langsam nicht mehr...
> Wenn ich es als Arduino flashe, funktioniert alles.
> Normal in C ohne Arduino Bootloader gibt es diesen komischen Balken
> oben.

 Das hattest du aber auch gleich sagen konnen.

Klaus schrieb:
> Dann ist doch alles klar. In der Arduino Umgebung wird etwas
> initialisiert, was du nicht initialisierst.

 Stimme ich vollkommen zu.

von D. M. (Gast)


Lesenswert?

Mit dem Delay gehts leider auch nicht.

Hier der Arduino Code:
1
#include "U8glib.h"
2
3
// setup u8g object, please remove comment from one of the following constructor calls
4
5
//U8GLIB_ST7920_128X64 u8g(3, 9, 8, U8G_PIN_NONE);               
6
/* SPI Com: 
7
SCK = en = 3 = PD3, 
8
MOSI = rw = 9 = PB1, 
9
CS = di = 8 = PB0
10
*/
11
12
U8GLIB_ST7920_128X64_1X u8g(5);
13
14
int analogPin = 0;     
15
16
int val = 0;   
17
18
void draw(void) {
19
  u8g.setFont(u8g_font_6x10);
20
  u8g.setFontPosTop(); 
21
  u8g.drawStr(0, 0, "Amps1");
22
  u8g.setPrintPos(35, 0);  // col, row
23
  u8g.print(val,4);
24
25
}
26
27
void setup(void) {
28
  
29
  // flip screen, if required
30
  // u8g.setRot180();
31
  
32
  // set SPI backup if required
33
  //u8g.setHardwareBackup(u8g_backup_avr_spi);
34
35
  // assign default color value
36
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) 
37
    u8g.setColorIndex(255);     // white
38
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
39
    u8g.setColorIndex(3);         // max intensity
40
  else if ( u8g.getMode() == U8G_MODE_BW )
41
    u8g.setColorIndex(1);         // pixel on
42
}
43
44
void loop(void) {
45
  val = analogRead(analogPin);
46
  // picture loop
47
  u8g.firstPage();  
48
  do {
49
    draw();
50
  } while( u8g.nextPage() );
51
  
52
  // rebuild the picture after some delay
53
  delay(500);
54
}

Sehe da jetzt keinen großen Unterschied. Weiß natürlich auch nicht, was 
da jetzt in den Inits selber abläuft.

von Karl H. (kbuchegg)


Lesenswert?

Das ist alles ganz nett was du da postest.
Aber das Problem ist irgendwo in der U8GLib zu suchen und nicht in 
deinem Code.

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.