I was building a simple wattmeter using the schematic as shown here
And the ASM code for PIC16F88 here to drive the JHD162A LCD as well.
(The code is on 4 bits HD44780, but is compatible with KS0066 driver used here.)
However after I'd built the circuit, I found that LCD shows nothing.
And I wonder if I had done something wrong on my code or what, or maybe thay said I need some kind of driver "wake-up" for the LCD module?
Thanks if you can help.
[COLOR="Red"][B]; processor PIC16f870
; processor PIC16F88
[/B]
[/COLOR] ifdef __16F870
include P16f870.inc
#DEFINE TMR0IF T0IF
else
include P16F88.inc
endif
errorlevel -302,-305 ; not reporting bank<>0, dest=file
#DEFINE FALSE 0
#DEFINE movfw ERROR movwf?
ifdef __16F870
__config _BODEN_OFF&_WDT_OFF&_LVP_OFF&_PWRTE_ON&_HS_OSC
else ; 16F88
__config _CONFIG1,_BODEN_OFF&_WDT_OFF&_LVP_OFF&_MCLR_OFF&_PWRTE_ON&_INTRC_IO
endif
; I/O pin assignments
ifdef __16F870
#DEFINE PGBTN PORTC,0 ; page button
#DEFINE HDBTN PORTC,1 ; hold button
#DEFINE BLDBTN PORTC,3 ; blades button
#DEFINE RPMIN PORTC,2 ; rpm input
#DEFINE LCD_D7 PORTB,0 ; \
#DEFINE LCD_D6 PORTB,1 ; |
#DEFINE LCD_D5 PORTB,2 ; | LCD panel
#DEFINE LCD_D4 PORTB,3 ; |
#DEFINE LCD_E PORTB,4 ; |
#DEFINE LCD_RS PORTB,5 ; /
else ; 16f88
#DEFINE PGBTN PORTB,6 ; page button
#DEFINE HDBTN PORTB,7 ; hold button
#DEFINE BLDBTN PORTA,7 ; blades button
#DEFINE RPM_IN PORTB,0 ; rpm input
#DEFINE LCD_D7 PORTA,4 ; \
#DEFINE LCD_D6 PORTB,1 ; |
#DEFINE LCD_D5 PORTB,2 ; | LCD panel
#DEFINE LCD_D4 PORTB,3 ; |
#DEFINE LCD_E PORTB,4 ; |
#DEFINE LCD_RS PORTB,5 ; /
endif
hi,
Have you selected a PIC type for this conditional compile..??
Also
Have you adjusted R1 the 'VO' contrast pot so that the pixel blocks are just visible.
Code:[COLOR="Red"][B]; processor PIC16f870 ; processor PIC16F88 [/B] [/COLOR] ifdef __16F870 include P16f870.inc #DEFINE TMR0IF T0IF else include P16F88.inc endif errorlevel -302,-305 ; not reporting bank<>0, dest=file #DEFINE FALSE 0 #DEFINE movfw ERROR movwf? ifdef __16F870 __config _BODEN_OFF&_WDT_OFF&_LVP_OFF&_PWRTE_ON&_HS_OSC else ; 16F88 __config _CONFIG1,_BODEN_OFF&_WDT_OFF&_LVP_OFF&_MCLR_OFF&_PWRTE_ON&_INTRC_IO endif ; I/O pin assignments ifdef __16F870 #DEFINE PGBTN PORTC,0 ; page button #DEFINE HDBTN PORTC,1 ; hold button #DEFINE BLDBTN PORTC,3 ; blades button #DEFINE RPMIN PORTC,2 ; rpm input #DEFINE LCD_D7 PORTB,0 ; \ #DEFINE LCD_D6 PORTB,1 ; | #DEFINE LCD_D5 PORTB,2 ; | LCD panel #DEFINE LCD_D4 PORTB,3 ; | #DEFINE LCD_E PORTB,4 ; | #DEFINE LCD_RS PORTB,5 ; / else ; 16f88 #DEFINE PGBTN PORTB,6 ; page button #DEFINE HDBTN PORTB,7 ; hold button #DEFINE BLDBTN PORTA,7 ; blades button #DEFINE RPM_IN PORTB,0 ; rpm input #DEFINE LCD_D7 PORTA,4 ; \ #DEFINE LCD_D6 PORTB,1 ; | #DEFINE LCD_D5 PORTB,2 ; | LCD panel #DEFINE LCD_D4 PORTB,3 ; | #DEFINE LCD_E PORTB,4 ; | #DEFINE LCD_RS PORTB,5 ; / endif
May i know what do you mean by PIC type?
I am using MPLAB IDE to compile and burn it to PIC....
I use #defines and directives to make the program easier to
read and modify. For example, the status of the Hold button
is determined by examining bit 7 of PortB on the 16F88, but
it's bit 3 of PortC on the 16F870. I want to write the same
code for both, so I define the port and bit for each MPU, and
use the assembler directives 'ifdef', 'else', and 'endif' to
select the code used depending on which processer is selected.
Then, when I need to read the port pin, the same instruction
works for both PIC's, eg.
hi
As you are using a 16F88 , then remove the semi-colon from the start of processor PIC16F88
; processor PIC16f870
processor PIC16F88
I have tried to compile your code using Oshonsoft, it reports it cannot find the
include LCD.asm file
Have downloaded this from the wattmeter site.??
EDIT:
I am famliar with and use conditional assembly directives.
Oh yes... i put LCD.asm into the same directory and compile it...
successfully built the .HEX file.
Are you expert in ASM by the way? I have had my moments.!
May I know the IO that is interface with the LCD module? (The last 4 bits)...
Is that code responsible to drive onli for the LCD? If i tried to connect the IO to another IO of other module, what will i obtain? Thanks for your help.
hi,
Post the LCD.asm file so that I can compile the full program, in that way I can help you better.
I'll look at the circuit you have posted.
hi,
A quick look at the circuit shows that the VO contrast line is connected to a -V supply.!!
I assume that the LCD is HD44780 compatible, if yes, the VO should be settable to 0V thru to +5V.
you mean connecting the VO to the +5V instead of 0V?
hi,
Please confirm the type of the LCD.
Also what the Source and Load lines are connected too.?
The LCD i use is JHD 162A with 16 pins...
i'd searched thru the internet that its controller is KS0066 driven ..
Well for the source, I use the 9V battery and the load can be anything resistance ...
P/S: The source "-" and 0V is connecting to the same rail at the negative terminal of the source.
hi,
Been looking at the JHD specs, it has a Samsung KS0070B controller, which suggests a +5V nominal supply voltage.??
EDIT:
Using the posted assembler code for the wattmeter and lcd in MPLAB for a 16F88 produces 240 ERRORS.!
Did you say you have compiled this code.?
----------------------------------------------------------------------
Debug build of project `D:\Watt Meter (desired design)\wattmeter.mcp' started.
Preprocessor symbol `__DEBUG' is defined.
Fri Jan 23 18:18:22 2009
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Deleted file "D:\Watt Meter (desired design)\wattmeter.err".
Clean: Deleted file "D:\Watt Meter (desired design)\wattmeter.cod".
Clean: Deleted file "D:\Watt Meter (desired design)\wattmeter.hex".
Clean: Deleted file "D:\Watt Meter (desired design)\wattmeter.lst".
Clean: Deleted file "D:\Watt Meter (desired design)\wattmeter.mcs".
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F88 "wattmeter.asm" /l"wattmeter.lst" /e"wattmeter.err" /d__DEBUG=1
Loaded D:\Watt Meter (desired design)\wattmeter.cod.
----------------------------------------------------------------------
Debug build of project `D:\Watt Meter (desired design)\wattmeter.mcp' succeeded.
Preprocessor symbol `__DEBUG' is defined.
Fri Jan 23 18:18:24 2009
----------------------------------------------------------------------
BUILD SUCCEEDED
hi,
The KS0066 datasheet shows low voltage operation.!!!!
Why dont you write a simple LCD driver diagnostic program and debug that.
Thanks, will try it...
may i know the function of the contrast ? using potentiometer?
#include <16F88.h>
#fuses HS,NOWDT,PUT,NOLVP
#use delay(clock=20000000)
#include "flex_lcd.c"
//==========================
void main()
{
lcd_init(); // Always call this first.
lcd_putc("\fHello World\n");
lcd_putc("Line Number 2");
while(1);
}
// flex_lcd.c
// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.
#define LCD_DB4 PIN_B0
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_B2
#define LCD_DB7 PIN_B3
#define LCD_RS PIN_B4
#define LCD_RW PIN_B5
#define LCD_E PIN_B6
// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.
#define USE_LCD_RW 1
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?