|
|
View previous topic :: View next topic |
Author |
Message |
mojo_risin
Joined: 09 Sep 2013 Posts: 2 Location: Ireland
|
Another LCD newbie question |
Posted: Mon Sep 09, 2013 3:51 pm |
|
|
Hello,
I've been trying to get the 16x2 LCD working for two days now, biggest success being black squares on blue canvas. Here is the code:
Code: |
// flex_lcd.c
#define LCD_RS PIN_A2
#define LCD_E PIN_A3
#define LCD_DB4 PIN_A4
#define LCD_DB5 PIN_A5
#define LCD_DB6 PIN_A6
#define LCD_DB7 PIN_A7
// 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);
}
//---------------------------------------
//----------------------------------------
// 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;
}
}
//------------------------------
|
And here is the main file:
Code: |
#include <18F4523.h>
#fuses NOWDT, NOMCLR,NOPROTECT,INTRC_IO, PUT, NOLVP
#use delay(clock=4000000)
#include "lcd.c"
void configuration();
/****************************************************************************/
main() {
configuration();
delay_ms(500);
lcd_init();
delay_ms(500);
while (1)
{
output_toggle(PIN_A0);
lcd_putc("\fHello World\n");
delay_ms(500);
}
return 0;
}
/****************************************************************************/
void configuration() {
//CONFIGURATION
setup_oscillator(OSC_4MHZ);
setup_adc_ports(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC);
set_tris_a(0b00000000);
}
|
It doesn't work on breadboard or in Proteus. Now I see I must be doing something really wrong here, but I couldn't find it for ages. Please help me.
Pins are connected like this:
Vss - Ground
Vdd - 5 V
Vo - 10K pot
RS - pin A2
RW - Ground
EN - pin A3
D4 - pin A4
D5 - pin A5
D6 - pin A6
D7 - pin A7
The display is this:
http://www.amazon.co.uk/1602-Character-Display-Module-Blacklight/dp/B009GEPZRE/ref=sr_1_1?s=electronics&ie=UTF8&qid=1378763356&sr=1-1&keywords=16x2+lcd
Thanks |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Mon Sep 09, 2013 4:09 pm |
|
|
possible problems...
1) LCD driver is called flex_lcd.c but your program loads 'lcd.c'
I use the flex_lcd driver ,so I know it works but I copied and renamed it to my_flex_lcd.dvr
2) contrast is set wrong..
Usually you need about .5 volts.
3) does the test LED blink at a 1/2Hz rate?
This would confirm the PIC is alive and running right
4) some other internal peripheral is defaulted 'on' or 'attached' to your LCD pins ?
5) Get rid of Proteus.....
hth
jay |
|
|
mojo_risin
Joined: 09 Sep 2013 Posts: 2 Location: Ireland
|
|
Posted: Mon Sep 09, 2013 4:28 pm |
|
|
Got it!
I had two pins wired wrong... feel stupid to admit, but that's what was happening. Pins RA6 and RA7 do not come sequentially, RA7 comes before RA6, and I had connected D7 to RA6. Not very bright.
Thanks for the reply! It was you suggestion for an active peripheral that got me to look again at the datasheet. Really, thanks a lot! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|