logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C] LCD Simens S65 problem z inicjalizacją

ePeter1234 17 Paź 2009 15:07 2453 11
REKLAMA
  • #1 7139675
    ePeter1234
    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:

    
    #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);
    }
    
  • REKLAMA
  • #2 7139716
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #3 7140300
    ePeter1234
    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.
  • #4 7143155
    tmf
    VIP Zasłużony dla elektroda
    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.
  • REKLAMA
  • #5 7143254
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #6 7143509
    zdebel
    Poziom 15  
    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?
  • #7 7143549
    Konto nie istnieje
    Poziom 1  
  • #8 7143693
    zdebel
    Poziom 15  
    :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
  • #9 7144827
    tmf
    VIP Zasłużony dla elektroda
    Ja zrobilem tak jak na stronie www.superkranz.de i ten step up sprawdza sie ladnie, dodatkowo regulujac wypelnienie reguluje jasnosc podswietlenia.
  • #10 7173872
    ePeter1234
    Poziom 18  
    Udało mi się w końcu uruchomić podświetleie w tym wyświetlaczu. Po wysłanym kodzie:

    
    #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??
  • #11 7187527
    tmf
    VIP Zasłużony dla elektroda
    Masz tu fragmenty mojej (dzialajacej) incjalizacji:
    
    #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.
  • #12 7191939
    ePeter1234
    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:

    
    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]); 
    	}
    }
    
REKLAMA