- LiTime Speicher und Akkus         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 27

Thema: LCD (KS0066) 4Bit-Mode init brauche hilfe, PIC 18f4550

  1. #11
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo

    Tja, so langsam gehen mir die Ideen aus. Du könntest bei Display on (sollte doch besser drin bleiben) ein 0x0f übergeben, dann müßte der Cursor irgendwo sichtbar sein und blinken.

    Was ich noch nicht nachvollziehen kann ist das Timeing mit den Verzögerungen. Vielleicht nochmal prüfen ob wirklich die erwartete Zeit gewartet wird. Wird bei Delay10TCYx() wirklich ein 16-bit-Wert erwartet (z.B. 40*200)? Im Zweifel eine kleine Blinksteuerung im Sekundentakt programmieren und mit Stoppuhr überprüfen:

    Code:
    void blink(void)
    {
    	unsigned char temp;
    	while(1)
    	{
    	   led_an;
    	   for(temp=0; temp<50; temp++) delay100us(200); // 50*20ms=1sek
    	   led_aus;
    	   for(temp=0; temp<50; temp++) delay100us(200); // 50*20ms=1sek
    	}
    }
    (ungetestet)

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #12
    Benutzer Stammmitglied
    Registriert seit
    20.07.2008
    Ort
    Herford
    Alter
    39
    Beiträge
    52
    hi

    hast mal wieder recht
    an Delay10TCYx() darf nur 0..255 sprich 8 bit

    hab die funktion abgeändert leider viel mir auf dieschnelle nix beseres ein als eine long veriable zu verwende.




    Code:
    void delay100us(unsigned long multiplikator)
    // for  PicLSBK (16MHz Taktzyklus = 4 MHz Befehlszyklus)
    {
    unsigned long i;
    	
    	for (i=0;i<(multiplikator*400);i++) // 400*nop=100µs 
    	{nop;}
    }
    lcd flackert nicht mehr, aber zeichen sind auch nicht drauf zu erkennen

    HILFE

  3. #13
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Der multiplikator kann ja weiterhin 8 Bit haben, muß also nicht long sein.

    Vielleicht wird die Schleife von Kompiler wegrationalisiert. Ich verzögere mit Dummy-Befehlen in der Zählschleife:
    Code:
    void delay(uint8_t d)
    {
    	uint16_t d1, dummy;
    	for (d1=d*255; d1>0; d1--) dummy^=d1;
    }
    Eleganter wäre allerdings dies:
    Code:
    void delay100us(unsigned char multiplikator)
    // for  PicLSBK (16MHz Taktzyklus = 4 MHz Befehlszyklus)
    {
       while(multiplikator--) Delay10TCYx(40);   //40*10*0,25µs = 100 µs
    }
    Wenn die Wartezeit zu kurz ist scheint mir der Clearbefehl kritisch, weil der recht lange zur Ausführung benötigt. Dann würden die nachfolgenden Einstellungen ins Nirwana gehen. Vielleicht mal testweise ohne clear initialisieren. Hast du das mit dem "Display on-Cursor on-Cursor blink" mal getestet?

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    20.07.2008
    Ort
    Herford
    Alter
    39
    Beiträge
    52
    erstes erfolgs erlebnis init scheint zu funktionieren, auch wenn nur seeeehr langsam.

    hab zum test das display auf einzeilig umgestellt

    LCD_WriteRegister(0x20); funktioniert

    zudem bei LCD an courser an
    LCD_WriteRegister(0x0f); fungtioniert auch

    das komische
    erst nach sa 5 sec ist 1 zeilen mode aktiv
    nach weiteren 20 sec blinkt der courser an positon 1
    nach 6 sec geht er wieder für 20 sec aus und kommt für 6 sec wieder.

    von einem zeichen keine spur

  5. #15
    Benutzer Stammmitglied
    Registriert seit
    20.07.2008
    Ort
    Herford
    Alter
    39
    Beiträge
    52
    deine while schleife gefällt mir sehr gut, ich war so frei sie gleich einzubauen.

    courser blinkt nun an erster position aber im wechsel mit einem rechteck 5x8 dot's

  6. #16
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    ...ich war so frei sie gleich einzubauen.
    So war's auch gedacht :)

    Schön, immerhin ein Fortschritt. Zeig doch nochmal deinen aktuellen (geputzten?) Code. Ich würde das Übernehmen der Daten in eine Funktion schreiben und nochmals die high-Zeit verlängern:
    Code:
    void strobe(void)
    {
       LCD_E = 1;                // Daten übernehmen
       delay100us(3);
       LCD_E = 0;
    }
    Hast du ein Datenblatt für dein Display (oder eine genaue Typangabe)? Ich verwende das oben erwähnte KS0066U-Datenblatt (war eine der ersten Fundstellen der Suchmaschine), vielleicht gibt's da Unterschiede.

    Blockcursor 5x8 ist schon richtig. Ist das Init() und das Blinken immer noch so langsam?

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    20.07.2008
    Ort
    Herford
    Alter
    39
    Beiträge
    52
    link zum datenblatt meines LCD
    http://www.zyscom.pl/katalog/ym2004a.pdf

    verwende das gleiche controler datenblat wie du : http://www.datasheetcatalog.org/data...5/553815_1.pdf

    init ist nun sehr schnell fertig und keine pausen danach, courser blinkt fröhlich an zeilen anfang ununterbrochen.

    Code:
    /** I N C L U D E S **********************************************************/
    
    #include <p18f4550.h>
    #include <delays.h>
    
    
    /** D E F I N I T I O N S ****************************************************/
    
    #define PORTLCD 	LATB
    #define TRIS_LCD    TRISB
    #define LCD_E		PORTBbits.RB0
    #define LCD_RS		PORTBbits.RB2
    #define LCD_RW		PORTBbits.RB3
    #define nop			_asm nop _endasm  // verzögerung 0,25µs
    
    //****************************************************************************
    
    #pragma code
    
    
    void delay100us(unsigned char multiplikator)
    // for  PicLSBK (16MHz Taktzyklus = 4 MHz Befehlszyklus)
    {
       while(multiplikator--) Delay10TCYx(40);   //40*10*0,25µs = 100 µs
    }
    
    
    void LCD_BUSY(void)
    {
    	unsigned char temp1;
    //	unsigned char temp2;
    	do
    	{
    		TRIS_LCD = 0xF0; 		// LCD-PORT = high nibbles:eingang; low nibbles:ausgang
    //Display abfrage
    		LCD_RS = 0; 			// LCD im Befehls-Mode
    		LCD_RW = 1; 			// LCD im Lesen-Mode
    		LCD_E = 1; 				// Enable (LCD)
    		temp1 = PORTLCD;
    		temp1 = temp1 & 0xF0; 	// Niederw.Nibble (steuerbits) ausmaskieren
    		LCD_E = 0; 				//   toggeln
    		
    		LCD_E = 1; 				// Enable (LCD)
    		nop;
    		LCD_E = 0; 				//   toggeln
    	} while (temp1>=0x80);	
    		
    	delay100us(1);
    	LCD_RW = 0; 		// Busy = low: LCD im Schreiben-Mode
    	TRIS_LCD = 0x00;     // LCD-PORT = Ausgänge
    	PORTLCD  = 0x00;	 // Daten und Steuerleitungen LOW
    } 
    
    
    void LCD_WriteZeichen(unsigned char zeichen)
    {
    	unsigned char x;
    delay100us(200);
    //	LCD_BUSY(); 				// Warten bis LCD bereit ist
    				
    	LCD_RW = 0; 				// LCD im Schreiben-Mode
    	LCD_RS = 1; 				// LCD im Befehl-Mode
    
    	x = zeichen & 0xf0;
    	x = x | LCD_RS;	
    	PORTLCD = x;				//höherwertiges nibbel
    
    	nop;
    	LCD_E = 1; 					// Enable (LCD)
    	nop;nop;					
    	LCD_E = 0;
    
    delay100us(50);					//5ms warten nach den 1.nibble
    
    	x = zeichen;			
    	x = (x << 4)& 0xf0;			//niederwertiges nibbel
    	x = x | LCD_RS;
    	PORTLCD = x;
    	
    	LCD_E = 1; 					// Enable (LCD)
    	nop;nop;					
    	LCD_E = 0;
    delay100us(50);					//5ms warten nach den 2.nibble
    	LCD_RS = 0;
    }
    
    
    void LCD_WriteString(unsigned char *String) 
    {
    	unsigned char zeichen;
    	
    	zeichen = *String;
    	while(zeichen !='\0')
    	{
    		LCD_WriteZeichen(zeichen); 	// zeichen am LC-Display ausgeben
    		String++; 					
    		zeichen = *String; 			
    	}
    }
    
    void LCD_WriteRegister(unsigned char data) 
    {
    	unsigned char x;
    delay100us(200);
    //	LCD_BUSY(); 				// Warten bis LCD bereit ist
    
    	//	LCD_RW = 0; 				// LCD im Schreiben-Mode
    	//	LCD_RS = 0; 				// LCD im Befehl-Mode	
    					
    	x = data & 0xf0;
    	PORTLCD = x;				//höherwertiges nibbel
    
    
    	LCD_E = 1; 					// Enable (LCD)
    	nop;nop;					
    	LCD_E = 0;
    
    delay100us(50);					//5ms warten nach den 1.nibble
    	x = data;			
    	x = (x << 4)& 0xf0;			//niederwertiges nibbel
    	PORTLCD = x;
    	
    	LCD_E = 1; 					// Enable (LCD)
    	nop;nop;					
    	LCD_E = 0;
    delay100us(50);					//5ms warten nach dem 2.nibble
    }
    
    
    
    void LCD_Init(void) 
    {
    // LCD initialisieren
    
    	TRIS_LCD = 0x00;     // LCD-PORT = Ausgänge
    	PORTLCD  = 0x00;	 // Daten und Steuerleitungen LOW
    
    
    	delay100us (150);
    	delay100us (150);	// warte über 30ms
    	delay100us (100);
    
    	PORTLCD = 0x30;				// Interface auf 8-Bit setzen						
    	LCD_E = 1; 					// Enable (LCD)
    	nop;nop;	
    	LCD_E = 0;
    	
    	delay100us(50);				//warte 5ms
    								
    	LCD_E = 1; 					// Interface auf 8-Bit setzen
    	nop;nop;					// Enable (LCD)					
    	LCD_E = 0;
    
    	delay100us(2);				//warte 200µs
    								
    	LCD_E = 1; 					// Interface auf 8-Bit setzen
    	nop;nop;					// Enable (LCD)				
    	LCD_E = 0;
    	
    	delay100us(2);				//warte 200µs
    	
    	PORTLCD = 0x20;				// Interface auf 4-Bit setzen
    	LCD_E = 1; 					// Enable (LCD)
    	nop;nop;					
    	LCD_E = 0;
    
    	LCD_WriteRegister(0x28);  // 2-zeilig, 5x8-Punkt-Matrix
    	LCD_WriteRegister(0x08);  // Display aus	
    	LCD_WriteRegister(0x01);  // Display löschen
    	LCD_WriteRegister(0x06);  // Kursor nach rechts wandernd, kein Display-Shift
    	LCD_WriteRegister(0x0f);  // Display ein  [ 0x0C = ein, 0x08 = aus ] 
    
    }
    
    
    void main (void)
    {
       LCD_Init();
    	
    	LCD_WriteZeichen('t');
    	LCD_WriteZeichen('x');
    }

  8. #18
    Benutzer Stammmitglied
    Registriert seit
    20.07.2008
    Ort
    Herford
    Alter
    39
    Beiträge
    52
    noch mal mit funktion void enable (void)

    Code:
    /** D E F I N I T I O N S ****************************************************/
    
    #define PORTLCD 	LATB
    #define TRIS_LCD    TRISB
    #define LCD_E		PORTBbits.RB0
    #define LCD_RS		PORTBbits.RB2
    #define LCD_RW		PORTBbits.RB3
    #define nop			_asm nop _endasm  // verzögerung 0,25µs
    
    //****************************************************************************
    
    #pragma code
    
    void delay100us(unsigned char multiplikator)
    // for  PicLSBK (16MHz Taktzyklus = 4 MHz Befehlszyklus)
    {
       while(multiplikator--) Delay10TCYx(40);   //40*10*0,25µs = 100 µs
    }
    
    void enable(void)
    {
       LCD_E = 1;                // Daten übernehmen
       delay100us(3);
       LCD_E = 0;
    }
    
    void LCD_BUSY(void)
    {
    	unsigned char temp1;
    //	unsigned char temp2;
    	do
    	{
    		TRIS_LCD = 0xF0; 		// LCD-PORT = high nibbles:eingang; low nibbles:ausgang
    //Display abfrage
    		LCD_RS = 0; 			// LCD im Befehls-Mode
    		LCD_RW = 1; 			// LCD im Lesen-Mode
    		LCD_E = 1; 				// Enable (LCD)
    		temp1 = PORTLCD;
    		temp1 = temp1 & 0xF0; 	// Niederw.Nibble (steuerbits) ausmaskieren
    		LCD_E = 0; 				//   toggeln
    		
    		enable();
    	} while (temp1>=0x80);	
    		
    	delay100us(1);
    	LCD_RW = 0; 		// Busy = low: LCD im Schreiben-Mode
    	TRIS_LCD = 0x00;     // LCD-PORT = Ausgänge
    	PORTLCD  = 0x00;	 // Daten und Steuerleitungen LOW
    } 
    
    
    void LCD_WriteZeichen(unsigned char zeichen)
    {
    	unsigned char x;
    delay100us(200);
    //	LCD_BUSY(); 				// Warten bis LCD bereit ist
    				
    	LCD_RW = 0; 				// LCD im Schreiben-Mode
    	LCD_RS = 1; 				// LCD im Befehl-Mode
    
    	x = zeichen & 0xf0;
    	x = x | LCD_RS;	
    	PORTLCD = x;				//höherwertiges nibbel
    
    	nop;
    	enable();
    delay100us(50);					//5ms warten nach den 1.nibble
    
    	x = zeichen;			
    	x = (x << 4)& 0xf0;			//niederwertiges nibbel
    	x = x | LCD_RS;
    	PORTLCD = x;
    	
    	enable();
    delay100us(50);					//5ms warten nach den 2.nibble
    	LCD_RS = 0;
    }
    
    
    void LCD_WriteString(unsigned char *String) 
    {
    	unsigned char zeichen;
    	
    	zeichen = *String;
    	while(zeichen !='\0')
    	{
    		LCD_WriteZeichen(zeichen); 	// zeichen am LC-Display ausgeben
    		String++; 					
    		zeichen = *String; 			
    	}
    }
    
    void LCD_WriteRegister(unsigned char data) 
    {
    	unsigned char x;
    delay100us(200);
    //	LCD_BUSY(); 				// Warten bis LCD bereit ist
    
    	//	LCD_RW = 0; 				// LCD im Schreiben-Mode
    	//	LCD_RS = 0; 				// LCD im Befehl-Mode	
    					
    	x = data & 0xf0;
    	PORTLCD = x;				//höherwertiges nibbel
    
    
    	enable();
    
    delay100us(50);					//5ms warten nach den 1.nibble
    	x = data;			
    	x = (x << 4)& 0xf0;			//niederwertiges nibbel
    	PORTLCD = x;
    
    	enable();	
    delay100us(50);					//5ms warten nach dem 2.nibble
    }
    
    
    
    void LCD_Init(void) 
    {
    // LCD initialisieren
    
    	TRIS_LCD = 0x00;     // LCD-PORT = Ausgänge
    	PORTLCD  = 0x00;	 // Daten und Steuerleitungen LOW
    
    
    	delay100us (150);
    	delay100us (150);	// warte über 30ms
    	delay100us (100);
    
    	PORTLCD = 0x30;				// Interface auf 8-Bit setzen						
    	enable();
    	
    	delay100us(50);				//warte 5ms
    								
    			 					// Interface auf 8-Bit setzen
    	enable();					// Enable (LCD)					
    
    	delay100us(2);				//warte 200µs
    								
    	enable(); 					// Interface auf 8-Bit setzen
    								// Enable (LCD)				
    
    	delay100us(2);				//warte 200µs
    	
    	PORTLCD = 0x20;				// Interface auf 4-Bit setzen
    	enable();					// Enable (LCD)
    						
    	LCD_WriteRegister(0x28);  // 2-zeilig, 5x8-Punkt-Matrix
    	LCD_WriteRegister(0x08);  // Display aus	
    	LCD_WriteRegister(0x01);  // Display löschen
    	LCD_WriteRegister(0x06);  // Kursor nach rechts wandernd, kein Display-Shift
    	LCD_WriteRegister(0x0f);  // Display ein  [ 0x0C = ein, 0x08 = aus ] 
    }
    
    
    void main (void)
    {
       LCD_Init();
    	
    	LCD_WriteZeichen('t');
    	LCD_WriteZeichen('x');
    }

  9. #19
    Benutzer Stammmitglied
    Registriert seit
    20.07.2008
    Ort
    Herford
    Alter
    39
    Beiträge
    52
    wenn ich nach

    ein 'E' ausgeben will. bekomme ich aufeinmal 2 blinkende courser einen in der ersten zeile an 1. stelle (wie gehabt) und einen 2 . in der 2. zeile an 5. stelle???

    Code:
    void main (void)
    {
       LCD_Init();
    	LCD_WriteZeichen('E');
    }

  10. #20
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Ein Verdacht:
    'E' hat den Hexwert 0x45, das ist Binär 0b01000101. Wenn nun beim Schreiben der Daten das RS nicht gesetzt wäre, würde dies den Start des Usergraphik-Bereich definieren:
    Set CGRAM Address 0 0 0 1 AC5 AC4 AC3 AC2 AC1 AC0 Set CGRAM address in address counter.
    Alle weiteren Daten würden dann in den Grafikspeicher geschrieben werden, der Cursor würde aber vermutlich trotzdem im sichtbaren Bereich bewegt werden. Das ist allerdings reine Spekulation. Was ich in diesem Zusammenhang nicht weiß:

    x = x | LCD_RS;

    Funktioniert dies wie erwartet? Der Wert für LCD_RS ist doch 1, wir benötigen aber 4 (RS ist PortBit2) zum verodern, oder? Vielleicht mal sicherheitshalber doch diese Formulierung verwenden:

    x = zeichen & 0xf0;
    PORTLCD = x; //höherwertiges nibbel
    LCD_RS = 1; // LCD Daten-Mode setzen

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test