Maker Pro
Maker Pro

LCD driving with PIC

A

Alexander

I'd like to drive an LCD-display with an PIC.
It's an standard 2x16 with backlight.

Unfortunatly I have had no luck doing this.
Some questions arise.
What should I do with the third pin, which is sometimes called contrast or
LCD-Drive or V0???

Is it possible to use PWM to drive this pin?
Is it possible to use PWM to drive the backlight?

And the final questions ;)
If I use multiple displays, are same questions possible or should I put an
amplifier (eg FET) in the circuit.
Can I connect al pins of both displays on the same line except for enable???

Greetings,

Alexander
 
D

david

Alexander said:
I'd like to drive an LCD-display with an PIC.
It's an standard 2x16 with backlight.

Unfortunatly I have had no luck doing this.
Some questions arise.
What should I do with the third pin, which is sometimes called contrast or
LCD-Drive or V0???

Is it possible to use PWM to drive this pin?
Is it possible to use PWM to drive the backlight?

And the final questions ;)
If I use multiple displays, are same questions possible or should I put an
amplifier (eg FET) in the circuit.
Can I connect al pins of both displays on the same line except for
enable???

Greetings,

Alexander
I have two displays wired up in tandem. ie parrelled up all wires. I wonder
how many display would work like this anyone ????


David
 
A

Alexander

I have two displays wired up in tandem. ie parrelled up all wires. I
wonder how many display would work like this anyone ????


David
All wires, including V0 and the backlight???
 
J

JK

Alexander said:
I'd like to drive an LCD-display with an PIC.
It's an standard 2x16 with backlight.

Unfortunatly I have had no luck doing this.
Some questions arise.
What should I do with the third pin, which is sometimes called contrast or
LCD-Drive or V0???

Connect a adjustable resistor (10 kOhm) between 5V and 0V, connect the
adjustable pin to the contrast pin
Start at midrange, adjust the pot. to adjust contrast (darkness) of letters
in display.
Is it possible to use PWM to drive this pin?

PWM on the contrast pin? I never tried this, my datasheet says: feed with
current from 0,5 to 2,4 mA
(Could be a killer! But if you have a surplus display, try it! Or in
combination with the 10k pot.)
Is it possible to use PWM to drive the backlight?

If you switch it with a transistor and use a series resistor of about 4,7
Ohm ( current limiter ~ 170mA at 5V) for the backlight (LED-based type).
It's a good way to adjust the backlight!
And the final questions ;)
If I use multiple displays, are same questions possible or should I put an
amplifier (eg FET) in the circuit.

If you connect 1000000 display's together, i would say yes.....
Can I connect al pins of both displays on the same line except for
enable???

Correct!
I have a 40 X 4 LCD which is in fact a double 40 X 2, therefore it has 2
ENABLE lines.
All other lines are common
Backlight is connected trough separate connections
Greetings,

Alexander

I've programmmed a PIC16F84 in the past to produce text on such display's,
you can do this in two way's (8 or 4 bit)
These display's need a very specific and timed startup-procedure before they
will function.
You need to get the proper programmingspec's for youre display and follow it
to the letter.
Look at the back off youre display at the biggest chip (mostly near the
connector) (Mine says HD44780).
Search the WWW with the number on the chip in mind!

happy new year

JK
 
A

Alexander

Het volgende bericht werd op ons ingehakt door JK
Connect a adjustable resistor (10 kOhm) between 5V and 0V, connect the
adjustable pin to the contrast pin
Start at midrange, adjust the pot. to adjust contrast (darkness) of
letters in display.
I've tried a 100k,
I will try a 10k soon
PWM on the contrast pin? I never tried this, my datasheet says: feed
with current from 0,5 to 2,4 mA
(Could be a killer! But if you have a surplus display, try it! Or in
combination with the 10k pot.)
I will try it as soon as I have de display working.
If it doesn't work I will try adding a diode, which prevents the current to
flow back if the output is low. To stabilize the current an Voltage I will
also ad an capacitor between the pin and ground.
If you switch it with a transistor and use a series resistor of about
4,7 Ohm ( current limiter ~ 170mA at 5V) for the backlight (LED-based
type). It's a good way to adjust the backlight!
Of course but a Field Effect might do the trick better.
If you connect 1000000 display's together, i would say yes.....


Correct!
I have a 40 X 4 LCD which is in fact a double 40 X 2, therefore it
has 2 ENABLE lines.
All other lines are common
Backlight is connected trough separate connections


I've programmmed a PIC16F84 in the past to produce text on such
display's, you can do this in two way's (8 or 4 bit)
These display's need a very specific and timed startup-procedure
before they will function.
You need to get the proper programmingspec's for youre display and
follow it to the letter.
Look at the back off youre display at the biggest chip (mostly near
the connector) (Mine says HD44780).
Search the WWW with the number on the chip in mind!

