Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C] LCD Simens S65 problem z inicjalizacją

17 Paź 2009 15:07 2264 11
  • Poziom 18  
    Witam!!!

    Chciałem sobie podpiąć wyświetlacz z wyżej wymienionego telefonu pod ATmega644. LCD pracuje po sprzętowym SPI + dwa dodatkowe piny na RS i RESET. Pobrałem z internetu instrukcje w PDF jak ten wyświetlacz zainicjować. Napisałem procedury w c pod WUN AVR, ale coś mi to się nie odpala. połączenia są poprawne SPI też napewno działa bo, dekoder mp3 pracuje poprawnie. Problem pewnie leży gdzies w programie, ale nie mogę go dostrzec. Prosż eo pomoc w rozwiązaniu problemu.

    Kod inicjalizacji procka:

    Code:

    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include "spi.h"
    #include "s65_lcd.h"

    char cmd;

    char int1[24] =
    {
    0xFD, 0xFD, 0xFD, 0xFD,
    0xEF, 0x00, 0xEE, 0x04, 0x1B, 0x04, 0xFE, 0xFE, 0xFE, 0xFE, 0xEF, 0x90, 0x4A, 0x04,
    0x7F, 0x3F, 0xEE, 0x04, 0x43, 0x06
    };

    char int2[40] =
    {
    0xEF, 0x90,  0x09, 0x83,  0x08, 0x00,  0x0B, 0xAF,  0x0A, 0x00,  0x05, 0x00,  0x06, 0x00,
    0x07, 0x00,  0xEF, 0x00,  0xEE, 0x0C,  0xEF, 0x90,  0x00, 0x80,  0xEF, 0xB0,  0x49, 0x02,
    0xEF, 0x00,  0x7F, 0x01,  0xE1, 0x81,  0xE2, 0x02,  0xE2, 0x76,  0xE1, 0x83
    };

    char int3[6] =
    {
    0x80, 0x01,
    0xEF, 0x90, 0x00, 0x00
    };

    void lcd_init(void)
    {

    int n = 1;

       while(n<25)
       {
       if(n==3)
          {
          _delay_ms(50);
          }
       send_lcd_cmd(int1[1]);
       n++;
       }
       
       n = 1;
       
       _delay_ms(6);
       
       while(n<41)
       {
       send_lcd_cmd(int1[2]);
       n++;
       }
       
       n = 1;
       
       _delay_ms(50);
       
       while(n<7)
       {
       send_lcd_cmd(int1[3]);
       n++;
       }
    }

    void send_lcd_cmd(char lcd_data)
    {
       spi_init_lcd();
       PORTD |=(_BV(PD4)|_BV(PD3));
       PORTB &=~_BV(PB1);
       
       spi_send(lcd_data);
    }
  • Poziom 43  
    Aleś nakombinował ;p
    Spróbuj to:

    Code:

       for (i=0;i<=23;i++)
       {
         send_lcd_cmd(int1[i]);
       }
       
       
       _delay_ms(7);
       
       for (i=0;i<=39;i++)
       {
         send_lcd_cmd(int2[i]);
       }
       
       _delay_ms(50);
       
       for (i=0;i<=1;i++)
       {
         send_lcd_cmd(int3[i]);
       }


    Widzę że to LS020. Mogłeś chociaż napisać.
  • Poziom 18  
    Dzieki za odp. Faktycznie, zapomnialem napisac jaki to rodzaj wyswietlacza, ale pisalem posta na szybko przed wyjsciem:) Zmienilem kod na taki jaki zaproponowales, ale nadal ekran jest martwy. Albo tak mi sie wydaje, bo nie mam jeszcze podswietlenia ekranu. Chociaz wydaje mi sie ze bez podswietlenia powinienem zobaczyc jakies losowe piksele.
  • Moderator Mikrokontrolery Projektowanie
    Wejdz na strone www.superkranz.de i tam masz gotowe programy pod ten wyswietlacz. Jesli potrzebujesz to mam tez pdfa z opisem zastosowanego tam sterownika.
  • Poziom 43  
    Kod jest dobry.
    Zresztą mój też na tym wzorowałem (a dokładniej na kodzie w BASCOMIe który rok temu wzorowałem na kodzie z tej strony ;D)
    Bez podświetlania mało co widać. Po prostu je podłącz.
  • Poziom 14  
    Przy okazji się zapytam, jaki jest właśnie najlepszy sposób żeby uzyskać to 10.4V, zaproponowany step up/boost, będzie on działał przy 3.6V też? Czy może przetwornica pojemnościowa, skoro nie potrzebujemy jakiegoś dużego prądu?
  • Poziom 43  
    Ja bym dał Step-Up z cewką sterowany PWM-em z procesora.
    Działa już od 1,5V :D
  • Poziom 14  
    :D nice, ja w swoich obu lcd'kach (ls020 i l2f50) małymi drucikami połączyłem diody równolegle i z 3.6 je daje, no ale jest to już metoda inwazyjna
  • Moderator Mikrokontrolery Projektowanie
    Ja zrobilem tak jak na stronie www.superkranz.de i ten step up sprawdza sie ladnie, dodatkowo regulujac wypelnienie reguluje jasnosc podswietlenia.
  • Poziom 18  
    Udało mi się w końcu uruchomić podświetleie w tym wyświetlaczu. Po wysłanym kodzie:

    Code:

    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include "spi.h"
    #include "s65_lcd.h"

    char cmd;

    char int1[4] =
    {
    0xFD, 0xFD, 0xFD, 0xFD,
    };

    char int2[20] =
    {
    0xEF, 0x00, 0xEE, 0x04, 0x1B, 0x04, 0xFE, 0xFE, 0xFE, 0xFE, 0xEF, 0x90, 0x4A, 0x04,
    0x7F, 0x3F, 0xEE, 0x04, 0x43, 0x06
    };

    char int3[40] =
    {
    0xEF, 0x90,  0x09, 0x83,  0x08, 0x00,  0x0B, 0xAF,  0x0A, 0x00,  0x05, 0x00,  0x06, 0x00,
    0x07, 0x00,  0xEF, 0x00,  0xEE, 0x0C,  0xEF, 0x90,  0x00, 0x80,  0xEF, 0xB0,  0x49, 0x02,
    0xEF, 0x00,  0x7F, 0x01,  0xE1, 0x81,  0xE2, 0x02,  0xE2, 0x76,  0xE1, 0x83
    };

    char int4[6] =
    {
    0x80, 0x01,
    0xEF, 0x90, 0x00, 0x00
    };

    void lcd_init(void)
    {

    int i = 0;

       for(i=0;i<=3;i++)
       {
       send_lcd_cmd(int1[i]);
       }
       
       _delay_ms(50);

       for (i=0;i<=19;i++)
       {
        send_lcd_cmd(int2[i]);
       }
       
       _delay_ms(7);
       
       for (i=0;i<=39;i++)
       {
        send_lcd_cmd(int3[i]);
       }
       
       _delay_ms(50);
       
       for (i=0;i<=5;i++)
       {
        send_lcd_cmd(int4[i]);
       }
    }

    void send_lcd_cmd(char lcd_data)
    {
       spi_init_lcd();
       PORTD |=(_BV(PD4)|_BV(PD3));
       PORTB &=~_BV(PB1);
       
       spi_send(lcd_data);
    }


    Mam cały czas biały ekran. Wydaje mi się, że dalej nie przechodzi inicjalizacja, bo z tego co czytałem to powinienm zobaczyć jakąś pikseloze czy coś. Nie jestem pewien czy mam wszystko ok w kodzie. Może ktoś na to żucić okiem??
  • Moderator Mikrokontrolery Projektowanie
    Masz tu fragmenty mojej (dzialajacej) incjalizacji:
    Code:

    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include <stddef.h>
    #include <progspace.h>

    //Pin assigments:
    //PA5 - LCD Data
    //PD5 - 0 - PA5 is input
    //PC4 - 0 - PA5 is output (default)
    //PD4 - LCD CS
    //PC2 - LCD RS
    //PC6 - LCD RESET
    //PC1 - LSC SCK

    #ifndef LCD_RESET
    #define LCD_RESET    PC6
    #endif

    #ifndef LCD_CS
    #define LCD_CS      PD4
    #endif

    #ifndef LCD_RS
    #define LCD_RS      PC2
    #endif

    #ifndef LCD_SCK
    #define LCD_SCK      PC1
    #endif

    #ifndef LCD_DAT
    #define LCD_DAT      PA5
    #endif

    //LCD controller registers
    #define DATCTL   0xBC         // Data Control (data handling in RAM)
    #define DISCTL   0xCA         // Display Control
    #define GCP64   0xCB         // pulse set for 64 gray scale
    #define GCP16   0xCC         // pulse set for 16 gray scale
    #define OSSEL   0xD0         // Oscillator select
    #define GSSET   0xCD         // set for gray scales
    #define SLPOUT   0x94         // Display out of sleep (no parameter)
    #define SD_CSET 0x15         // column address setting
    #define SD_PSET 0x75         // page address setting
    #define ASCSET   0xAA         // aerea scroll setting
    #define SCSTART 0xAB         // scroll start setting
    #define DISON   0xAF         // Display ON (no parameter)
    #define DISOFF   0xAE       // Display off
    #define SLEEPIN 0x95       // Sleep in sequence
    #define RAMWR   0x5C         // Display Memory write

    LCDDriver::LCDDriver()
    {
       PORTC&=~(_BV(PC3)); DDRC|=_BV(PC3);   //Pin to 3V regulator as output, logic zero
       DDRE|=_BV(PE3);   //Pin to LCD backlight as output
       TCCR3A|=_BV(COM3A1) | _BV(WGM30);   //Set pin OC3A to clear on compare match, fast 8-bit PWM mode
       TCCR3B|=_BV(CS30);               //Set timer3 prescaler to 1
       PORTC&=~_BV(PC4); PORTD|=_BV(PD5);   //Set direction drivers - outpt to LCD
       DDRC|=_BV(PC4);
       SetLCDOn(LCD_FullPower);         //Turn on LCD power
       SetBackLight(140);               //Set LCD backlight intensity

       PORTC &= ~_BV(LCD_RESET);
         DDRC |= _BV(LCD_RESET);

         PORTA |= _BV(LCD_DAT);
         DDRA |= _BV(LCD_DAT);

       PORTD &= ~_BV(LCD_CS);
         DDRD |= _BV(LCD_CS);

         PORTC &= ~_BV(LCD_SCK);
         DDRC |= _BV(LCD_SCK);

         PORTC |= _BV(LCD_RS);  // not used from LPH display
         DDRC |= _BV(LCD_RS);

       LCDInit();         //Initialize LCD controller
       SetTxtAttrs(TxtOpaque);
    }

    void LCDDriver::LCDInit()
    {
      // generate clean display reset
      PORTC &= ~_BV(LCD_RESET); // reset display
      SelectCS(false);          // CS is high during reset release
      PORTC |= _BV(LCD_RS);     // RS is set to high
      _delay_ms(10);
      PORTC |= _BV(LCD_RESET);  // release reset
      _delay_ms(35);

      SelectCS(true);         // select display

      WriteCmd(DATCTL);
      WriteByte(0x2B);

      CSpulse();

      static const uint8_t disctl[9] PROGMEM = {0x4C, 0x01, 0x53, 0x00, 0x02, 0xB4, 0xB0, 0x02, 0x00};
      static const uint8_t gcp64_0[29] PROGMEM =
                          {0x11,0x27,0x3C,0x4C,0x5D,0x6C,0x78,0x84,0x90,0x99,0xA2,0xAA,0xB2,0xBA,
                           0xC0,0xC7,0xCC,0xD2,0xC7,0xDC,0xE0,0xE4,0xE8,0xED,0xF0,0xF4,0xF7,0xFB,
                           0xFE};
      static const uint8_t gcp64_1[34] PROGMEM =
                         {0x01,0x03,0x06,0x09,0x0B,0x0E,0x10,0x13,0x15,0x17,0x19,0x1C,0x1E,0x20,
                          0x22,0x24,0x26,0x28,0x2A,0x2C,0x2D,0x2F,0x31,0x33,0x35,0x37,0x39,0x3B,
                          0x3D,0x3F,0x42,0x44,0x47,0x5E};
      static const uint8_t gcp16[15] PROGMEM =
                          {0x13,0x23,0x2D,0x33,0x38,0x3C,0x40,0x43,0x46,0x48,0x4A,0x4C,0x4E,0x50,0x64};

      uint8_t i;

      WriteCmd(DISCTL);
      for (i=0; i<9; i++)
      {
        WriteByte(pgm_read_byte(&disctl[i]));
      }

      WriteCmd(GCP64);
      for (i=0; i<29; i++)
      {
        WriteByte(pgm_read_byte(&gcp64_0[i]));
        WriteByte(0x00);
      }

      for (i=0; i<34; i++)
      {
        WriteByte(pgm_read_byte(&gcp64_1[i]));
        WriteByte(0x01);
      }

      WriteCmd(GCP16);
      for (i=0; i<15; i++)
      {
        WriteByte(pgm_read_byte(&gcp16[i]));
      }

      WriteCmd(GSSET);
      WriteByte(0x00);

      WriteCmd(OSSEL);
      WriteByte(0x00);

      WriteCmd(SLPOUT);

      WriteCmd(SD_CSET);
      WriteByte(0x08);
      WriteByte(0x01);
      WriteByte(0x8B);
      WriteByte(0x01);

      WriteCmd(SD_PSET);
      WriteByte(0x00);
      WriteByte(0x8F);

      WriteCmd(ASCSET);
      WriteByte(0x00);
      WriteByte(0xAF);
      WriteByte(0xAF);
      WriteByte(0x03);

      WriteCmd(SCSTART);
      WriteByte(0x00);

      PORTC &= ~_BV(LCD_RS);
      WriteByte(DISON);

      SelectCS(false);      // deselect display
    }

    void LCDDriver::CSpulse()
    {
      PORTD |= _BV(LCD_CS);
      asm volatile("nop");
      PORTD &= ~_BV(LCD_CS);
    }

    void LCDDriver::SelectCS(bool state)
    {
       if(state) PORTD&=~_BV(LCD_CS); else PORTD|=_BV(LCD_CS);
    }

    void LCDDriver::WriteCmd(uint8_t cmd)
    {
      PORTC &= ~_BV(LCD_RS);

      Write(cmd);
      Write(0x00);

      PORTC |= _BV(LCD_RS);
    }

    void LCDDriver::WriteByte(uint8_t byte)
    {
      Write(byte);
      Write(0x00);
    }

    void LCDDriver::WriteWord(uint16_t word)
    {
      Write(word>>8);
      Write(word);
    }


    Po zainicjowaniu powinienes zobaczyc tlo skladajace sie z losowych kolorowych pixeli. Jesli jest inaczej to znaczy, ze cos masz zle.
  • Poziom 18  
    W końcu udało mi się ( tak mi się wydaje) uruchomić wyświetlacz. Na ekranie mam jakieś piksele:) W moim kodzie brakowało mi tylko resetu i opóżnieniea jednej ms. przed inicjalizacją. Kod wygląda tak. Może komuś się przyda:

    Code:

    void lcd_init(void)
    {

    int i = 0;

       PORTD &=~_BV(PD4);
       _delay_ms(1);
       PORTD |=_BV(PD4);

       for(i=0;i<=3;i++)
       {
       send_lcd_cmd(int1[i]);
       }
       
       _delay_ms(50);

       for (i=0;i<=19;i++)
       {
        send_lcd_cmd(int2[i]);
       }
       
       _delay_ms(7);
       
       for (i=0;i<=39;i++)
       {
        send_lcd_cmd(int3[i]);
       }
       
       _delay_ms(50);
       
       for (i=0;i<=5;i++)
       {
        send_lcd_cmd(int4[i]);
       }
    }