LCD Probelm Med Microchip C18

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Jörgen H
Inlägg: 6
Blev medlem: 3 juni 2010, 12:17:11

LCD Probelm Med Microchip C18

Inlägg av Jörgen H »

Hej har problem med min LCD funtion.
Jag försöker med en MikroC liknande funktion

"lcd_out(Rad,Position,"TEXT")"

Rad 1,2,3 fungerar som dom ska,
men skriver jag "123456789"
till rad 4 ser det ut så här.

------------------------
| |
|56789 |
| 4|
|123 |
------------------------

Skriver 123 på rad 4 hoppar till rad 3 och fortsätter,
Varför??

Skriver jag utan att flytta cursor
så fungerar hela LCDn.

Annväner PIC 18F4550 och 4 raders LCD Från Kjell.com

Borde kanske nämna att jag inte är någon expert
har programmerat PIC i 1 år som hobby.

Så här ser min LCD kod ut:

Kod: Markera allt

#define LCD_RS LATAbits.LATA5
#define LCD_EN LATAbits.LATA4
#define LCD_D7 LATAbits.LATA3
#define LCD_D6 LATAbits.LATA2
#define LCD_D5 LATAbits.LATA1
#define LCD_D4 LATAbits.LATA0

void LCD_STROBE(void){
  LCD_EN = 1;
  Delay10TCYx(1);						// 5uS
  LCD_EN = 0;
}  
void lcd_write(unsigned char c){
	LCD_D4 = ( ( c >> 4 ) & 0x01 );
	LCD_D5 = ( ( c >> 5 ) & 0x01 );
	LCD_D6 = ( ( c >> 6 ) & 0x01 );
	LCD_D7 = ( ( c >> 7 ) & 0x01 );
	Delay100TCYx(1);					// 54uS
	LCD_STROBE();
	LCD_D4 = ( c & 0x01 );
	LCD_D5 = ( ( c >> 1 ) & 0x01 );
	LCD_D6 = ( ( c >> 2 ) & 0x01 );
	LCD_D7 = ( ( c >> 3 ) & 0x01 );
	Delay100TCYx(1);					// 54uS
	LCD_STROBE();
}

void lcd_out(unsigned char r,unsigned char p,const rom char *f){
 	LCD_RS = 0;
 switch(r){
	case 1:lcd_write(0x80+p);break;		// Rad 1 + Position
	case 2:lcd_write(0xA8+p);break;		// Rad 2 + Position
	case 3:lcd_write(0x94+p);break;		// Rad 3 + Position
	case 4:lcd_write(0xBC+p);break;		// Rad 4 + Position
	default: break;
   }
	LCD_RS = 1;
	while(*f)lcd_write(*f++);
}

void lcd_clear(void){
	LCD_RS = 0;
	lcd_write(0x01);
	Delay100TCYx(40);    // 2ms
}

void LCD_Init(void){
	LCD_RS = 0;
	LCD_EN = 0;
    Delay1KTCYx(30);		// 15mS

	LCD_D4 = 1;
	LCD_D5 = 1;
	LCD_D6 = 0;
	LCD_D7 = 0;
	LCD_STROBE();
    Delay100TCYx(100);		// 5mS
	LCD_STROBE();
	Delay100TCYx(10);		// 0,5mS
	LCD_STROBE();
	Delay100TCYx(10);		// 0,5mS
	LCD_D4 = 0;
	LCD_D5 = 1;
	LCD_D6 = 0;
	LCD_D7 = 0;
	LCD_STROBE();	
	lcd_write(0x28);	// Function set: (4Bit Mode,Display Lines=1,Character Font=0)
	lcd_write(0x0C);	// Display on/off control: (Display On, Cursor OFF, Cursor Blink OFF)
	lcd_clear();		// Clear screen
	lcd_write(0x06); 	// Entry Mode set:(Cursor moves to the right)
 }	
//****************************************************************************************	