I've already tried it, I didn't find good schematics however.
Some datasheets where found by me.
The displays I tried are DEM16216 SYH-PY-12/V and the HMC16216SY-PY-12, both
should be driven identically I guess.
I've tried both 4 and 8 lbit interface modes.
The timings should be as followed (8-bit mode),
30ms power up
Functionset
39us
Display on/off control
39us
Display Clear
1.53 ms
Entry mode set

I didn't wait exactly these times but a bit longer.
 
J

JK

My datasheet says that the busy-flag is only available after init-procedure
is completed.

Jk
 
A

Alexander

I have had time to look overthings again.
I made one mistake hooking op the LCD (took the schematics from a different
type with VCC and VDD reversed).
Now I took another Display (DEM16216 SYH-PY-12/V) to make sure I didn't blew
the old one.
Still nothing happens.
I have hooked op all 8 datalines directly to the PIC (Port C) and the RS, RW
and E lines also directly (to Port A)
So now pull-ups and pull-downs and no other peripheral connected.

I've included the code.

Hope someone can help me.

Alexander



;*****************************************************************************
; Fosc = 4MHz
; Cycle_time = 1/Fosc / 4
; = 1/(4*10^6) / 4
; = 1uSec
;*****************************************************************************
LIST P=18F442, F=INHX8M
include <p18f442.inc>

RESET_V EQU 0x0000 ; Address of RESET Vector
ISR_V EQU 0x0004 ; Address of Interrupt
Vector
OSC_FREQ EQU D'4000000' ; Oscillator Frequency is 4
MHz

LCD_DATA EQU PORTC ; LCD data lines interface
LCD_DATA_TRIS EQU TRISC
LCD_CTRL EQU PORTA ; LCD control lines
interface
LCD_CTRL_TRIS EQU TRISA ; LCD control lines
interface

LCD_LINE0 EQU 0x000
LCD_LINE1 EQU 0x040

; PORTA bits
LCD_E EQU 2 ; LCD Enable control line
LCD_RW EQU 1 ; LCD Read/Write control line
LCD_RS EQU 0 ; LCD Register-Select control
line

; misc.
LCD_TEMP EQU 0x020 ; LCD subroutines internal
use
COUNT EQU 0x022 ; A counter
DELAY equ 0x023 ; Used in DELAYxxx routines
X_DELAY equ 0x024 ; Used in X_DELAYxxx
routines


;*****************************************************************************
; Program start
;*****************************************************************************
ORG RESET_V ; RESET vector location
GOTO START


;*****************************************************************************
; This is the Interrupt routine. Should NOT get here
;*****************************************************************************
ORG ISR_V ; Interrupt vector location
INTERRUPT:
RETFIE
GOTO INTERRUPT


;*****************************************************************************
; Initialize processor registers
;*****************************************************************************
START: ; POWER_ON Reset (Beginning of
program)

MOVLW 0x07
MOVWF ADCON1
CLRF TRISA

MAIN:
CLRF LCD_DATA ; ALL PORT output should
output Low.
CLRF LCD_CTRL

MOVLW 0x000 ; RB7-0 outputs
MOVWF LCD_DATA_TRIS

CALL LCDINIT ; Initialize LCDisplay

CALL LCDHOME
MOVLW 0x030 ; ASCII '0'
CALL LCDPUTCHAR ;
MOVLW 0x031 ;
CALL LCDPUTCHAR ;
MOVLW 0x032 ;
CALL LCDPUTCHAR ;
MOVLW 0x033 ;
CALL LCDPUTCHAR ;
MOVLW 0x034 ;
CALL LCDPUTCHAR ;

;*****************************************************************************
; Program ends here
;*****************************************************************************
LOOP:
GOTO LOOP ; Stay here forever

;*****************************************************************************
; LCD Module Subroutines
;*****************************************************************************
;
;=============================================================================
; LCDINIT
; Initilize LC-Display Module
;=============================================================================
LCDINIT:
; Busy-flag is not yet valid
CLRF LCD_CTRL ; ALL PORT output should output Low.
; power-up delay
MOVLW 0x03c
CALL X_DELAY500 ; 30 * 0.5mS = 15mS
; Function Set
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVLW 0x3c
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
CALL DELAY500 ; 0.5mS
; Display on/off ctrl
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVLW 0x0c
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
CALL DELAY500 ; 0.5mS
; Display clear
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVLW 0x01
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
MOVLW 0x004
CALL X_DELAY500 ; 4 * 0.5mS = 20mS
; Entry mode
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVLW 0x06
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN

