Sida 1 av 1
Problem med initiering av LCD (PIC 16f877a)
Postat: 23 mars 2012, 23:55:13
av Spket
Hej!
Jag har smått börjat med C programmering för Microchips microkontrollers. Jag har kopplat in en Winstar WH2004A till min PIC16f877a enligt följande. Displayen är en 4x20 display men egentligen har den bara två rader.
Datablad för WH2004A
http://www.winstar.com.tw/products_deta ... p?ProID=36 Direktlänk för PDF-dokument
http://www.winstar.com.tw/download.php?ProID=36
RS = RA0
EN= RA1
Edit: R/W är kopplad till GND
DB4 = RB0 , DB5 = RB1 , DB6 = RB2 , DB7 = RB3
WH2004A använder sig av KS0066 eller 'liknande' (KS 0066 or Equivalent). Jag har inte hittat något datablad för just KS0066 men jag har ett för KS0066U
http://www.datsi.fi.upm.es/docencia/Mic ... s0066u.pdf
Jag använder mig av 4-bit mode och initialiseringsprocessen finns på sidan 27(enligt Adobe reader) i databladet.
Det egentliga problemet jag har är att jag inte får initialiseringen av LCDn att fungera. Bara Line1 lyser upp (visas som Rad 1 & 3 på displayen). Jag började först med att följa ett datablad med HD44780 men fick det inte fungera och upptäckte sen att KS0066 har lite olika 'timings' när det kommer till initialiseringen. I alla fall.. här är koden.
Kod: Markera allt
#include <htc.h>
#include <pic16f877a.h>
#include <pic.h>
__CONFIG(FOSC_XT & WDTE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF &
DEBUG_OFF & CP_OFF);
#define _XTAL_FREQ 4000000 //4MHz
#define RS RA0
#define EN RA1
void startupint() {
PORTD = 0x00;
PORTB = 0x00;
ADCON1 = 0x06; //Analog comparators off
CMCON = 0x07;
PORTA = 0x00;
PORTE = 0x00;
PORTC = 0x00;
TRISA = 0x00; //PORTA all output
TRISB = 0x00; //PORTB all output
TRISC = 0x00; //PORTC all output
TRISD = 0x00; //PORTD all output
TRISE = 0x00; //PORTE all output
}
void strobe_EN() {
EN = 1;
EN = 0;
}
void lcdinit() {
__delay_ms(1000); // Wait for LCD to settle
RS=0;
EN=0;
PORTB = 0x02; // START FUNCTION SET
strobe_EN();
//__delay_us(10);
strobe_EN();
PORTB = 0x0C; // 2-Line mode, Display on
strobe_EN(); // END FUNCTION SET
__delay_us(80); // WAIT FOR MORE THAN 39uS
PORTB = 0x00; // START ON/OFF Control
strobe_EN();
PORTB = 0x0c; // Display on
strobe_EN();
__delay_us(80); // END ON/OFF Control
PORTB = 0x00; // START DISPLAY CLEAR
strobe_EN();
PORTB = 0x01;
strobe_EN();
__delay_ms(4); // END DISPLAY CLEAR
PORTB = 0x00; // START ENTRY MODE SET
strobe_EN();
PORTB = 0x06; // Increment mode, entire shift off
strobe_EN();
__delay_us(80); // END ENTRY MODE SET
}
void main() {
startupint();
lcdinit();
//lcdclear();
//writelcd(0x30);
while(1) {
NOP();
}
}
Är det ett problem med mina "timings". Kanske mellan EN=1, EN=0 i strobe_EN()?
Duty cycle på WH2004A är 1/16 men jag hittar ingen information om dom använder en annan fosc än 270kHz som står i databladet för KS0066u
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 24 mars 2012, 02:50:45
av dubbear
Funkar det verkligen att skriva
__delay_ms(1000);
Min erfarenhet är att man inte kan köra det macrot med så höga värden.
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 24 mars 2012, 03:44:30
av Spket
Det är direkt saxat från
http://www.jescab.se/HD44780.html dock så använder han Assembler och inte C.
I databladet så står det "Wait for more than 30ms". En delay på 30, 35, 50, 100 eller 1000 spelar ingen som helst roll i min del. Resultatet blir den samma.
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 24 mars 2012, 10:45:17
av ToPNoTCH
Den där stroben funderar jag på.
Du togglar den utan paus mellan omslagen (nu kan jag ju inte så mycket C).
Dessutom kör du rutinen 2ggr vid varje tillfälle.
Eller funkar "strobe_EN()" som så att om du anropar den och EN=1 så blir den 0 och viceversa ?
Som du ser i sodjans kod så har han en NOP efter varje omslag (2 per toggling).
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 27 mars 2012, 20:32:35
av Spket
Trodde jag hade upptäckt felet och jag trodde det va att microcontrollern glappade i min breadboard. Med en sockel till microcontrollern och multimetern i högsta hugg har jag upptäckt att det endå inte fungerar
Jag har ändrat
Kod: Markera allt
strobe_EN() {
EN = 1;
__delay_us(1);
EN = 0;
__delay_us(1);
}
I databladet för KS0066U hittar man initierings cykeln.
KS0066Uinit.jpg
DB3 - DB7 = RB0 - RB3
RS = RA0
EN = RA1
Så då borde initieringen bli så här?
Kod: Markera allt
__delay_ms(100); // Vänta så att LCDn hinner starta okej
EN = 0;
RS = 0;
PORTB = 0x02; // 0010
strobe_EN();
strobe_EN(); // PORTB = 0x02 två gånger
PORTB = 0x0C; // 1100
strobe_EN();
__delay_us(80); // Minst 39uS. Tar 80 för att vara säker?
PORTB = 0x00;
strobe_EN();
PORTB = 0x0F; // 1111
strobe_EN();
__delay_us(80);
PORTB = 0x00; // 0000
strobe_EN();
PORTB = 0x01; // 0001
strobe_EN();
__delay_ms(5); // Minst 1.53mS.
PORTB = 0x00; // 0000
strobe_EN();
PORTB = 0x06; // 0110
strobe_EN();
// Slut på initieringen.
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 27 mars 2012, 20:52:03
av sodjan
Dokumentrera/kommentera gärna vad varje steg i initieringen gör
(eller egentligen vad du tror att de gör

).
När det gäller delayerna så är alltid för långt bättre än för kort.
Du kan gärna köra riktigt sakta i början, då hinner du kolla signalerna
med en DVM eller med lysdioder. Du kan aldrig köra för sakta.
Angående 8/4 bits mode så kör LCD'n alltid i 8-bitars mode fram till
att du ställer om till 4-bitars mode. Så innan dessa skickar man inte
kommandon i halva bytes och man använder bara de 4 lägsta bitarna.
Efter att man har ställt om till 4-bit mode så *måste* man köra varje
byte som 2 halva bytes.
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 27 mars 2012, 21:34:51
av Spket
Kan min display va trasig tro?
Fast än jag kopplat R/W (pin 5) till GND kan jag ändå mäta 4.8V mellan den pinnen och GND.
DB0, DB1, DB2 uppmäter jag 4.82V fastän de hänger helt fritt.
Kanske ska beställa mig en ny HD44780 (verkar som om de flesta exemplen på internet är med denna krets)
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 27 mars 2012, 21:49:19
av sodjan
> Fast än jag kopplat R/W (pin 5) till GND kan jag ändå mäta 4.8V mellan den pinnen och GND.
Ja, alltså... Du gör ju uppenbarligen något galet, kolla upp det istället...