void main(void){
 PIC_Init();
 LCD_Init();
 
 while(1==1){
 lcd_clear();
 Delay10KTCYx(200);
 lcd_out(4,0,"123456789");
 Delay10KTCYx(200);
 
 }
}
Är det något galet med koden??

Tack för ett bra forum!!
bos
Inlägg: 2314
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: LCD Probelm Med Microchip C18

Inlägg av bos »

Min erfarenhet av LCD i 4-bitsläge är att det ibland inte är 100% säkert att LCD:n blir initialiserad korrekt. Lösningen jag använt är att skicka samma initialiseringskommando flera gånger i rad för att säkerställa att den hamnar i 4-bitläge.

Jag har inget datablad till hands och orkar inte googla åt dig, men jag är inte säker på vad din "manuella" skrivning före lcd_write(0x28); gör i slutet på koden. Om 0x28 är din initialiseringssträng som kommentaren säger så upprepa den raden 4-5 gånger och testa om det hjälper.
Jörgen H
Inlägg: 6
Blev medlem: 3 juni 2010, 12:17:11

Re: LCD Probelm Med Microchip C18

Inlägg av Jörgen H »

bos

Har testat ditt förslag utan resultat .

Initiering enligt Wikin här på forumet.

Här är det datablad jag har hittat:
http://www.datasheetpro.com/572146_down ... sheet.html

Får testa mer i kväll när jag har tid!
Tack för snabba svar
Användarvisningsbild
Porto
EF Sponsor
Inlägg: 437
Blev medlem: 27 mars 2004, 12:58:48

Re: LCD Probelm Med Microchip C18

Inlägg av Porto »

Angående problem med 4-bitarsläge:
Vid 4-bitarsläge så måste man först initiera den som 8-bitars TVÅ gånger. Orsaken är den att om man startar om programmet så finns risken att displayen dels är i 4-bitarsläge, dels att den har hamnat i osynk på grund av att man startade om mitt i en överföring där bara de första 4-bitarna är skickade. Kommandot för 8-bitarsläge är likadant i både 4/8-bitarsläget, enda skillnaden är att om displayen är för stunden i 4-bitarsläge så väntar den på att den andra delen av överföringen skall komma. Därav behöver man initiera den två gånger som 8-bitars innan man byter till 4-bitar.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: LCD Probelm Med Microchip C18

Inlägg av sodjan »

Eftersom siffrorna faktiskt kommer ut på LCD'n så tror jag inte
att det är strul med 8/4 bitars mode. Snarare att du har strulat
till adresseringen. Eller timing problem. Eller något annat... :-)
Det första jag skulle göra är att lägga in en rejäl delay (flera sekunder)
mellan varje skrivning till LCD'n. Dels så ser du om det är timing problem, dels
så kan du faktiskt hinna med att mäta (t.ex med ett oscilloskop) på signalerna.

Men för övrigt så är det väl bara att felsöka, eller hur ? :-)
Det första är t.e att hårdkoda det du tror att du gör mot LCD'n och
se om *det* fungerar. Om det *gör* det, så har du fel i dina rutiner.
Om det *inte* fungerar så är det fel i din förståelse av hur LCD'n fungerar.

Jag tycker att din "lcd_write" ser lite onödigt stökig ut. Jag hade kört 4-bitars
mode med SWAPF och ANDF/ORF (vilket det nu blir) mot LATA istället
för de där 4 shiften.

Vad gör "c >> 4" ? Shiftar 4 steg ?
I så fall blir det väl 28 SHIFT och 7 AND operationer för varje anrop av "lcd_write" (?).
bos
Inlägg: 2314
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: LCD Probelm Med Microchip C18

Inlägg av bos »

> Vad gör "c >> 4" ? Shiftar 4 steg ?

Ja.

Håller helt med sodjan om att lcd_write() är onödigt bökig och ett rent slöseri med instruktioner, men om målet är att "få det att funka" så duger den förstås.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: LCD Probelm Med Microchip C18