;=============================================================================
; LCD_ENABLE
; Pulses LCD enable pin
;=============================================================================
LCD_ENABLE:
BSF LCD_CTRL, LCD_E ; LCD E-line High
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;=============================================================================
; LCDBUSY
; Returns when LCD busy-flag is inactive
;=============================================================================
LCDBUSY:
MOVLW 0x0FF ; Set PORTB for input
MOVWF LCD_DATA_TRIS
BCF LCD_CTRL, LCD_RS; Set LCD for command mode
BSF LCD_CTRL, LCD_RW; Setup to read busy flag
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_DATA, W ; Read busy flag + DDram address
BCF LCD_CTRL, LCD_E ; LCD E-line Low
ANDLW 0x80 ; Check Busy flag, High = Busy
BTFSS STATUS, Z
GOTO LCDBUSY
LCDNOTBUSY:
BCF LCD_CTRL, LCD_RW
CLRF LCD_DATA_TRIS ; Set PORTB for output
RETURN
;=============================================================================
; LCDCLEAR
; Clears display and returns cursor to home position (upper-left corner).
;=============================================================================
LCDCLEAR:
MOVLW 0x001
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDHOME
; Returns cursor to home position.
; Returns display to original position (when shifted).
;=============================================================================
LCDHOME:
MOVLW 0x002
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDEMODE
; Sets entry mode of display.
; Required entry mode must be set in W
; b0 : 0 = no display shift 1 = display shift
; b1 : 0 = auto-decrement 1 = auto-increment
; b2-7 : don't care
;=============================================================================
LCDEMODE:
ANDLW 0x003 ; Strip upper bits
IORLW 0x004 ; entry mode
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDDMODE
; Sets display control.
; Required display mode must be set in W
; b0 : 0 = cursor blink off 1 = cursor blink on
; b1 : 0 = cursor off 1 = cursor on
; b2 : 0 = display off 1 = display on (display data remains in DDRAM)
; b3-7 : don't care
;=============================================================================
LCDDMODE:
ANDLW 0x007 ; Strip upper bits
IORLW 0x008 ; Display on/off control
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDSCGA
; Sets Character-Generator-RAM address. CGRAM is read/written after
; this setting.
; Required CGRAM address must be set in W
; b0-5 : required CGRAM address
; b6-7 : don't care
;=============================================================================
LCDSCGA:
ANDLW 0x03F ; Strip upper bits
IORLW 0x040 ; Function set
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDSDDA
; Sets the Display-Data-RAM address. DDRAM data is read/written after
; this setting.
; Required DDRAM address must be set in W
; b0-6 : required DDRAM address
; b7 : don't care
;=============================================================================
LCDSDDA:
ANDLW 0x07F
IORLW 0x080 ; Function set
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDPUTCHAR
; Sends character to LCD
; Required character must be in W
;=============================================================================
LCDPUTCHAR
MOVWF LCD_TEMP ; Character to be sent is in W
CALL LCDBUSY ; Wait for LCD to be ready
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BSF LCD_CTRL, LCD_RS; Set LCD in data mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_TEMP, W
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;=============================================================================
; LCDPUTCMD
; Sends command to LCD
; Required command must be in W
;=============================================================================
LCDPUTCMD
MOVWF LCD_TEMP ; Command to be sent is in W
CALL LCDBUSY ; Wait for LCD to be ready
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_TEMP, W
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN

;*****************************************************************************
; Delay_time = ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value = (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
;
; i.e. (@ 4MHz crystal)
; Delay_time = ((32 * 3) + 4) * 1uSec
; = 100uSec
; DELAY_value = (500uSec - 4) / 3
; = 165.33
; = 165
;*****************************************************************************
DELAY500
MOVLW D'165' ; +1 1 cycle
MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP
DECFSZ DELAY, F ; step 1 1 cycle
GOTO DELAY500_LOOP ; step 2 2 cycles
RETURN ; +3 2 cycles


X_DELAY500 MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP
CALL DELAY500 ; step1 wait 500uSec
DECFSZ X_DELAY, F ; step2 1 cycle
GOTO X_DELAY500_LOOP ; step3 2 cycles
RETURN ; +2 2 cycles

END ; End of program
 
A

Alexander

Het volgende bericht werd op ons ingehakt door Anthony Fremont
"Alexander" wrote

With power applied to your LCD and the contrast pin grounded, you
should see a row of black rectangles on the display. Does it do this?
It does now ;)
Why it didn't yesterday??? I don't know.
I even get on the first line after de black rectangles disapear something
like 1234.
I'm very happy about that.
You should probably clear TRISB, TRISD, and TRISE as well. All pins
start off as input pins. Unless you have them all tied to Vcc or Vdd,
then you should make them output pins so that they are not floating.
You're right about that, but I will use them later as in- and outputs.
It looks like you took code that was intended for another (16F) PIC
model and are using it on the 18F. I don't see anything that should
stop it from working, but I'm not that familiar with the 18F PICs and
may be missing something.
You were nothing missing since it works fin now, without any change at all.
And you were right about the 16F PIC I started to test with an 16F84a (or
it's similar borther), but needed the 18F for the whole project.
I will clean up the code later.
I will try it again to see if it was an EMC problem (occors sometimes in my
room :p )

ThanX you all for helping!!!
 
Top