Antingen har du inte kopplat som du tror eller så mäter du inte det du tror.
Det finns inget magiskt i detta...
> DB0, DB1, DB2 uppmäter jag 4.82V fastän de hänger helt fritt.
Controllern har interna pullups, det ingår i HD44780 standarden.
> Kanske ska beställa mig en ny HD44780 (verkar som om de flesta exemplen på internet är med denna krets)
Väldigt få *nya* LCD'er har *original* HD44780 controllers. Däremot är alla "kompatibla".
Här är dock en som har original Hitachi controller om du vill ha något att labba med :
http://www.tradera.com/1st-hd44780-lcd- ... _152600737
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 28 mars 2012, 23:14:17
av Spket
Efter att ha letat lite på ebay så hittade jag återförsäljaren där jag köpte min display 2009. Det stod hd44780 så jag körde med det databladet. Drog om alla kopplingar till displayen med nya kablar (skalade nya). Nu fungerar det fint!

Har beställt bättre kablar för kopplingsdäcket. Hoppas att jag slipper glapp i framtiden.
IMG_0575.JPG
Kod: Markera allt
/* Första test till LCD-Program med PIC16f877a
Typ: Winstar WH2004A
Blå med vita bokstäver. Bakgrundsbeylst LED
4-bit Mode
'KS 0066' - Controller (Kompatibel med HD44780?)
Pins på LCD
1: Ground, VSS
2: Supply voltage for logic, VDD
3: Contrast Adjustment - 10kOhm pot
4: RS -- RD0
5: R/W -- GND (Not used)
6: E -- RD1
7: DB0 (Not used)
8: DB1 (Not used)
9: DB2 (Not used)
10: DB3 (Not used)
11: DB4 -- RB0
12: DB5 -- RB1
13: DB6 -- RB2
14: DB7 -- RB3
15: Anode: +4.2v for LED (Backlight)
16: Cathode: Power Supply for B/L(-)
En vanlig blå LED är kopplad till RD0 för att se om allt fungerar som det ska
*/
#include <htc.h>
#include <pic16f877a.h>
#include <pic.h>
__CONFIG(FOSC_HS & WDTE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & DEBUG_OFF & CP_OFF);
#define _XTAL_FREQ 4000000 //4MHz
#define RS RD0
#define EN RD1
#define LED RA0
void startupmcu() {
// Start with all ports shut off
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
ADCON1 = 0x06; // All ports digital I/O (RA0-5, RE0-2)
CMCON = 0x07; // Compatators OFF
// Port Direction: 1=input, 0=output
TRISA = 0x00;
TRISB = 0x00;
TRISC = 0x00;
TRISD = 0x00;
TRISE = 0x00;
}
void strobe_EN() {
__delay_us(1);
EN = 1;
__delay_us(1);
EN = 0;
__delay_us(1);
}
void write_strobe() {
__delay_us(1);
RS = 1;
EN = 1;
__delay_us(1);
EN = 0;
RS = 0;
__delay_us(1);
}
void lcdcmd(unsigned char Data) {
RS=0;
EN=0;
PORTB = ((Data >> 4) & 0x0F);
strobe_EN();
__delay_us(200);
PORTB = (Data & 0x0F);
strobe_EN();
__delay_us(200);
}
void writelcd(unsigned char Text) {
PORTB = ((Text >> 4) & 0x0F);
write_strobe();
__delay_us(1);
PORTB = (Text & 0x0F);
write_strobe();
__delay_ms(5);
}
void crshome() {
lcdcmd(0x02);
__delay_ms(5);
}
void lcdclear() {
RS = 0;
lcdcmd(0x01);
__delay_ms(3);
}
void hd44780init() {
__delay_ms(100); // Wait for LCD to Settle
PORTB = 0x03;
strobe_EN();
__delay_ms(10);
strobe_EN();
__delay_us(200);
strobe_EN();
__delay_us(10);
PORTB = 0x02;
strobe_EN();
__delay_us(200);
lcdcmd(0x2A); // Function set. 4-bits, 2 Lines, 5x8 dots.
lcdcmd(0x0F); // Display On/Off Control. Display on, Cursor on, Blinking cursor on.
lcdcmd(0x01); // Clear Display
lcdcmd(0x06); // Entry Mode Set. Cursor increment.
__delay_ms(5);
}
void main() {
startupmcu();
// ksinit();
hd44780init();
crshome();
writelcd(0x48); // H
writelcd(0x45); // E
writelcd(0x4A); // J
lcdcmd(0xC0); // Select 2nd row
writelcd(0x65); // e
writelcd(0x6C); // l
writelcd(0x65); // e
writelcd(0x6B); // k
writelcd(0x74); // t
writelcd(0x72); // r
writelcd(0x6F); // o
writelcd(0x6E); // n
writelcd(0x69); // i
writelcd(0x6B); // k
writelcd(0x66); // f
writelcd(0x6F); // o
writelcd(0x72); // r
writelcd(0x75); // u
writelcd(0x6D); // m
writelcd(0x65); // e
writelcd(0x74); // t
lcdcmd(0x94); // Select 3rd row
writelcd(0x2E); // .
writelcd(0x63); // c
writelcd(0x6F); // o
writelcd(0x6D); // m
while(1) {
LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
}
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 1 april 2012, 08:45:23
av choppertony
Mtt inlägg har inte med den displayen som du använder att göra, men en annan som använder KS0108 eller HD61202 , en grafisk display. jag köpte en sådan display, och när jag letade efter information om den så hittade jag en bra simulator där man kan testa hur man skall gå till väga innan man börjar programmera så man får kläm på vad som händer . Jag hade mycket hjälp av denna sidan. Men man får ju läsa databladet oxå för displayen.
Hoppas någon annan har nytta av denna länken! mvh / Tony
http://www.geocities.com/dinceraydin/dj ... cdsim.html
Re: Problem med initiering av LCD (PIC 16f877a)
Postat: 1 april 2012, 10:53:05
av mrfrenzy
Det var en bra länk! Lär komma till nytta när jag ska börja använda mina grafiska mrmister-displayer. Lade in länken på wikin.