Forum: Mikrocontroller und Digitale Elektronik Displaybeleuchtung mit PWM Dimmen=> Display hängt sich auf?


von Mario H. (rocko)


Lesenswert?

Hallo Leute,
ich habe hier ein Display 3000 Board mit 2,1" Display.
Darauf ist ein Atmega 2561 drauf und ich versuche gerade das Display mit 
der PWM zu Dimmen.

Prinzipiell funktioniert das Dimmen schon, das Problem dabei ist, dass 
sich bei Einschalten der PWM das Display verabschiedet und schön langsam 
das Display komplett weiss wird. (Sieht so aus, als hätte jemand die 
Reset Taste vom Display gedrückt). Die Displaybeleuchtung ist so wie 
gewünscht ;-(

Der Mikrokontroller läuft aber weiter (die verschiedenen Dimmstufen 
werden korrekt abgearbeitet).

Weis jemand was ich da falsch mache? Oder habe ich einfach ein 
EMV-Problem?

Dagegen spricht eigentlich, dass sich das Display auch vertschüsst, wenn 
ich 255 als Dimmstufe eingebe, da sollte das Display ja eigentlich 
Dauernd beleuchtet sein, so wie wenn gar keine PWM läuft?

Bin ein wenig Ratlos, vielleicht weis wer mehr?

vielen Dank

lg Rocko



ps.: anbei der (bescheidene) Sourcecode:

DDRB = (1 << DDB7); //Beleuchtungspin auf Ausgang schalten
  TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00); //OC0A auf Clear on 
Compare match setzen (sollte auf Pin PB7 gehen)


  OCR0A = 255;
  TCCR0B = (1<<CS01); //Timer Einschalten
  delay_ms(1000);
  OCR0A = 100;
  delay_ms(1000);
  OCR0A = 150;
  delay_ms(1000);
  OCR0A = 250;

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Da fehlt aber noch ´ne ganze Menge Code, oder gibst Du auf dem Display 
gar nichts aus?

von Mario H. (rocko)


Lesenswert?

Hi Travel Rec.

Das ist natürlich nur der PWM Teil,
vorher kommt ein "Init Display" und "Schreib was aufs Display" (nur 
damit halt was da steht)
Diese Routinen kommen von Display 3000 und funktionieren ja (wenn ich 
den PWM Teil weglasse).

Ich schrieb mir eigentlich nur aufs Display, wo im Programm ich bin (ist 
grad nur zum PWM debuggen).

Ich bin übrigens noch auf was draufgekommen: Wenn ich erst das Display 
initialisiere nachdem der PWM-Timer gestartet wurde, dann läufts 
Problemlos. Ich kann auch das Match Compare Register neu setzen und 
damit die Dimmstufe umstellen ohne Display Absturz.

Ich kanns zwar so verwenden, aber Schlau werde ich da nicht draus!

Sieht jemand MEGA 2561 Erfahrener aus meinem Code, ob ich versehentlich 
was anderes als den PB7 Pin angreife?

Vielleicht gibts ja auch jemanden mit dem Display 3000 Board, der einen 
funktionierenden Source für die Displaydimmung hat. Dann kann ich 
wenigstens einen Hardwarefehler ausschließen.

Rätselgrübend....

lg Rocko

von P. S. (Gast)


Lesenswert?

Also, prinzipiell funktioniert das display3000, da kann ich dich 
schonmal beruhigen ;-)

Ich haenge dir mal den wesentlichen Teil meiner Initialisierung an, aber 
ist dir aufgefallen, dass du fuer das Licht mit

DDRB = (1 << DDB7); //Beleuchtungspin auf Ausgang schalten

alle Pins ausser Nummer 7 auf Eingang schaltest? Wenn du das nach der 
Initialisierung machst, wuerde mich ein Reset des LCD nicht ueberraschen 
;-)

void LCD::initialize( void)
{
  // All Ports to output
  LCD_DDR = 255;

  // Turn light on.
  SetBacklight( lightness);

  SPSR |= BIT_VALUE( SPI2X);
  SPCR = BIT_VALUE( SPE) | BIT_VALUE( MSTR);

  UTILITY::Pause( 300);

  LCD_BIT_CLEAR( LCD_RESET);
  UTILITY::Pause( 75);

  LCD_BIT_SET( LCD_SELECT);
  UTILITY::Pause( 75);

  LCD_BIT_CLEAR( LCD_CLOCK);
  UTILITY::Pause( 75);

  LCD_BIT_SET( LCD_DC);
  UTILITY::Pause( 75);

  LCD_BIT_SET( LCD_RESET);
  UTILITY::Pause( 75);

  spiSendPGMWords( &InitData[ 0], 2);
  UTILITY::Pause( 75);

  spiSendPGMWords( &InitData[ 2], 10);
  UTILITY::Pause( 75);

  spiSendPGMWords( &InitData[ 12], 23);

  LCD_BIT_CLEAR( LCD_SELECT);
}

void LCD::SetBacklight( uint8_t Lightness)
{
  static const uint16_t PWMValue [] =
  {
    0x00, 0x1b, 0x1d, 0x20, 0x24, 0x28, 0x30, 0x38,
    0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa8, 0xc0,
    0xf0, 0x128, 0x168, 0x180
  };

  if( Lightness > LCD_BACKLIGHT_FULL)
  {
    Lightness = LCD_BACKLIGHT_FULL;
  }

  OCR1C = PWMValue[ Lightness];

  OCR1A = 0x180;

  // PWM, phase correct.
  LCD_TIMERA = ( 1 << WGM11) | ( 1 << WGM10) | ( 1 << COM1C1);
  // Set clock/prescaler 1/256 -> enable counter.
  LCD_TIMERB = ( 1 << WGM13) | ( 1 << CS11) | ( 1 << CS10);
}

von Mario H. (rocko)


Lesenswert?

Hallo Peter,

*****
alle Pins ausser Nummer 7 auf Eingang schaltest? Wenn du das nach der
Initialisierung machst, wuerde mich ein Reset des LCD nicht ueberraschen
;-)
******

Danke für den Tipp, werde das nacher gleich ausprobieren (wenn mein 
Desktop wieder frei zum Flashen ist).
Darf ich fragen wieso ich die Eingänge nicht alle auf Input schalten 
darf? Ich dachte Standardmäßig sind die sowieso auf Input gestellt? (Ich 
sollte das mal im Datenblatt nachlesen, weis aber dann immer noch nicht, 
warum ein Umschalten einen Reset beim Display bewirkt!)

lg Rocko

von P. S. (Gast)


Lesenswert?

Schau mal in die Initialisierung vom Display, das haengt doch an diesem 
Port und die Pins werden als Ausgaenge gebraucht, um mit dem Display zu 
kommunizieren.

von Mario H. (rocko)


Lesenswert?

oops!!!

Anfänger Fehler!!!

vielen Dank Peter...


lg Rocko

von Rico H. (Firma: FHNW) (2she)


Lesenswert?

P. S. schrieb:
> static const uint16_t PWMValue [] =
>   {
>     0x00, 0x1b, 0x1d, 0x20, 0x24, 0x28, 0x30, 0x38,
>     0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa8, 0xc0,
>     0xf0, 0x128, 0x168, 0x180
>   };

Hey! wieso 0x00 bis 0x180 und nicht nur 0xff?! kommt man so auf 100% 
Helligkeit?

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.