Sida 1 av 1

Problem med LCD

Postat: 8 augusti 2005, 19:03:17
av fatpo83
Mina "gamla" LCD rutiner för pic16 fungerar inte i pic18! Hur kommer det sig? Jag har tittat genom koden många många gånger. Ser ni något konstigt?

Kod: Markera allt

-----------------LCD.h------------------------------------

void LCD_data(char data, char mode);						//Funktioner för LCD
void LCD_string(const char *string);						//Funktioner för LCD
void lcd_dec_byte(int val, int digits);						//Skriver int till LCD med given bas
void initlcd(void);											//Initierar LCDn
void enable(void);
int num_to_char(int val);									//Funktion för LCD, omvandlar från num (dec) till char för skrivning i LCD

#define	lcd_rensa		0x01 								//Rensa displayen
#define	lcd_hem			0x02								//Markör till första raden första positionen
#define	lcd_on			0x0C								//Display på...
#define	lcd_off			0x08								//..ja...undra...
#define	lcd_rad1		0x80								//Första raden första positionen
#define	lcd_rad2		0xC0

#define text			1
#define instr			0

-----------------LCD.c------------------------------------
#include <p18cxxx.h>
#include "LCD.h"


void initlcd(void)
{
	delayMs(35);
	LCD_data(0x02,instr);
	LCD_data(0x02,instr);
	LCD_data(0x02,instr);
	LCD_data(0x00,instr);
	LCD_data(0x0E,instr);
	LCD_data(0x00,instr);
	LCD_data(0x06,instr);
	LCD_data(0x28,instr);	//Två rader
}

void enable(void)
{
	PORTBbits.RB6=1;
	PORTBbits.RB6=0;
	delayMs(4);
}

void LCD_data(char data, char mode)					//4-bit data kommunikation med LCD:n
{
	char nibble,j;
	j=mode;
	PORTBbits.RB5=j;								//Register select - Välja register, data eller instruktion
	nibble=data;			
	nibble=nibble>>3;								//Skifta tre steg för att första nibblen ska hamna rätt...
	nibble=(nibble&0x1E);							//Nollställer allt utom den nibble vi vill skicka
	PORTB = (PORTB&0xE1);							//Nollställer databussarna
	PORTB = (PORTB|nibble);							//Odlar ihop nibblen och PORTB
	enable();										//Uppdatera	

	nibble=data;									//Samma fast den lägre nibblen
	nibble=nibble<<1;
	nibble=(nibble&0x1E);
	PORTB = (PORTB&0xE1);
	PORTB = (PORTB|nibble);
	enable();
}

void LCD_string(const char *string)
{
	char i=0;
	while(string[i]!=0)
		LCD_data(string[i++],text);
}

void lcd_dec_byte(int val, int digits)				// displays byte in decimal as either 1, 2 or 3 digits

{
   int d;
   int ch;
   if (digits == 3)
   {
      d=val/100;
      ch=num_to_char(d);
      LCD_data(ch,text);
   }
   if (digits >1)									// take the two lowest digits
   {
       val=val%100;
       d=val/10;
       ch=num_to_char(d);
       LCD_data(ch,text);
   }
   if (digits == 1)									// take the least significant digit
   {
       val = val%100;
   }

   d=val % 10;
   ch=num_to_char(d);
   LCD_data(ch,text);
}

int num_to_char(int val)							// converts val to hex character
{
   int ch;
   if (val < 10)
   {
     ch=val+'0';
   }
   else
   {
     val=val-10;
     ch=val + 'A';
   }
   return(ch);
}
-----------------------main.c--------------------------------
...
void main(void)
{
	ADCON1 |= 0x0F;                 // Default all pins to digital
	TRISB= 0x00;
	PORTB= 0x00;

	PORTBbits.RB7=1;

	initlcd();		
	delayMs(50);									
	LCD_data(lcd_rad1,instr);
	LCD_string("xXx");		
while(1);
}
..

Postat: 8 augusti 2005, 19:41:08
av fatpo83
Det verkar som om bara LCD_string(" xXx "); inte fungerar. Funktionen lcd_dec_byte(244, 3); fungerar fint. Konstigt....

Postat: 8 augusti 2005, 22:02:46
av sodjan
Först, varför är du säker på att det *ska* fungera ?

Vad är det för språk (ser ut som C, men språk och kompilator skall vara med) ?

Processormodeller ???

Definiera "fungerar inte" ? Vad händer ?