Inlägg av sodjan »

> men om målet är att "få det att funka" så duger den förstås.

Right. Men nu så fungerar det ju inte. Och då så försvårar den
sannolikt felsökningen som den ser ut nu. Hur som helst med det,
det som behövs är enbart gammal hederlig felsökning, inget annat... :-)
Jörgen H
Inlägg: 6
Blev medlem: 3 juni 2010, 12:17:11

Re: LCD Probelm Med Microchip C18

Inlägg av Jörgen H »

OK
jag är ingen expert men "c >> 4" håller väl inte reda på :

#define LCD_D7 LATAbits.LATA0
#define LCD_D6 LATAbits.LATB1
#define LCD_D5 LATAbits.LATC1
#define LCD_D4 LATAbits.LATD0

det va det jag var ute efter!
Inte minsta instruktioner!

Tack för alla svar!
Har redan laborera med olika tider som "sodjan" skrev, men inte med oscilloskop!!

Tiderna är tagna med Stopwath i MPLAB

While(1==1){
lcd_clear();
Delay10KTCYx(200); // 1 Sec
lcd_out(4,0,"123456789");
Delay10KTCYx(200); // 1Sec
}
Det blinkar med 1 sekund på lcdn!!!! (1Sec ON 1Sec OFF)

Kör med INTOSC 8Mhz
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47010
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: LCD Probelm Med Microchip C18

Inlägg av TomasL »

Öka tidsfördröjningarna, eftersom du inte använder "busyflaggan" .
ANDa utgångarna istället för alla dessa shiftoprerationer, blir bättre.
Jörgen H
Inlägg: 6
Blev medlem: 3 juni 2010, 12:17:11

Re: LCD Probelm Med Microchip C18

Inlägg av Jörgen H »

Denna kod fungerar i MikroC utan problem:

Kod: Markera allt

void main() {

 PIC_Init();                        // Initialize PIC
 Lcd_Init();                        // Initialize LCD

 Lcd_Cmd(_LCD_CLEAR);               // Clear display
 Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

 while(1){
  Lcd_Cmd(_LCD_CLEAR);
  Delay_Ms(1000);               // Clear display
  Lcd_Out(4,1,"1234567890");
  Delay_Ms(1000);
  }
}
Så det borde inte vara LCD:n??

Kör med "Microcip C18 Lite" om det har någon betydelse
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: LCD Probelm Med Microchip C18

Inlägg av sodjan »

> Så det borde inte vara LCD:n??

Det är lite oklart vad du menar med "vara LCD:n".
Om du menar det inte är något fel på LCD'n i sig så
är det med 100% säkerhet inte det.

Självklart är det antingen fel i din kod eller fel i hur du
tror att LCD'n fungerar. Vilket som är mest sannolikt just
nu vet jag inte, men det är enkelt att verifiera av dig.
dangraf
Inlägg: 530
Blev medlem: 9 juni 2003, 15:30:56
Ort: göteborg

Re: LCD Probelm Med Microchip C18

Inlägg av dangraf »

kopilerar du exakt samma kod i microC som för C18 när du säger att det fungerar för microC?
Om du kör någon from av debugger (realIce eller ICD2) så skulle jag nog stega i koden och se vad som händer. Du skulle även kunna stega i koden i mplabs simulator och titta på vad portarna får för värden.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: LCD Probelm Med Microchip C18

Inlägg av sodjan »

Jag har inte kollat i detalj, men det är nog lite osannolikt att
Lcd_Out, Lcd_Cmd o.s.v är implementerade (om de ens finns)
på samma sätt i MikroC och C18.
Jörgen H
Inlägg: 6
Blev medlem: 3 juni 2010, 12:17:11

Re: LCD Probelm Med Microchip C18

Inlägg av Jörgen H »

Ha
Har löst problemet!
Jag hade strulat till det med "Address counter"
Byte till rad 2 = 40Hex inte decimalt som jag skrev!
Knepigt att LCD skrev på rad 2+4 När (Address countern < 0x40)

å vad man kan strula till det ibland :vissla:

Tack för alla svar

Här är den fungerande koden om någon e intresserad !

Kod: Markera allt

#define LCD_RS LATAbits.LATA5
#define LCD_EN LATAbits.LATA4
#define LCD_D7 LATAbits.LATA3
#define LCD_D6 LATAbits.LATA2
#define LCD_D5 LATAbits.LATA1
#define LCD_D4 LATAbits.LATA0

void LCD_STROBE(void){
  LCD_EN = 1;
  Delay10TCYx(1);						// 5uS
  LCD_EN = 0;
}  
void lcd_write(unsigned char c){
	
	LCD_D4 = ( ( c >> 4 ) & 0x01 );
	LCD_D5 = ( ( c >> 5 ) & 0x01 );
	LCD_D6 = ( ( c >> 6 ) & 0x01 );
	LCD_D7 = ( ( c >> 7 ) & 0x01 );
	Delay100TCYx(1);					// 54uS
	LCD_STROBE();
	LCD_D4 = ( c & 0x01 );
	LCD_D5 = ( ( c >> 1 ) & 0x01 );
	LCD_D6 = ( ( c >> 2 ) & 0x01 );
	LCD_D7 = ( ( c >> 3 ) & 0x01 );
	Delay100TCYx(1);					// 54uS
	LCD_STROBE();
}

void lcd_out(unsigned char r,unsigned char p,const rom char *f){
 	LCD_RS = 0;
 switch(r){
	case 1:lcd_write(0x80+p);break;		// Rad 1 + Position
	case 2:lcd_write(0xC0+p);break;		// Rad 2 + Position
	case 3:lcd_write(0x94+p);break;		// Rad 3 + Position
	case 4:lcd_write(0xD4+p);break;		// Rad 4 + Position
	default: break;
   }
	LCD_RS = 1;
	while(*f)lcd_write(*f++);
}

void lcd_clear(void){
	LCD_RS = 0;
	lcd_write(0x01);
	Delay100TCYx(40);    // 2ms
}

void LCD_Init(void){
	LCD_RS = 0;
	LCD_EN = 0;
    Delay1KTCYx(40);		// 20mS

	LCD_D4 = 1;
	LCD_D5 = 1;
	LCD_D6 = 0;
	LCD_D7 = 0;
	LCD_STROBE();
    Delay100TCYx(100);		// 5mS
	LCD_STROBE();
	Delay100TCYx(10);		// 0,5mS
	LCD_STROBE();
	Delay100TCYx(10);		// 0,5mS
	LCD_D4 = 0;
	LCD_D5 = 1;
	LCD_D6 = 0;
	LCD_D7 = 0;
	LCD_STROBE();	
	lcd_write(0x28);	// Function set: (4Bit Mode,Display Lines=1,Character Font=0)
	lcd_write(0x0C);	// Display on/off control: (Display On, Cursor OFF, Cursor Blink OFF)
	lcd_clear();		// Clear screen
	lcd_write(0x06); 	// Entry Mode set:(Cursor moves to the right)
 }	
//****************************************************************************************	

void main(void){
 PIC_Init();
 LCD_Init();
 
while(1==1){
 lcd_clear();
 Delay10KTCYx(200);		// Delay 1 Sec
 lcd_out(1,1,"1234567890");
 Delay10KTCYx(200);		// Delay 1 Sec
 lcd_out(2,2,"1234567890");
 Delay10KTCYx(200);		// Delay 1 Sec
 lcd_out(3,3,"1234567890");
 Delay10KTCYx(200);		// Delay 1 Sec
 lcd_out(4,4,"1234567890");
 Delay10KTCYx(200);		// Delay 1 Sec
 
 }
}
Skriv svar