Sen, om lcd_dec_byte fungerar, så måste väll även LCD_data fungera, eller ?

Har PIC18 processorn en annan hastighet (högre) än PIC16 processorn ?

Du läser och skriver PORTB i samma instruktion och gör även bit instruktioner mot PORTB, använd LATB för skrivningar till porten. Antagligen inte orsaken til dina problem här, man kan bli i framtiden.

Du borde fixa ett kort exempel som visar problemet. Det verkar ju som om det skulle räcka med LCD_string och ett anrop. Det finns ju ingen anledning att visa kod som *fungerar*

En liten detalj, konstanten "instr" hade varit bättre om den hette "instruction", nu kan det förväxlas med "instring" (vilket jag gjorde först)...

Min gissning, du har problem med hantering av strängar. Så vitt jag vet så skilljer det en del i hur C kompilatorer hanterar strängar mellan PIC16 och PIC18. Speciellt i samband med funktionsanrop.

Och LCD_String är ju bara ett par rader, så det bör väll gå att kolla... :-)

Slutligen, många C versioner brukar ha inbyggda LCD funktioner, men det kanske inte din kompilator har...

Postat: 9 augusti 2005, 01:03:32
av fatpo83
Först, varför är du säker på att det *ska* fungera ?
Nja, det funkade ju utmärkt för tidigare pic16 så det finns ingen anledning att det inte ska funka för pic18 (då allt är SW-baserat)
Vad är det för språk (ser ut som C, men språk och kompilator skall vara med) ?
Som det står i början av varje fil så är det C. Mplab C18 används och picen heter 18f2455.
Definiera "fungerar inte" ? Vad händer ?
Den initierar LCDen, för cursern blinkar och man kan byta position. Sen kan man även skriva tal med lcd_dec_byte, men som sagt ingenting syns när man anropar LCD_string - inte ens cursorn flyttar sig.

Har PIC18 processorn en annan hastighet (högre) än PIC16 processorn ?

Ja den är snabbare men har mindre betydelse då det är samma delayer.

Jag har även ändrat ändrat instr till något annat --> samma problem. Jag vet att C18 har inbyggda rutiner för hantering av LCD...jag kanske borde titta på dem...men det är frustrerande när saker som "borde" fungera inte fungerar!

Postat: 9 augusti 2005, 06:58:56
av Icecap

Kod: Markera allt

void LCD_string(const char *string)
  {
   while(*string) LCD_data(*(string++),text);
  }
Fungerar?

Är det samma compiler för PIC18 som för PIC16?

Postat: 9 augusti 2005, 14:23:26
av sodjan
> "det funkade ju utmärkt för tidigare pic16 så det finns ingen anledning att det inte ska funka för pic18"

Ja men då så !! :-) :-)

> "Jag har även ändrat ändrat instr till något annat --> samma problem."

Och jag sa att det inte hade med ditt problem att göra, det var mer av kosmetiskt karaktär som medförde risk att man missförstog koden...

> "det är frustrerande när saker som "borde" fungera inte fungerar!"

Vadå "borde" ???
Kan du peka på något som explicit säger att just din kod SKA fungera ?

Att det fungrar på PIC16 är inget "bevis"...

Båda jag och Icecap har nu pekat på stränghaneringen, men efter som du tycker att koden ska/borde fungera som den är, så kanske det inte spelar så stor roll... :-) :-)

För övrigt, inte byggde du väll denna kod m.h.a C18 för PIC16 ???

Mvh
/Janne.

Postat: 9 augusti 2005, 21:34:05
av fatpo83
Problem löst. Tydligen ska man skriva "rom const char * strang" i C18. Tack för alla svar.
Vadå "borde" ???
Kan du peka på något som explicit säger att just din kod SKA fungera ?
Ett exempel. Du lär dig cykla vid 7 års åldern. Sen köper du en större cykel vid 15. Kan du fft cykla? Samma resonemang när man byter bil...

Postat: 9 augusti 2005, 22:45:38
av Icecap
Javisst är C portabelt över olika arkitekturer.....ungefär!

Iblant måste man lusläsa manualer ordentligt.

Men denna förträffeliga C som används till PIC18....är den gratis och i så fall från var?

Postat: 9 augusti 2005, 23:24:22
av sodjan
Microchip (det är deras egen...)

"Student version", fri i 60 dagar, sedan lägger optimizern (m.m) av.

Ominstallation "får igång" allt igen...